dEQP-VK.renderpass: Set IMAGE_USAGE_TRANSFER_SRC_BIT when needed
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / shaderexecutor / vktShaderBuiltinConstantTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7  *
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:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
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.
22  *
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.
30  *
31  *//*!
32  * \file
33  * \brief Shader built-in constant tests.
34  *//*--------------------------------------------------------------------*/
35
36 #include "vktShaderBuiltinConstantTests.hpp"
37 #include "vktShaderExecutor.hpp"
38 #include "deUniquePtr.hpp"
39 #include "deStringUtil.hpp"
40 #include "tcuTestLog.hpp"
41
42 using std::string;
43 using std::vector;
44 using tcu::TestLog;
45 using namespace vk;
46
47 namespace vkt
48 {
49 namespace shaderexecutor
50 {
51
52 namespace
53 {
54
55 static deUint32 getUint32 (deUint32 VkPhysicalDeviceLimits::* ptr, Context &ctx)
56 {
57         VkPhysicalDeviceProperties properties;
58         ctx.getInstanceInterface().getPhysicalDeviceProperties(ctx.getPhysicalDevice(), &properties);
59         return properties.limits.*ptr;
60 }
61
62 template<deUint32 VkPhysicalDeviceLimits::* ptr>
63 static deUint32 getUint32 (Context &ctx)
64 {
65         return getUint32(ptr, ctx);
66 }
67
68 #define GET_UINT32(name) getUint32<&VkPhysicalDeviceLimits::name>
69
70 static deInt32 getInt32 (deInt32 VkPhysicalDeviceLimits::* ptr, Context &ctx)
71 {
72         VkPhysicalDeviceProperties properties;
73         ctx.getInstanceInterface().getPhysicalDeviceProperties(ctx.getPhysicalDevice(), &properties);
74         return properties.limits.*ptr;
75 }
76
77 template<deInt32 VkPhysicalDeviceLimits::* ptr>
78 static deInt32 getInt32 (Context &ctx)
79 {
80         return getInt32(ptr, ctx);
81 }
82
83 #define GET_INT32(name) getInt32<&VkPhysicalDeviceLimits::name>
84
85 static tcu::UVec3 getUVec3 (deUint32 (VkPhysicalDeviceLimits::*ptr)[3], Context &ctx)
86 {
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]);
90 }
91
92 template<deUint32 (VkPhysicalDeviceLimits::*ptr)[3]>
93 static tcu::UVec3 getUVec3 (Context &ctx)
94 {
95         return getUVec3(ptr, ctx);
96 }
97
98 #define GET_UVEC3(name) getUVec3<&VkPhysicalDeviceLimits::name>
99
100 static std::string makeCaseName (const std::string& varName, glu::ShaderType shaderType)
101 {
102         DE_ASSERT(varName.length() > 3);
103         DE_ASSERT(varName.substr(0,3) == "gl_");
104
105         std::ostringstream name;
106         name << de::toLower(char(varName[3]));
107
108         for (size_t ndx = 4; ndx < varName.length(); ndx++)
109         {
110                 const char c = char(varName[ndx]);
111                 if (de::isUpper(c))
112                         name << '_' << de::toLower(c);
113                 else
114                         name << c;
115         }
116         name << '_' << glu::getShaderTypeName(glu::ShaderType(shaderType));
117         return name.str();
118 }
119
120 enum
121 {
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),
128
129         SHADER_TYPES = VS|TC|TE|GS|FS|CS
130 };
131
132 template<typename DataType>
133 class ShaderBuiltinConstantTestInstance;
134
135 template<typename DataType>
136 class ShaderBuiltinConstantCase : public TestCase
137 {
138 public:
139         typedef DataType (*GetConstantValueFunc) (Context &);
140
141                                                                 ShaderBuiltinConstantCase       (tcu::TestContext& testCtx, const char* varName, glu::ShaderType shaderType, GetConstantValueFunc getValue, const char* requiredExt);
142         virtual                                         ~ShaderBuiltinConstantCase      (void) {};
143
144         virtual void                            initPrograms                            (vk::SourceCollections& programCollection) const
145                                                                 {
146                                                                         m_executor->setShaderSources(programCollection);
147                                                                 }
148
149         virtual TestInstance* createInstance (Context& context) const { return new ShaderBuiltinConstantTestInstance<DataType>(context, m_getValue, *m_executor, m_varName); };
150
151 private:
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;
157         ShaderSpec                                                      m_spec;
158 };
159
160 template<typename T>
161 struct GLConstantTypeForVKType {};
162
163 template<>
164 struct GLConstantTypeForVKType<tcu::UVec3>
165 {
166         typedef tcu::IVec3 GLConstantType;
167 };
168
169 template<>
170 struct GLConstantTypeForVKType<deUint32>
171 {
172         typedef deInt32 GLConstantType;
173 };
174
175 template<>
176 struct GLConstantTypeForVKType<deInt32>
177 {
178         typedef deInt32 GLConstantType;
179 };
180
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)
188 {
189         DE_ASSERT(!requiredExt == m_requiredExt.empty());
190
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)));
194
195         if (!m_requiredExt.empty())
196                 shaderSpec.globalDeclarations = "#extension " + m_requiredExt + " : require\n";
197
198         m_executor = createExecutor(shaderType, shaderSpec);
199 }
200
201 template<typename DataType>
202 static void logVarValue (tcu::TestLog& log, const std::string& varName, DataType value)
203 {
204         log << TestLog::Message << varName << " = " << value << TestLog::EndMessage;
205 }
206
207 template<>
208 void logVarValue<int> (tcu::TestLog& log, const std::string& varName, int value)
209 {
210         log << TestLog::Integer(varName, varName, "", QP_KEY_TAG_NONE, value);
211 }
212
213 // ShaderBuiltinConstantTestInstance
214
215 template<typename DataType>
216 class ShaderBuiltinConstantTestInstance : public TestInstance
217 {
218 public:
219                                                                 ShaderBuiltinConstantTestInstance (Context& ctx, typename ShaderBuiltinConstantCase<DataType>::GetConstantValueFunc getValue, ShaderExecutor& executor, const std::string varName )
220                                                                         : TestInstance  (ctx)
221                                                                         , m_getValue    (getValue)
222                                                                         , m_testCtx             (ctx.getTestContext())
223                                                                         , m_executor    (executor)
224                                                                         , m_varName             (varName)
225                                                                 {}
226         virtual tcu::TestStatus         iterate (void);
227
228 private:
229         const typename ShaderBuiltinConstantCase<DataType>::GetConstantValueFunc        m_getValue;
230         tcu::TestContext&                                                                                                                       m_testCtx;
231         ShaderExecutor&                                                                                                                         m_executor;
232         const std::string                                                                                                                       m_varName;
233
234         typedef typename GLConstantTypeForVKType<DataType>::GLConstantType GLConstantType;
235         GLConstantType getReference (void);
236 };
237
238 template<typename DataType>
239 typename ShaderBuiltinConstantTestInstance<DataType>::GLConstantType ShaderBuiltinConstantTestInstance<DataType>::getReference (void)
240 {
241         return m_getValue(m_context);
242 }
243
244 template<>
245 typename ShaderBuiltinConstantTestInstance<tcu::UVec3>::GLConstantType ShaderBuiltinConstantTestInstance<tcu::UVec3>::getReference (void)
246 {
247         return m_getValue(m_context).asInt();
248 }
249
250 template<typename DataType>
251 tcu::TestStatus ShaderBuiltinConstantTestInstance<DataType>::iterate (void)
252 {
253         GLConstantType                  reference       = getReference();
254         GLConstantType                  result          = GLConstantType(-1);
255         void* const                             outputs         = &result;
256
257         m_executor.execute(m_context, 1, DE_NULL, &outputs);
258         logVarValue(m_testCtx.getLog(), m_varName, result);
259
260         if (result != reference)
261         {
262                 m_testCtx.getLog() << TestLog::Message << "ERROR: Expected " << m_varName << " = " << reference << TestLog::EndMessage;
263                 return tcu::TestStatus::fail("Invalid builtin constant value");
264         }
265         else
266                 return tcu::TestStatus::pass("Pass");
267 }
268
269 // createShaderBuiltinConstantCase
270
271 template<typename DataType>
272 void createShaderBuiltinConstantCase(tcu::TestCaseGroup* group, tcu::TestContext& testCtx, const char* varName, typename ShaderBuiltinConstantCase<DataType>::GetConstantValueFunc getValue, const char* requiredExt)
273 {
274         for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; shaderType++)
275         {
276                 if ((SHADER_TYPES & (1<<shaderType)) != 0)
277                         group->addChild(new ShaderBuiltinConstantCase<DataType>(testCtx, varName, static_cast<glu::ShaderType>(shaderType), getValue, requiredExt));
278         }
279 }
280
281 } // anonymous
282
283 ShaderBuiltinConstantTests::ShaderBuiltinConstantTests (tcu::TestContext& testCtx)
284         : TestCaseGroup(testCtx, "constant", "Built-in Constant Tests")
285 {
286 }
287
288 ShaderBuiltinConstantTests::~ShaderBuiltinConstantTests (void)
289 {
290 }
291
292 void ShaderBuiltinConstantTests::init (void)
293 {
294         // Core builtin constants
295         {
296                 static const struct
297                 {
298                         const char*                                                                                                     varName;
299                         ShaderBuiltinConstantCase<deUint32>::GetConstantValueFunc       getValue;
300                 } uintConstants[] =
301                 {
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)                                                              },
307                 };
308
309                 static const struct
310                 {
311                         const char*                                                                                                     varName;
312                         ShaderBuiltinConstantCase<tcu::UVec3>::GetConstantValueFunc     getValue;
313                 } uvec3Constants[] =
314                 {
315                         { "gl_MaxComputeWorkGroupCount",                        GET_UVEC3(maxComputeWorkGroupCount)                                             },
316                         { "gl_MaxComputeWorkGroupSize",                         GET_UVEC3(maxComputeWorkGroupSize)                                              },
317                 };
318
319                 tcu::TestCaseGroup* const coreGroup = new tcu::TestCaseGroup(m_testCtx, "core", "Core Specification");
320                 addChild(coreGroup);
321
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);
324
325                 createShaderBuiltinConstantCase<deInt32>(coreGroup, m_testCtx, "gl_MinProgramTexelOffset", GET_INT32(minTexelOffset), DE_NULL);
326
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);
329         }
330
331         // EXT_geometry_shader
332         {
333                 static const struct
334                 {
335                         const char*                                                                                                     varName;
336                         ShaderBuiltinConstantCase<deUint32>::GetConstantValueFunc       getValue;
337                 } uintConstants[] =
338                 {
339                         { "gl_MaxGeometryInputComponents",                      GET_UINT32(maxGeometryInputComponents)                                  },
340                         { "gl_MaxGeometryOutputComponents",                     GET_UINT32(maxGeometryOutputComponents)                                 },
341                         { "gl_MaxGeometryOutputVertices",                       GET_UINT32(maxGeometryOutputVertices)                                   },
342                         { "gl_MaxGeometryTotalOutputComponents",        GET_UINT32(maxGeometryTotalOutputComponents)                    },
343                 };
344
345                 tcu::TestCaseGroup* const geomGroup = new tcu::TestCaseGroup(m_testCtx, "geometry_shader", "GL_EXT_geometry_shader");
346                 addChild(geomGroup);
347
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");
350         }
351
352         // EXT_tessellation_shader
353         {
354                 static const struct
355                 {
356                         const char*                                                                                                     varName;
357                         ShaderBuiltinConstantCase<deUint32>::GetConstantValueFunc       getValue;
358                 } uintConstants[] =
359                 {
360                         { "gl_MaxTessControlInputComponents",                   GET_UINT32(maxTessellationControlPerVertexInputComponents)              },
361                         { "gl_MaxTessControlOutputComponents",                  GET_UINT32(maxTessellationControlPerVertexOutputComponents)             },
362                         { "gl_MaxTessControlTotalOutputComponents",             GET_UINT32(maxTessellationControlTotalOutputComponents)                 },
363
364                         { "gl_MaxTessEvaluationInputComponents",                GET_UINT32(maxTessellationEvaluationInputComponents)                    },
365                         { "gl_MaxTessEvaluationOutputComponents",               GET_UINT32(maxTessellationEvaluationOutputComponents)                   },
366
367                         { "gl_MaxTessPatchComponents",                                  GET_UINT32(maxTessellationControlPerPatchOutputComponents)              },
368
369                         { "gl_MaxPatchVertices",                                                GET_UINT32(maxTessellationPatchSize)                                                    },
370                         { "gl_MaxTessGenLevel",                                                 GET_UINT32(maxTessellationGenerationLevel)                                              },
371                 };
372
373                 tcu::TestCaseGroup* const tessGroup = new tcu::TestCaseGroup(m_testCtx, "tessellation_shader", "GL_EXT_tessellation_shader");
374                 addChild(tessGroup);
375
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");
378         }
379 }
380
381 } // shaderexecutor
382 } // vkt