1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and/or associated documentation files (the
10 * "Materials"), to deal in the Materials without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Materials, and to
13 * permit persons to whom the Materials are furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice(s) and this permission notice shall be included
17 * in all copies or substantial portions of the Materials.
19 * The Materials are Confidential Information as defined by the
20 * Khronos Membership Agreement until designated non-confidential by Khronos,
21 * at which point this condition clause shall be removed.
23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
33 * \brief Shader built-in constant tests.
34 *//*--------------------------------------------------------------------*/
36 #include "vktShaderBuiltinConstantTests.hpp"
37 #include "vktShaderExecutor.hpp"
38 #include "deUniquePtr.hpp"
39 #include "deStringUtil.hpp"
40 #include "tcuTestLog.hpp"
49 namespace shaderexecutor
55 static deUint32 getUint32 (deUint32 VkPhysicalDeviceLimits::* ptr, Context &ctx)
57 VkPhysicalDeviceProperties properties;
58 ctx.getInstanceInterface().getPhysicalDeviceProperties(ctx.getPhysicalDevice(), &properties);
59 return properties.limits.*ptr;
62 template<deUint32 VkPhysicalDeviceLimits::* ptr>
63 static deUint32 getUint32 (Context &ctx)
65 return getUint32(ptr, ctx);
68 #define GET_UINT32(name) getUint32<&VkPhysicalDeviceLimits::name>
70 static deInt32 getInt32 (deInt32 VkPhysicalDeviceLimits::* ptr, Context &ctx)
72 VkPhysicalDeviceProperties properties;
73 ctx.getInstanceInterface().getPhysicalDeviceProperties(ctx.getPhysicalDevice(), &properties);
74 return properties.limits.*ptr;
77 template<deInt32 VkPhysicalDeviceLimits::* ptr>
78 static deInt32 getInt32 (Context &ctx)
80 return getInt32(ptr, ctx);
83 #define GET_INT32(name) getInt32<&VkPhysicalDeviceLimits::name>
85 static tcu::UVec3 getUVec3 (deUint32 (VkPhysicalDeviceLimits::*ptr)[3], Context &ctx)
87 VkPhysicalDeviceProperties properties;
88 ctx.getInstanceInterface().getPhysicalDeviceProperties(ctx.getPhysicalDevice(), &properties);
89 return tcu::UVec3((properties.limits.*ptr)[0], (properties.limits.*ptr)[1], (properties.limits.*ptr)[2]);
92 template<deUint32 (VkPhysicalDeviceLimits::*ptr)[3]>
93 static tcu::UVec3 getUVec3 (Context &ctx)
95 return getUVec3(ptr, ctx);
98 #define GET_UVEC3(name) getUVec3<&VkPhysicalDeviceLimits::name>
100 static std::string makeCaseName (const std::string& varName, glu::ShaderType shaderType)
102 DE_ASSERT(varName.length() > 3);
103 DE_ASSERT(varName.substr(0,3) == "gl_");
105 std::ostringstream name;
106 name << de::toLower(char(varName[3]));
108 for (size_t ndx = 4; ndx < varName.length(); ndx++)
110 const char c = char(varName[ndx]);
112 name << '_' << de::toLower(c);
116 name << '_' << glu::getShaderTypeName(glu::ShaderType(shaderType));
122 VS = (1<<glu::SHADERTYPE_VERTEX),
123 TC = (1<<glu::SHADERTYPE_TESSELLATION_CONTROL),
124 TE = (1<<glu::SHADERTYPE_TESSELLATION_EVALUATION),
125 GS = (1<<glu::SHADERTYPE_GEOMETRY),
126 FS = (1<<glu::SHADERTYPE_FRAGMENT),
127 CS = (1<<glu::SHADERTYPE_COMPUTE),
129 SHADER_TYPES = VS|TC|TE|GS|FS|CS
132 template<typename DataType>
133 class ShaderBuiltinConstantTestInstance;
135 template<typename DataType>
136 class ShaderBuiltinConstantCase : public TestCase
139 typedef DataType (*GetConstantValueFunc) (Context &);
141 ShaderBuiltinConstantCase (tcu::TestContext& testCtx, const char* varName, glu::ShaderType shaderType, GetConstantValueFunc getValue, const char* requiredExt);
142 virtual ~ShaderBuiltinConstantCase (void) {};
144 virtual void initPrograms (vk::SourceCollections& programCollection) const
146 m_executor->setShaderSources(programCollection);
149 virtual TestInstance* createInstance (Context& context) const { return new ShaderBuiltinConstantTestInstance<DataType>(context, m_getValue, *m_executor, m_varName); };
152 const std::string m_varName;
153 const GetConstantValueFunc m_getValue;
154 const std::string m_requiredExt;
155 ShaderExecutor* m_executor;
156 glu::ShaderType m_shaderType;
161 struct GLConstantTypeForVKType {};
164 struct GLConstantTypeForVKType<tcu::UVec3>
166 typedef tcu::IVec3 GLConstantType;
170 struct GLConstantTypeForVKType<deUint32>
172 typedef deInt32 GLConstantType;
176 struct GLConstantTypeForVKType<deInt32>
178 typedef deInt32 GLConstantType;
181 template<typename DataType>
182 ShaderBuiltinConstantCase<DataType>::ShaderBuiltinConstantCase (tcu::TestContext& testCtx, const char* varName, glu::ShaderType shaderType, GetConstantValueFunc getValue, const char* requiredExt)
183 : TestCase (testCtx, makeCaseName(varName, shaderType).c_str(), varName)
184 , m_varName (varName)
185 , m_getValue (getValue)
186 , m_requiredExt (requiredExt ? requiredExt : "")
187 , m_shaderType (shaderType)
189 DE_ASSERT(!requiredExt == m_requiredExt.empty());
191 ShaderSpec shaderSpec;
192 shaderSpec.source = string("result = ") + m_varName + ";\n";
193 shaderSpec.outputs.push_back(Symbol("result", glu::VarType(glu::dataTypeOf<typename GLConstantTypeForVKType<DataType>::GLConstantType>(), glu::PRECISION_HIGHP)));
195 if (!m_requiredExt.empty())
196 shaderSpec.globalDeclarations = "#extension " + m_requiredExt + " : require\n";
198 m_executor = createExecutor(shaderType, shaderSpec);
201 template<typename DataType>
202 static void logVarValue (tcu::TestLog& log, const std::string& varName, DataType value)
204 log << TestLog::Message << varName << " = " << value << TestLog::EndMessage;
208 void logVarValue<int> (tcu::TestLog& log, const std::string& varName, int value)
210 log << TestLog::Integer(varName, varName, "", QP_KEY_TAG_NONE, value);
213 // ShaderBuiltinConstantTestInstance
215 template<typename DataType>
216 class ShaderBuiltinConstantTestInstance : public TestInstance
219 ShaderBuiltinConstantTestInstance (Context& ctx, typename ShaderBuiltinConstantCase<DataType>::GetConstantValueFunc getValue, ShaderExecutor& executor, const std::string varName )
221 , m_getValue (getValue)
222 , m_testCtx (ctx.getTestContext())
223 , m_executor (executor)
224 , m_varName (varName)
226 virtual tcu::TestStatus iterate (void);
229 const typename ShaderBuiltinConstantCase<DataType>::GetConstantValueFunc m_getValue;
230 tcu::TestContext& m_testCtx;
231 ShaderExecutor& m_executor;
232 const std::string m_varName;
234 typedef typename GLConstantTypeForVKType<DataType>::GLConstantType GLConstantType;
235 GLConstantType getReference (void);
238 template<typename DataType>
239 typename ShaderBuiltinConstantTestInstance<DataType>::GLConstantType ShaderBuiltinConstantTestInstance<DataType>::getReference (void)
241 return m_getValue(m_context);
245 typename ShaderBuiltinConstantTestInstance<tcu::UVec3>::GLConstantType ShaderBuiltinConstantTestInstance<tcu::UVec3>::getReference (void)
247 return m_getValue(m_context).asInt();
250 template<typename DataType>
251 tcu::TestStatus ShaderBuiltinConstantTestInstance<DataType>::iterate (void)
253 GLConstantType reference = getReference();
254 GLConstantType result = GLConstantType(-1);
255 void* const outputs = &result;
257 m_executor.execute(m_context, 1, DE_NULL, &outputs);
258 logVarValue(m_testCtx.getLog(), m_varName, result);
260 if (result != reference)
262 m_testCtx.getLog() << TestLog::Message << "ERROR: Expected " << m_varName << " = " << reference << TestLog::EndMessage;
263 return tcu::TestStatus::fail("Invalid builtin constant value");
266 return tcu::TestStatus::pass("Pass");
269 // createShaderBuiltinConstantCase
271 template<typename DataType>
272 void createShaderBuiltinConstantCase(tcu::TestCaseGroup* group, tcu::TestContext& testCtx, const char* varName, typename ShaderBuiltinConstantCase<DataType>::GetConstantValueFunc getValue, const char* requiredExt)
274 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; shaderType++)
276 if ((SHADER_TYPES & (1<<shaderType)) != 0)
277 group->addChild(new ShaderBuiltinConstantCase<DataType>(testCtx, varName, static_cast<glu::ShaderType>(shaderType), getValue, requiredExt));
283 ShaderBuiltinConstantTests::ShaderBuiltinConstantTests (tcu::TestContext& testCtx)
284 : TestCaseGroup(testCtx, "constant", "Built-in Constant Tests")
288 ShaderBuiltinConstantTests::~ShaderBuiltinConstantTests (void)
292 void ShaderBuiltinConstantTests::init (void)
294 // Core builtin constants
299 ShaderBuiltinConstantCase<deUint32>::GetConstantValueFunc getValue;
302 { "gl_MaxVertexAttribs", GET_UINT32(maxVertexInputAttributes) },
303 { "gl_MaxVertexOutputVectors", GET_UINT32(maxVertexOutputComponents) },
304 { "gl_MaxFragmentInputVectors", GET_UINT32(maxFragmentInputComponents) },
305 { "gl_MaxDrawBuffers", GET_UINT32(maxColorAttachments) },
306 { "gl_MaxProgramTexelOffset", GET_UINT32(maxTexelOffset) },
312 ShaderBuiltinConstantCase<tcu::UVec3>::GetConstantValueFunc getValue;
315 { "gl_MaxComputeWorkGroupCount", GET_UVEC3(maxComputeWorkGroupCount) },
316 { "gl_MaxComputeWorkGroupSize", GET_UVEC3(maxComputeWorkGroupSize) },
319 tcu::TestCaseGroup* const coreGroup = new tcu::TestCaseGroup(m_testCtx, "core", "Core Specification");
322 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uintConstants); ndx++)
323 createShaderBuiltinConstantCase<deUint32>(coreGroup, m_testCtx, uintConstants[ndx].varName, uintConstants[ndx].getValue, DE_NULL);
325 createShaderBuiltinConstantCase<deInt32>(coreGroup, m_testCtx, "gl_MinProgramTexelOffset", GET_INT32(minTexelOffset), DE_NULL);
327 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uvec3Constants); ndx++)
328 createShaderBuiltinConstantCase<tcu::UVec3>(coreGroup, m_testCtx, uvec3Constants[ndx].varName, uvec3Constants[ndx].getValue, DE_NULL);
331 // EXT_geometry_shader
336 ShaderBuiltinConstantCase<deUint32>::GetConstantValueFunc getValue;
339 { "gl_MaxGeometryInputComponents", GET_UINT32(maxGeometryInputComponents) },
340 { "gl_MaxGeometryOutputComponents", GET_UINT32(maxGeometryOutputComponents) },
341 { "gl_MaxGeometryOutputVertices", GET_UINT32(maxGeometryOutputVertices) },
342 { "gl_MaxGeometryTotalOutputComponents", GET_UINT32(maxGeometryTotalOutputComponents) },
345 tcu::TestCaseGroup* const geomGroup = new tcu::TestCaseGroup(m_testCtx, "geometry_shader", "GL_EXT_geometry_shader");
348 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uintConstants); ndx++)
349 createShaderBuiltinConstantCase<deUint32>(geomGroup, m_testCtx, uintConstants[ndx].varName, uintConstants[ndx].getValue, "GL_EXT_geometry_shader");
352 // EXT_tessellation_shader
357 ShaderBuiltinConstantCase<deUint32>::GetConstantValueFunc getValue;
360 { "gl_MaxTessControlInputComponents", GET_UINT32(maxTessellationControlPerVertexInputComponents) },
361 { "gl_MaxTessControlOutputComponents", GET_UINT32(maxTessellationControlPerVertexOutputComponents) },
362 { "gl_MaxTessControlTotalOutputComponents", GET_UINT32(maxTessellationControlTotalOutputComponents) },
364 { "gl_MaxTessEvaluationInputComponents", GET_UINT32(maxTessellationEvaluationInputComponents) },
365 { "gl_MaxTessEvaluationOutputComponents", GET_UINT32(maxTessellationEvaluationOutputComponents) },
367 { "gl_MaxTessPatchComponents", GET_UINT32(maxTessellationControlPerPatchOutputComponents) },
369 { "gl_MaxPatchVertices", GET_UINT32(maxTessellationPatchSize) },
370 { "gl_MaxTessGenLevel", GET_UINT32(maxTessellationGenerationLevel) },
373 tcu::TestCaseGroup* const tessGroup = new tcu::TestCaseGroup(m_testCtx, "tessellation_shader", "GL_EXT_tessellation_shader");
376 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uintConstants); ndx++)
377 createShaderBuiltinConstantCase<deUint32>(tessGroup, m_testCtx, uintConstants[ndx].varName, uintConstants[ndx].getValue, "GL_EXT_tessellation_shader");