1 #ifndef _GLCSUBGROUPSTESTSUTILS_HPP
2 #define _GLCSUBGROUPSTESTSUTILS_HPP
3 /*------------------------------------------------------------------------
4 * OpenGL Conformance Tests
5 * ------------------------
7 * Copyright (c) 2017-2019 The Khronos Group Inc.
8 * Copyright (c) 2017 Codeplay Software Ltd.
9 * Copyright (c) 2019 NVIDIA Corporation.
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
25 * \brief Subgroups tests utility classes
26 */ /*--------------------------------------------------------------------*/
29 #include "deSTLUtil.hpp"
30 #include "deStringUtil.hpp"
31 #include "glwEnums.hpp"
32 #include "glwFunctions.hpp"
33 #include "glwDefs.hpp"
34 #include "tcuDefs.hpp"
35 #include "tcuTestCase.hpp"
36 #include "glcTestCase.hpp"
37 #include "glcSpirvUtils.hpp"
39 #include "tcuFormatUtil.hpp"
40 #include "tcuTestLog.hpp"
41 #include "tcuVectorUtil.hpp"
43 #include "gluShaderUtil.hpp"
44 #include "gluContextInfo.hpp"
46 #include "deSharedPtr.hpp"
47 #include "deUniquePtr.hpp"
62 template<typename Program>
63 class ProgramCollection
66 ProgramCollection (void);
67 ~ProgramCollection (void);
71 Program& add (const std::string& name);
72 void add (const std::string& name, de::MovePtr<Program>& program);
74 bool contains (const std::string& name) const;
75 const Program& get (const std::string& name) const;
80 typedef typename std::map<std::string, Program*>::const_iterator IteratorImpl;
83 explicit Iterator (const IteratorImpl& i) : m_impl(i) {}
85 Iterator& operator++ (void) { ++m_impl; return *this; }
86 const Program& operator* (void) const { return getProgram(); }
88 const std::string& getName (void) const { return m_impl->first; }
89 const Program& getProgram (void) const { return *m_impl->second; }
91 bool operator== (const Iterator& other) const { return m_impl == other.m_impl; }
92 bool operator!= (const Iterator& other) const { return m_impl != other.m_impl; }
99 Iterator begin (void) const { return Iterator(m_programs.begin()); }
100 Iterator end (void) const { return Iterator(m_programs.end()); }
102 bool empty (void) const { return m_programs.empty(); }
105 typedef std::map<std::string, Program*> ProgramMap;
107 ProgramMap m_programs;
110 template<typename Program>
111 ProgramCollection<Program>::ProgramCollection (void)
115 template<typename Program>
116 ProgramCollection<Program>::~ProgramCollection (void)
121 template<typename Program>
122 void ProgramCollection<Program>::clear (void)
124 for (typename ProgramMap::const_iterator i = m_programs.begin(); i != m_programs.end(); ++i)
129 template<typename Program>
130 Program& ProgramCollection<Program>::add (const std::string& name)
132 DE_ASSERT(!contains(name));
133 de::MovePtr<Program> prog = de::newMovePtr<Program>();
134 m_programs[name] = prog.get();
136 return *m_programs[name];
139 template<typename Program>
140 void ProgramCollection<Program>::add (const std::string& name, de::MovePtr<Program>& program)
142 DE_ASSERT(!contains(name));
143 m_programs[name] = program.get();
147 template<typename Program>
148 bool ProgramCollection<Program>::contains (const std::string& name) const
150 return de::contains(m_programs, name);
153 template<typename Program>
154 const Program& ProgramCollection<Program>::get (const std::string& name) const
156 DE_ASSERT(contains(name));
157 return *m_programs.find(name)->second;
162 std::vector<std::string> sources[glu::SHADERTYPE_LAST];
164 GlslSource& operator<< (const glu::ShaderSource& shaderSource)
166 sources[shaderSource.shaderType].push_back(shaderSource.source);
171 typedef ProgramCollection<GlslSource> SourceCollections;
177 Context (deqp::Context& deqpCtx)
179 , m_sourceCollection()
180 , m_glslVersion(glu::getContextTypeGLSLVersion(m_deqpCtx.getRenderContext().getType()))
181 , m_shaderType(SHADER_TYPE_GLSL)
184 deqp::Context& getDeqpContext (void) const { return m_deqpCtx; }
185 SourceCollections& getSourceCollection (void) { return m_sourceCollection; }
186 glu::GLSLVersion getGLSLVersion (void) { return m_glslVersion; }
187 ShaderType getShaderType (void) { return m_shaderType; }
188 void setShaderType (ShaderType type) { m_shaderType = type; }
191 deqp::Context& m_deqpCtx;
192 SourceCollections m_sourceCollection;
193 glu::GLSLVersion m_glslVersion;
194 ShaderType m_shaderType;
200 template<typename Arg0>
201 class SubgroupFactory : public deqp::TestCase
204 //void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
205 typedef void (*InitFunction)(SourceCollections& programCollection, Arg0 arg0);
206 //void supportedCheck (Context& context, CaseDefinition caseDef)
207 typedef void (*SupportFunction)(Context& context, Arg0 arg0);
208 //tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
209 typedef tcu::TestStatus (*TestFunction)(Context& context, const Arg0 arg0);
212 SubgroupFactory(deqp::Context& context, tcu::TestNodeType type, const std::string& name, const std::string& desc,
213 SupportFunction suppFunc, InitFunction initFunc, TestFunction testFunc, Arg0 arg0)
214 : TestCase(context, type, name.c_str(), desc.c_str())
215 , m_supportedFunc(suppFunc)
216 , m_initFunc(initFunc)
217 , m_testFunc(testFunc)
219 , m_glcContext(m_context)
224 m_supportedFunc(m_glcContext, m_arg0);
226 m_initFunc(m_glcContext.getSourceCollection(), m_arg0);
234 tcu::TestNode::IterateResult iterate()
236 DE_ASSERT(m_testFunc);
237 tcu::TestLog& log = m_testCtx.getLog();
240 // do SPIRV version of tests if supported
241 log << tcu::TestLog::Message << "SPIRV pass beginning..." << tcu::TestLog::EndMessage;
242 spirvUtils::checkGlSpirvSupported(m_glcContext.getDeqpContext());
244 m_glcContext.setShaderType(SHADER_TYPE_SPIRV);
246 const tcu::TestStatus result = m_testFunc(m_glcContext, m_arg0);
247 if (result.isComplete())
249 DE_ASSERT(m_testCtx.getTestResult() == QP_TEST_RESULT_LAST);
250 if (result.getCode() == QP_TEST_RESULT_PASS)
252 log << tcu::TestLog::Message << "SPIRV pass completed successfully ("
253 << result.getDescription() << ")." << tcu::TestLog::EndMessage;
255 // test failed - log result and stop
256 m_testCtx.setTestResult(result.getCode(), result.getDescription().c_str());
257 return tcu::TestNode::STOP;
260 } catch(tcu::NotSupportedError& e)
262 log << tcu::TestLog::Message << "SPIRV pass skipped ("
263 << e.getMessage() << ")." << tcu::TestLog::EndMessage;
266 // do GLSL version of the tests
267 log << tcu::TestLog::Message << "GLSL pass beginning..." << tcu::TestLog::EndMessage;
268 m_glcContext.setShaderType(SHADER_TYPE_GLSL);
269 const tcu::TestStatus result = m_testFunc(m_glcContext, m_arg0);
271 if (result.isComplete())
273 DE_ASSERT(m_testCtx.getTestResult() == QP_TEST_RESULT_LAST);
274 log << tcu::TestLog::Message << "GLSL pass completed successfully ("
275 << result.getDescription() << ")." << tcu::TestLog::EndMessage;
276 m_testCtx.setTestResult(result.getCode(), result.getDescription().c_str());
277 return tcu::TestNode::STOP;
280 return tcu::TestNode::CONTINUE;
283 static void addFunctionCaseWithPrograms (deqp::TestCaseGroup* group,
284 const std::string& name,
285 const std::string& desc,
286 SupportFunction suppFunc,
287 InitFunction initFunc,
288 TestFunction testFunc,
291 group->addChild(new SubgroupFactory(group->getContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, suppFunc, initFunc, testFunc, arg0));
295 SupportFunction m_supportedFunc;
296 InitFunction m_initFunc;
297 TestFunction m_testFunc;
300 Context m_glcContext;
304 typedef enum ShaderStageFlags
306 SHADER_STAGE_VERTEX_BIT = GL_VERTEX_SHADER_BIT,
307 SHADER_STAGE_FRAGMENT_BIT = GL_FRAGMENT_SHADER_BIT,
308 SHADER_STAGE_GEOMETRY_BIT = GL_GEOMETRY_SHADER_BIT,
309 SHADER_STAGE_TESS_CONTROL_BIT = GL_TESS_CONTROL_SHADER_BIT,
310 SHADER_STAGE_TESS_EVALUATION_BIT = GL_TESS_EVALUATION_SHADER_BIT,
311 SHADER_STAGE_COMPUTE_BIT = GL_COMPUTE_SHADER_BIT,
312 SHADER_STAGE_ALL_GRAPHICS = (SHADER_STAGE_VERTEX_BIT | SHADER_STAGE_FRAGMENT_BIT | SHADER_STAGE_GEOMETRY_BIT |
313 SHADER_STAGE_TESS_CONTROL_BIT | SHADER_STAGE_TESS_EVALUATION_BIT ),
314 SHADER_STAGE_ALL_VALID = (SHADER_STAGE_ALL_GRAPHICS | SHADER_STAGE_COMPUTE_BIT),
317 typedef enum SubgroupFeatureFlags
319 SUBGROUP_FEATURE_BASIC_BIT = GL_SUBGROUP_FEATURE_BASIC_BIT_KHR,
320 SUBGROUP_FEATURE_VOTE_BIT = GL_SUBGROUP_FEATURE_VOTE_BIT_KHR,
321 SUBGROUP_FEATURE_ARITHMETIC_BIT = GL_SUBGROUP_FEATURE_ARITHMETIC_BIT_KHR,
322 SUBGROUP_FEATURE_BALLOT_BIT = GL_SUBGROUP_FEATURE_BALLOT_BIT_KHR,
323 SUBGROUP_FEATURE_SHUFFLE_BIT = GL_SUBGROUP_FEATURE_SHUFFLE_BIT_KHR,
324 SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT = GL_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT_KHR,
325 SUBGROUP_FEATURE_CLUSTERED_BIT = GL_SUBGROUP_FEATURE_CLUSTERED_BIT_KHR,
326 SUBGROUP_FEATURE_QUAD_BIT = GL_SUBGROUP_FEATURE_QUAD_BIT_KHR,
327 SUBGROUP_FEATURE_PARTITIONED_BIT_NV = GL_SUBGROUP_FEATURE_PARTITIONED_BIT_NV,
328 SUBGROUP_FEATURE_ALL_VALID = (SUBGROUP_FEATURE_BASIC_BIT | SUBGROUP_FEATURE_VOTE_BIT | SUBGROUP_FEATURE_ARITHMETIC_BIT |
329 SUBGROUP_FEATURE_BALLOT_BIT | SUBGROUP_FEATURE_SHUFFLE_BIT | SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT |
330 SUBGROUP_FEATURE_CLUSTERED_BIT | SUBGROUP_FEATURE_QUAD_BIT | SUBGROUP_FEATURE_QUAD_BIT |
331 SUBGROUP_FEATURE_PARTITIONED_BIT_NV),
332 } SubgroupFeatureFlags;
336 FORMAT_UNDEFINED = 0,
337 FORMAT_R32_SINT = GL_R32I,
338 FORMAT_R32_UINT = GL_R32UI,
339 FORMAT_R32G32_SINT = GL_RG32I,
340 FORMAT_R32G32_UINT = GL_RG32UI,
341 FORMAT_R32G32B32_SINT = GL_RGB32I,
342 FORMAT_R32G32B32_UINT = GL_RGB32UI,
343 FORMAT_R32G32B32A32_SINT = GL_RGBA32I,
344 FORMAT_R32G32B32A32_UINT = GL_RGBA32UI,
345 FORMAT_R32_SFLOAT = GL_R32F,
346 FORMAT_R32G32_SFLOAT = GL_RG32F,
347 FORMAT_R32G32B32_SFLOAT = GL_RGB32F,
348 FORMAT_R32G32B32A32_SFLOAT = GL_RGBA32F,
349 FORMAT_R64_SFLOAT = 0x6000,
350 FORMAT_R64G64_SFLOAT,
351 FORMAT_R64G64B64_SFLOAT,
352 FORMAT_R64G64B64A64_SFLOAT,
353 FORMAT_R32_BOOL = 0x6100,
355 FORMAT_R32G32B32_BOOL,
356 FORMAT_R32G32B32A32_BOOL,
359 typedef enum DescriptorType
361 DESCRIPTOR_TYPE_UNIFORM_BUFFER = GL_UNIFORM_BUFFER,
362 DESCRIPTOR_TYPE_STORAGE_BUFFER = GL_SHADER_STORAGE_BUFFER,
363 DESCRIPTOR_TYPE_STORAGE_IMAGE = GL_TEXTURE_2D,
366 // A struct to represent input data to a shader
370 initializeType (InitializeNone),
371 format (FORMAT_UNDEFINED),
375 stages ((ShaderStageFlags)0u)
378 enum InputDataInitializeType
386 deUint64 numElements;
389 ShaderStageFlags stages;
392 std::string getSharedMemoryBallotHelper();
394 deUint32 getSubgroupSize(Context& context);
396 deUint32 maxSupportedSubgroupSize();
398 std::string getShaderStageName(ShaderStageFlags stage);
400 std::string getSubgroupFeatureName(SubgroupFeatureFlags bit);
402 void addNoSubgroupShader (SourceCollections& programCollection);
404 std::string getVertShaderForStage(ShaderStageFlags stage);
406 bool isSubgroupSupported(Context& context);
408 bool areSubgroupOperationsSupportedForStage(
409 Context& context, ShaderStageFlags stage);
411 bool areSubgroupOperationsRequiredForStage(ShaderStageFlags stage);
413 bool isSubgroupFeatureSupportedForDevice(Context& context, SubgroupFeatureFlags bit);
415 bool isFragmentSSBOSupportedForDevice(Context& context);
417 bool isVertexSSBOSupportedForDevice(Context& context);
419 bool isDoubleSupportedForDevice(Context& context);
421 bool isDoubleFormat(Format format);
423 std::string getFormatNameForGLSL(Format format);
425 void addGeometryShadersFromTemplate (const std::string& glslTemplate, SourceCollections& collection);
427 void setVertexShaderFrameBuffer (SourceCollections& programCollection);
429 void setFragmentShaderFrameBuffer (SourceCollections& programCollection);
431 void setFragmentShaderFrameBuffer (SourceCollections& programCollection);
433 void setTesCtrlShaderFrameBuffer (SourceCollections& programCollection);
435 void setTesEvalShaderFrameBuffer (SourceCollections& programCollection);
437 bool check(std::vector<const void*> datas,
438 deUint32 width, deUint32 ref);
440 bool checkCompute(std::vector<const void*> datas,
441 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
444 tcu::TestStatus makeTessellationEvaluationFrameBufferTest(Context& context, Format format,
445 SSBOData* extraData, deUint32 extraDataCount,
446 bool (*checkResult)(std::vector<const void*> datas, deUint32 width, deUint32 subgroupSize),
447 const ShaderStageFlags shaderStage = SHADER_STAGE_ALL_GRAPHICS);
449 tcu::TestStatus makeGeometryFrameBufferTest(Context& context, Format format, SSBOData* extraData,
450 deUint32 extraDataCount,
451 bool (*checkResult)(std::vector<const void*> datas, deUint32 width, deUint32 subgroupSize));
453 tcu::TestStatus allStages(Context& context, Format format,
454 SSBOData* extraData, deUint32 extraDataCount,
455 bool (*checkResult)(std::vector<const void*> datas, deUint32 width, deUint32 subgroupSize),
456 const ShaderStageFlags shaderStage);
458 tcu::TestStatus makeVertexFrameBufferTest(Context& context, Format format,
459 SSBOData* extraData, deUint32 extraDataCount,
460 bool (*checkResult)(std::vector<const void*> datas, deUint32 width, deUint32 subgroupSize));
462 tcu::TestStatus makeFragmentFrameBufferTest(Context& context, Format format,
463 SSBOData* extraData, deUint32 extraDataCount,
464 bool (*checkResult)(std::vector<const void*> datas, deUint32 width,
465 deUint32 height, deUint32 subgroupSize));
467 tcu::TestStatus makeComputeTest(
468 Context& context, Format format, SSBOData* inputs,
469 deUint32 inputsCount,
470 bool (*checkResult)(std::vector<const void*> datas,
471 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
472 deUint32 subgroupSize));
476 #endif // _GLCSUBGROUPSTESTSUTILS_HPP