Skip to content

Commit 71b0b7b

Browse files
committed
Add tests for specialization constants.
1 parent 88f7047 commit 71b0b7b

2 files changed

Lines changed: 483 additions & 0 deletions

File tree

Tests/DiligentCoreAPITest/src/ObjectCreationFailure/PSOCreationFailureTest.cpp

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1759,4 +1759,122 @@ TEST_F(PSOCreationFailureTest, SpecConst_ErrorAtSecondElement)
17591759
}
17601760

17611761

1762+
// ---------------------------------------------------------------------------
1763+
// Vulkan-specific negative tests for BuildSpecializationData (Name->SpecId matching).
1764+
// These require GLSL shaders with layout(constant_id) declarations so that
1765+
// the reflected specialization constants are available for matching.
1766+
// ---------------------------------------------------------------------------
1767+
1768+
TEST_F(PSOCreationFailureTest, SpecConst_NameNotFoundInShader)
1769+
{
1770+
auto* const pEnv = GPUTestingEnvironment::GetInstance();
1771+
auto* const pDevice = pEnv->GetDevice();
1772+
const auto& DeviceInfo = pDevice->GetDeviceInfo();
1773+
1774+
if (!DeviceInfo.IsVulkanDevice())
1775+
GTEST_SKIP() << "Name->SpecId matching is currently Vulkan-only";
1776+
if (DeviceInfo.Features.SpecializationConstants != DEVICE_FEATURE_STATE_ENABLED)
1777+
GTEST_SKIP() << "Specialization constants are not supported by this device";
1778+
1779+
// GLSL vertex shader with one specialization constant named "sc_Scale".
1780+
static constexpr char VSSource_GLSL[] = R"(
1781+
#version 450
1782+
layout(constant_id = 0) const float sc_Scale = 1.0;
1783+
#ifndef GL_ES
1784+
out gl_PerVertex { vec4 gl_Position; };
1785+
#endif
1786+
void main()
1787+
{
1788+
gl_Position = vec4(0.0, 0.0, 0.0, sc_Scale);
1789+
}
1790+
)";
1791+
1792+
static constexpr char PSSource_GLSL[] = R"(
1793+
#version 450
1794+
layout(location = 0) out vec4 out_Color;
1795+
void main()
1796+
{
1797+
out_Color = vec4(0.0, 0.0, 0.0, 1.0);
1798+
}
1799+
)";
1800+
1801+
ShaderCreateInfo ShaderCI;
1802+
ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL_VERBATIM;
1803+
1804+
RefCntAutoPtr<IShader> pVS;
1805+
{
1806+
ShaderCI.Desc = {"SpecConst NameNotFound VS", SHADER_TYPE_VERTEX, true};
1807+
ShaderCI.Source = VSSource_GLSL;
1808+
pDevice->CreateShader(ShaderCI, &pVS);
1809+
ASSERT_TRUE(pVS);
1810+
}
1811+
1812+
RefCntAutoPtr<IShader> pPS;
1813+
{
1814+
ShaderCI.Desc = {"SpecConst NameNotFound PS", SHADER_TYPE_PIXEL, true};
1815+
ShaderCI.Source = PSSource_GLSL;
1816+
pDevice->CreateShader(ShaderCI, &pPS);
1817+
ASSERT_TRUE(pPS);
1818+
}
1819+
1820+
const float Data = 2.0f;
1821+
SpecializationConstant SpecConsts[] = {
1822+
{"sc_NonExistent", SHADER_TYPE_VERTEX, sizeof(Data), &Data},
1823+
};
1824+
1825+
auto PsoCI{GetGraphicsPSOCreateInfo("PSO Create Failure - SpecConst NameNotFoundInShader")};
1826+
PsoCI.pVS = pVS;
1827+
PsoCI.pPS = pPS;
1828+
PsoCI.NumSpecializationConstants = _countof(SpecConsts);
1829+
PsoCI.pSpecializationConstants = SpecConsts;
1830+
TestCreatePSOFailure(PsoCI, "was not found in");
1831+
}
1832+
1833+
TEST_F(PSOCreationFailureTest, SpecConst_SizeMismatch)
1834+
{
1835+
auto* const pEnv = GPUTestingEnvironment::GetInstance();
1836+
auto* const pDevice = pEnv->GetDevice();
1837+
const auto& DeviceInfo = pDevice->GetDeviceInfo();
1838+
1839+
if (!DeviceInfo.IsVulkanDevice())
1840+
GTEST_SKIP() << "Name->SpecId matching is currently Vulkan-only";
1841+
if (DeviceInfo.Features.SpecializationConstants != DEVICE_FEATURE_STATE_ENABLED)
1842+
GTEST_SKIP() << "Specialization constants are not supported by this device";
1843+
1844+
// GLSL compute shader with a float specialization constant (4 bytes).
1845+
// The spec constant must be used so the compiler does not optimize it away.
1846+
static constexpr char CSSource_GLSL[] = R"(
1847+
#version 450
1848+
layout(constant_id = 0) const float sc_Value = 1.0;
1849+
layout(rgba8, binding = 0) writeonly uniform image2D g_DummyUAV;
1850+
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
1851+
void main()
1852+
{
1853+
imageStore(g_DummyUAV, ivec2(0), vec4(sc_Value));
1854+
}
1855+
)";
1856+
1857+
ShaderCreateInfo ShaderCI;
1858+
ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL_VERBATIM;
1859+
ShaderCI.Desc = {"SpecConst SizeMismatch CS", SHADER_TYPE_COMPUTE, true};
1860+
ShaderCI.Source = CSSource_GLSL;
1861+
1862+
RefCntAutoPtr<IShader> pCS;
1863+
pDevice->CreateShader(ShaderCI, &pCS);
1864+
ASSERT_TRUE(pCS);
1865+
1866+
// Provide 8 bytes for a 4-byte float constant.
1867+
const double WrongSizeData = 2.0;
1868+
SpecializationConstant SpecConsts[] = {
1869+
{"sc_Value", SHADER_TYPE_COMPUTE, sizeof(WrongSizeData), &WrongSizeData},
1870+
};
1871+
1872+
auto PsoCI{GetComputePSOCreateInfo("PSO Create Failure - SpecConst SizeMismatch")};
1873+
PsoCI.pCS = pCS;
1874+
PsoCI.NumSpecializationConstants = _countof(SpecConsts);
1875+
PsoCI.pSpecializationConstants = SpecConsts;
1876+
TestCreatePSOFailure(PsoCI, "has size mismatch");
1877+
}
1878+
1879+
17621880
} // namespace

0 commit comments

Comments
 (0)