1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 The Khronos Group Inc.
6  * Copyright (c) 2019 Google Inc.
7  * Copyright (c) 2017 Codeplay Software Ltd.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */ /*!
22  * \file
23  * \brief Subgroups Tests
24  */ /*--------------------------------------------------------------------*/
25 
26 #include "vktSubgroupsBuiltinMaskVarTests.hpp"
27 #include "vktSubgroupsTestsUtils.hpp"
28 
29 #include <string>
30 #include <vector>
31 
32 using namespace tcu;
33 using namespace std;
34 using namespace vk;
35 
36 namespace vkt
37 {
38 namespace subgroups
39 {
40 
41 enum TestType
42 {
43     TEST_TYPE_SUBGROUP_EQ_MASK = 0,
44     TEST_TYPE_SUBGROUP_GE_MASK = 1,
45     TEST_TYPE_SUBGROUP_GT_MASK = 2,
46     TEST_TYPE_SUBGROUP_LE_MASK = 3,
47     TEST_TYPE_SUBGROUP_LT_MASK = 4,
48     TEST_TYPE_LAST
49 };
50 
51 const char *TestTypeSpirvBuiltins[] = {
52     "SubgroupEqMask", "SubgroupGeMask", "SubgroupGtMask", "SubgroupLeMask", "SubgroupLtMask",
53 };
54 DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(TestTypeSpirvBuiltins) == TEST_TYPE_LAST);
55 
56 const char *TestTypeMathOps[] = {
57     "==", ">=", ">", "<=", "<",
58 };
59 DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(TestTypeMathOps) == TEST_TYPE_LAST);
60 
61 const char *TestTypeSpirvOps[] = {
62     "OpIEqual", "OpUGreaterThanEqual", "OpUGreaterThan", "OpULessThanEqual", "OpULessThan",
63 };
64 DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(TestTypeSpirvOps) == TEST_TYPE_LAST);
65 
66 namespace
67 {
68 struct CaseDefinition
69 {
70     TestType testType;
71     VkShaderStageFlags shaderStage;
72     de::SharedPtr<bool> geometryPointSizeSupported;
73     bool requiredSubgroupSize;
74 };
75 } // namespace
76 
getTestSpirvBuiltinName(TestType testType)77 static inline string getTestSpirvBuiltinName(TestType testType)
78 {
79     return TestTypeSpirvBuiltins[static_cast<uint32_t>(testType)];
80 }
81 
getTestName(TestType testType)82 static inline string getTestName(TestType testType)
83 {
84     return de::toLower(getTestSpirvBuiltinName(testType));
85 }
86 
getTestVarName(TestType testType)87 static inline string getTestVarName(TestType testType)
88 {
89     return string("gl_") + getTestSpirvBuiltinName(testType);
90 }
91 
getTestMathOp(TestType testType)92 static inline string getTestMathOp(TestType testType)
93 {
94     return TestTypeMathOps[static_cast<uint32_t>(testType)];
95 }
96 
getTestSpirvOp(TestType testType)97 static inline string getTestSpirvOp(TestType testType)
98 {
99     return TestTypeSpirvOps[static_cast<uint32_t>(testType)];
100 }
101 
checkVertexPipelineStages(const void * internalData,vector<const void * > datas,uint32_t width,uint32_t)102 static bool checkVertexPipelineStages(const void *internalData, vector<const void *> datas, uint32_t width, uint32_t)
103 {
104     DE_UNREF(internalData);
105 
106     return check(datas, width, 1);
107 }
108 
checkComputeOrMeshStage(const void * internalData,vector<const void * > datas,const uint32_t numWorkgroups[3],const uint32_t localSize[3],uint32_t)109 static bool checkComputeOrMeshStage(const void *internalData, vector<const void *> datas,
110                                     const uint32_t numWorkgroups[3], const uint32_t localSize[3], uint32_t)
111 {
112     DE_UNREF(internalData);
113 
114     return checkComputeOrMesh(datas, numWorkgroups, localSize, 1);
115 }
116 
subgroupComparison(const CaseDefinition & caseDef)117 static inline string subgroupComparison(const CaseDefinition &caseDef)
118 {
119     const string spirvOp = getTestSpirvOp(caseDef.testType);
120     const string result  = (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage) ?
121                                "%56 = " + spirvOp + " %11 %53 %55\n" :
122                                "%38 = " + spirvOp + " %16 %35 %37\n";
123 
124     return result;
125 }
126 
varSubgroupMask(const CaseDefinition & caseDef)127 static inline string varSubgroupMask(const CaseDefinition &caseDef)
128 {
129     const string spirvBuiltin = getTestSpirvBuiltinName(caseDef.testType);
130     const string result       = (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage) ?
131                                     "OpDecorate %40 BuiltIn " + spirvBuiltin + "\n" :
132                                     "OpDecorate %22 BuiltIn " + spirvBuiltin + "\n";
133 
134     return result;
135 }
136 
subgroupMask(const CaseDefinition & caseDef)137 string subgroupMask(const CaseDefinition &caseDef)
138 {
139     const string varName = getTestVarName(caseDef.testType);
140     const string comp    = getTestMathOp(caseDef.testType);
141     ostringstream bdy;
142 
143     bdy << "  uint tempResult = 0x1;\n"
144         << "  uvec4 mask = subgroupBallot(true);\n"
145         << "  const uvec4 var = " << varName << ";\n"
146         << "  for (uint i = 0; i < gl_SubgroupSize; i++)\n"
147         << "  {\n"
148         << "    if ((i " << comp << " gl_SubgroupInvocationID) ^^ subgroupBallotBitExtract(var, i))\n"
149         << "    {\n"
150         << "      tempResult = 0;\n"
151         << "    }\n"
152         << "  }\n"
153         << "  uint c = bitCount(var.x) + bitCount(var.y) + bitCount(var.z) + bitCount(var.w);\n"
154         << "  if (subgroupBallotBitCount(var) != c)\n"
155         << "  {\n"
156         << "    tempResult = 0;\n"
157         << "  }\n"
158         << "  tempRes = tempResult;\n";
159 
160     return bdy.str();
161 }
162 
initFrameBufferPrograms(SourceCollections & programCollection,CaseDefinition caseDef)163 void initFrameBufferPrograms(SourceCollections &programCollection, CaseDefinition caseDef)
164 {
165     const SpirVAsmBuildOptions buildOptionsSpr(programCollection.usedVulkanVersion, SPIRV_VERSION_1_3);
166     const string comparison = subgroupComparison(caseDef);
167     const string mask       = varSubgroupMask(caseDef);
168 
169     subgroups::setFragmentShaderFrameBuffer(programCollection);
170 
171     if (VK_SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
172         subgroups::setVertexShaderFrameBuffer(programCollection);
173 
174     if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
175     {
176         /*
177             const string bdy = subgroupMask(caseDef);
178             const string vertex =
179             "#version 450\n"
180             "#extension GL_KHR_shader_subgroup_ballot: enable\n"
181             "layout(location = 0) out float out_color;\n"
182             "layout(location = 0) in highp vec4 in_position;\n"
183             "\n"
184             "void main (void)\n"
185             "{\n"
186             + bdy +
187             "  out_color = float(tempResult);\n"
188             "  gl_Position = in_position;\n"
189             "  gl_PointSize = 1.0f;\n"
190             "}\n";
191             programCollection.glslSources.add("vert")
192                 << glu::VertexSource(vertex) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
193         */
194 
195         const string vertex = "; SPIR-V\n"
196                               "; Version: 1.3\n"
197                               "; Generator: Khronos Glslang Reference Front End; 2\n"
198                               "; Bound: 123\n"
199                               "; Schema: 0\n"
200                               "OpCapability Shader\n"
201                               "OpCapability GroupNonUniform\n"
202                               "OpCapability GroupNonUniformBallot\n"
203                               "%1 = OpExtInstImport \"GLSL.std.450\"\n"
204                               "OpMemoryModel Logical GLSL450\n"
205                               "OpEntryPoint Vertex %4 \"main\" %22 %32 %36 %107 %114 %117\n" +
206                               mask +
207                               "OpDecorate %32 RelaxedPrecision\n"
208                               "OpDecorate %32 BuiltIn SubgroupSize\n"
209                               "OpDecorate %33 RelaxedPrecision\n"
210                               "OpDecorate %36 RelaxedPrecision\n"
211                               "OpDecorate %36 BuiltIn SubgroupLocalInvocationId\n"
212                               "OpDecorate %37 RelaxedPrecision\n"
213                               "OpDecorate %107 Location 0\n"
214                               "OpMemberDecorate %112 0 BuiltIn Position\n"
215                               "OpMemberDecorate %112 1 BuiltIn PointSize\n"
216                               "OpMemberDecorate %112 2 BuiltIn ClipDistance\n"
217                               "OpMemberDecorate %112 3 BuiltIn CullDistance\n"
218                               "OpDecorate %112 Block\n"
219                               "OpDecorate %117 Location 0\n"
220                               "%2 = OpTypeVoid\n"
221                               "%3 = OpTypeFunction %2\n"
222                               "%6 = OpTypeInt 32 0\n"
223                               "%7 = OpTypePointer Function %6\n"
224                               "%9 = OpConstant %6 1\n"
225                               "%12 = OpConstant %6 0\n"
226                               "%13 = OpTypeVector %6 4\n"
227                               "%14 = OpTypePointer Function %13\n"
228                               "%16 = OpTypeBool\n"
229                               "%17 = OpConstantTrue %16\n"
230                               "%18 = OpConstant %6 3\n"
231                               "%21 = OpTypePointer Input %13\n"
232                               "%22 = OpVariable %21 Input\n"
233                               "%31 = OpTypePointer Input %6\n"
234                               "%32 = OpVariable %31 Input\n"
235                               "%36 = OpVariable %31 Input\n"
236                               "%46 = OpTypeInt 32 1\n"
237                               "%47 = OpConstant %46 1\n"
238                               "%56 = OpConstant %6 32\n"
239                               "%76 = OpConstant %6 2\n"
240                               "%105 = OpTypeFloat 32\n"
241                               "%106 = OpTypePointer Output %105\n"
242                               "%107 = OpVariable %106 Output\n"
243                               "%110 = OpTypeVector %105 4\n"
244                               "%111 = OpTypeArray %105 %9\n"
245                               "%112 = OpTypeStruct %110 %105 %111 %111\n"
246                               "%113 = OpTypePointer Output %112\n"
247                               "%114 = OpVariable %113 Output\n"
248                               "%115 = OpConstant %46 0\n"
249                               "%116 = OpTypePointer Input %110\n"
250                               "%117 = OpVariable %116 Input\n"
251                               "%119 = OpTypePointer Output %110\n"
252                               "%121 = OpConstant %105 1\n"
253                               "%4 = OpFunction %2 None %3\n"
254                               "%5 = OpLabel\n"
255                               "%8 = OpVariable %7 Function\n"
256                               "%10 = OpVariable %7 Function\n"
257                               "%11 = OpVariable %7 Function\n"
258                               "%15 = OpVariable %14 Function\n"
259                               "%20 = OpVariable %14 Function\n"
260                               "%24 = OpVariable %7 Function\n"
261                               "%49 = OpVariable %7 Function\n"
262                               "OpStore %8 %9\n"
263                               "OpStore %10 %9\n"
264                               "OpStore %11 %12\n"
265                               "%19 = OpGroupNonUniformBallot %13 %18 %17\n"
266                               "OpStore %15 %19\n"
267                               "%23 = OpLoad %13 %22\n"
268                               "OpStore %20 %23\n"
269                               "OpStore %24 %12\n"
270                               "OpBranch %25\n"
271                               "%25 = OpLabel\n"
272                               "OpLoopMerge %27 %28 None\n"
273                               "OpBranch %29\n"
274                               "%29 = OpLabel\n"
275                               "%30 = OpLoad %6 %24\n"
276                               "%33 = OpLoad %6 %32\n"
277                               "%34 = OpULessThan %16 %30 %33\n"
278                               "OpBranchConditional %34 %26 %27\n"
279                               "%26 = OpLabel\n"
280                               "%35 = OpLoad %6 %24\n"
281                               "%37 = OpLoad %6 %36\n" +
282                               comparison +
283                               "%39 = OpLoad %13 %20\n"
284                               "%40 = OpLoad %6 %24\n"
285                               "%41 = OpGroupNonUniformBallotBitExtract %16 %18 %39 %40\n"
286                               "%42 = OpLogicalNotEqual %16 %38 %41\n"
287                               "OpSelectionMerge %44 None\n"
288                               "OpBranchConditional %42 %43 %44\n"
289                               "%43 = OpLabel\n"
290                               "OpStore %8 %12\n"
291                               "OpBranch %44\n"
292                               "%44 = OpLabel\n"
293                               "OpBranch %28\n"
294                               "%28 = OpLabel\n"
295                               "%45 = OpLoad %6 %24\n"
296                               "%48 = OpIAdd %6 %45 %47\n"
297                               "OpStore %24 %48\n"
298                               "OpBranch %25\n"
299                               "%27 = OpLabel\n"
300                               "OpStore %49 %12\n"
301                               "OpBranch %50\n"
302                               "%50 = OpLabel\n"
303                               "OpLoopMerge %52 %53 None\n"
304                               "OpBranch %54\n"
305                               "%54 = OpLabel\n"
306                               "%55 = OpLoad %6 %49\n"
307                               "%57 = OpULessThan %16 %55 %56\n"
308                               "OpBranchConditional %57 %51 %52\n"
309                               "%51 = OpLabel\n"
310                               "%58 = OpAccessChain %7 %20 %12\n"
311                               "%59 = OpLoad %6 %58\n"
312                               "%60 = OpLoad %6 %10\n"
313                               "%61 = OpBitwiseAnd %6 %59 %60\n"
314                               "%62 = OpUGreaterThan %16 %61 %12\n"
315                               "OpSelectionMerge %64 None\n"
316                               "OpBranchConditional %62 %63 %64\n"
317                               "%63 = OpLabel\n"
318                               "%65 = OpLoad %6 %11\n"
319                               "%66 = OpIAdd %6 %65 %47\n"
320                               "OpStore %11 %66\n"
321                               "OpBranch %64\n"
322                               "%64 = OpLabel\n"
323                               "%67 = OpAccessChain %7 %20 %9\n"
324                               "%68 = OpLoad %6 %67\n"
325                               "%69 = OpLoad %6 %10\n"
326                               "%70 = OpBitwiseAnd %6 %68 %69\n"
327                               "%71 = OpUGreaterThan %16 %70 %12\n"
328                               "OpSelectionMerge %73 None\n"
329                               "OpBranchConditional %71 %72 %73\n"
330                               "%72 = OpLabel\n"
331                               "%74 = OpLoad %6 %11\n"
332                               "%75 = OpIAdd %6 %74 %47\n"
333                               "OpStore %11 %75\n"
334                               "OpBranch %73\n"
335                               "%73 = OpLabel\n"
336                               "%77 = OpAccessChain %7 %20 %76\n"
337                               "%78 = OpLoad %6 %77\n"
338                               "%79 = OpLoad %6 %10\n"
339                               "%80 = OpBitwiseAnd %6 %78 %79\n"
340                               "%81 = OpUGreaterThan %16 %80 %12\n"
341                               "OpSelectionMerge %83 None\n"
342                               "OpBranchConditional %81 %82 %83\n"
343                               "%82 = OpLabel\n"
344                               "%84 = OpLoad %6 %11\n"
345                               "%85 = OpIAdd %6 %84 %47\n"
346                               "OpStore %11 %85\n"
347                               "OpBranch %83\n"
348                               "%83 = OpLabel\n"
349                               "%86 = OpAccessChain %7 %20 %18\n"
350                               "%87 = OpLoad %6 %86\n"
351                               "%88 = OpLoad %6 %10\n"
352                               "%89 = OpBitwiseAnd %6 %87 %88\n"
353                               "%90 = OpUGreaterThan %16 %89 %12\n"
354                               "OpSelectionMerge %92 None\n"
355                               "OpBranchConditional %90 %91 %92\n"
356                               "%91 = OpLabel\n"
357                               "%93 = OpLoad %6 %11\n"
358                               "%94 = OpIAdd %6 %93 %47\n"
359                               "OpStore %11 %94\n"
360                               "OpBranch %92\n"
361                               "%92 = OpLabel\n"
362                               "%95 = OpLoad %6 %10\n"
363                               "%96 = OpShiftLeftLogical %6 %95 %47\n"
364                               "OpStore %10 %96\n"
365                               "OpBranch %53\n"
366                               "%53 = OpLabel\n"
367                               "%97 = OpLoad %6 %49\n"
368                               "%98 = OpIAdd %6 %97 %47\n"
369                               "OpStore %49 %98\n"
370                               "OpBranch %50\n"
371                               "%52 = OpLabel\n"
372                               "%99 = OpLoad %13 %20\n"
373                               "%100 = OpGroupNonUniformBallotBitCount %6 %18 Reduce %99\n"
374                               "%101 = OpLoad %6 %11\n"
375                               "%102 = OpINotEqual %16 %100 %101\n"
376                               "OpSelectionMerge %104 None\n"
377                               "OpBranchConditional %102 %103 %104\n"
378                               "%103 = OpLabel\n"
379                               "OpStore %8 %12\n"
380                               "OpBranch %104\n"
381                               "%104 = OpLabel\n"
382                               "%108 = OpLoad %6 %8\n"
383                               "%109 = OpConvertUToF %105 %108\n"
384                               "OpStore %107 %109\n"
385                               "%118 = OpLoad %110 %117\n"
386                               "%120 = OpAccessChain %119 %114 %115\n"
387                               "OpStore %120 %118\n"
388                               "%122 = OpAccessChain %106 %114 %47\n"
389                               "OpStore %122 %121\n"
390                               "OpReturn\n"
391                               "OpFunctionEnd\n";
392         programCollection.spirvAsmSources.add("vert") << vertex << buildOptionsSpr;
393     }
394     else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
395     {
396         /*
397             const string bdy = subgroupMask(caseDef);
398             const string  evaluationSource =
399             "#version 450\n"
400             "#extension GL_KHR_shader_subgroup_ballot: enable\n"
401             "#extension GL_EXT_tessellation_shader : require\n"
402             "layout(isolines, equal_spacing, ccw ) in;\n"
403             "layout(location = 0) out float out_color;\n"
404             "\n"
405             "void main (void)\n"
406             "{\n"
407             + bdy +
408             "  out_color = float(tempResult);\n"
409             "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
410             "}\n";
411             programCollection.glslSources.add("tese")
412                 << glu::TessellationEvaluationSource(evaluationSource) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
413         */
414         const string evaluationSource =
415             "; SPIR-V\n"
416             "; Version: 1.3\n"
417             "; Generator: Khronos Glslang Reference Front End; 2\n"
418             "; Bound: 136\n"
419             "; Schema: 0\n"
420             "OpCapability Tessellation\n"
421             "OpCapability GroupNonUniform\n"
422             "OpCapability GroupNonUniformBallot\n"
423             "%1 = OpExtInstImport \"GLSL.std.450\"\n"
424             "OpMemoryModel Logical GLSL450\n"
425             "OpEntryPoint TessellationEvaluation %4 \"main\" %22 %32 %36 %107 %114 %120 %128\n"
426             "OpExecutionMode %4 Isolines\n"
427             "OpExecutionMode %4 SpacingEqual\n"
428             "OpExecutionMode %4 VertexOrderCcw\n" +
429             mask +
430             "OpDecorate %32 RelaxedPrecision\n"
431             "OpDecorate %32 BuiltIn SubgroupSize\n"
432             "OpDecorate %33 RelaxedPrecision\n"
433             "OpDecorate %36 RelaxedPrecision\n"
434             "OpDecorate %36 BuiltIn SubgroupLocalInvocationId\n"
435             "OpDecorate %37 RelaxedPrecision\n"
436             "OpDecorate %107 Location 0\n"
437             "OpMemberDecorate %112 0 BuiltIn Position\n"
438             "OpMemberDecorate %112 1 BuiltIn PointSize\n"
439             "OpMemberDecorate %112 2 BuiltIn ClipDistance\n"
440             "OpMemberDecorate %112 3 BuiltIn CullDistance\n"
441             "OpDecorate %112 Block\n"
442             "OpMemberDecorate %116 0 BuiltIn Position\n"
443             "OpMemberDecorate %116 1 BuiltIn PointSize\n"
444             "OpMemberDecorate %116 2 BuiltIn ClipDistance\n"
445             "OpMemberDecorate %116 3 BuiltIn CullDistance\n"
446             "OpDecorate %116 Block\n"
447             "OpDecorate %128 BuiltIn TessCoord\n"
448             "%2 = OpTypeVoid\n"
449             "%3 = OpTypeFunction %2\n"
450             "%6 = OpTypeInt 32 0\n"
451             "%7 = OpTypePointer Function %6\n"
452             "%9 = OpConstant %6 1\n"
453             "%12 = OpConstant %6 0\n"
454             "%13 = OpTypeVector %6 4\n"
455             "%14 = OpTypePointer Function %13\n"
456             "%16 = OpTypeBool\n"
457             "%17 = OpConstantTrue %16\n"
458             "%18 = OpConstant %6 3\n"
459             "%21 = OpTypePointer Input %13\n"
460             "%22 = OpVariable %21 Input\n"
461             "%31 = OpTypePointer Input %6\n"
462             "%32 = OpVariable %31 Input\n"
463             "%36 = OpVariable %31 Input\n"
464             "%46 = OpTypeInt 32 1\n"
465             "%47 = OpConstant %46 1\n"
466             "%56 = OpConstant %6 32\n"
467             "%76 = OpConstant %6 2\n"
468             "%105 = OpTypeFloat 32\n"
469             "%106 = OpTypePointer Output %105\n"
470             "%107 = OpVariable %106 Output\n"
471             "%110 = OpTypeVector %105 4\n"
472             "%111 = OpTypeArray %105 %9\n"
473             "%112 = OpTypeStruct %110 %105 %111 %111\n"
474             "%113 = OpTypePointer Output %112\n"
475             "%114 = OpVariable %113 Output\n"
476             "%115 = OpConstant %46 0\n"
477             "%116 = OpTypeStruct %110 %105 %111 %111\n"
478             "%117 = OpConstant %6 32\n"
479             "%118 = OpTypeArray %116 %117\n"
480             "%119 = OpTypePointer Input %118\n"
481             "%120 = OpVariable %119 Input\n"
482             "%121 = OpTypePointer Input %110\n"
483             "%126 = OpTypeVector %105 3\n"
484             "%127 = OpTypePointer Input %126\n"
485             "%128 = OpVariable %127 Input\n"
486             "%129 = OpTypePointer Input %105\n"
487             "%134 = OpTypePointer Output %110\n"
488             "%4 = OpFunction %2 None %3\n"
489             "%5 = OpLabel\n"
490             "%8 = OpVariable %7 Function\n"
491             "%10 = OpVariable %7 Function\n"
492             "%11 = OpVariable %7 Function\n"
493             "%15 = OpVariable %14 Function\n"
494             "%20 = OpVariable %14 Function\n"
495             "%24 = OpVariable %7 Function\n"
496             "%49 = OpVariable %7 Function\n"
497             "OpStore %8 %9\n"
498             "OpStore %10 %9\n"
499             "OpStore %11 %12\n"
500             "%19 = OpGroupNonUniformBallot %13 %18 %17\n"
501             "OpStore %15 %19\n"
502             "%23 = OpLoad %13 %22\n"
503             "OpStore %20 %23\n"
504             "OpStore %24 %12\n"
505             "OpBranch %25\n"
506             "%25 = OpLabel\n"
507             "OpLoopMerge %27 %28 None\n"
508             "OpBranch %29\n"
509             "%29 = OpLabel\n"
510             "%30 = OpLoad %6 %24\n"
511             "%33 = OpLoad %6 %32\n"
512             "%34 = OpULessThan %16 %30 %33\n"
513             "OpBranchConditional %34 %26 %27\n"
514             "%26 = OpLabel\n"
515             "%35 = OpLoad %6 %24\n"
516             "%37 = OpLoad %6 %36\n" +
517             comparison +
518             "%39 = OpLoad %13 %20\n"
519             "%40 = OpLoad %6 %24\n"
520             "%41 = OpGroupNonUniformBallotBitExtract %16 %18 %39 %40\n"
521             "%42 = OpLogicalNotEqual %16 %38 %41\n"
522             "OpSelectionMerge %44 None\n"
523             "OpBranchConditional %42 %43 %44\n"
524             "%43 = OpLabel\n"
525             "OpStore %8 %12\n"
526             "OpBranch %44\n"
527             "%44 = OpLabel\n"
528             "OpBranch %28\n"
529             "%28 = OpLabel\n"
530             "%45 = OpLoad %6 %24\n"
531             "%48 = OpIAdd %6 %45 %47\n"
532             "OpStore %24 %48\n"
533             "OpBranch %25\n"
534             "%27 = OpLabel\n"
535             "OpStore %49 %12\n"
536             "OpBranch %50\n"
537             "%50 = OpLabel\n"
538             "OpLoopMerge %52 %53 None\n"
539             "OpBranch %54\n"
540             "%54 = OpLabel\n"
541             "%55 = OpLoad %6 %49\n"
542             "%57 = OpULessThan %16 %55 %56\n"
543             "OpBranchConditional %57 %51 %52\n"
544             "%51 = OpLabel\n"
545             "%58 = OpAccessChain %7 %20 %12\n"
546             "%59 = OpLoad %6 %58\n"
547             "%60 = OpLoad %6 %10\n"
548             "%61 = OpBitwiseAnd %6 %59 %60\n"
549             "%62 = OpUGreaterThan %16 %61 %12\n"
550             "OpSelectionMerge %64 None\n"
551             "OpBranchConditional %62 %63 %64\n"
552             "%63 = OpLabel\n"
553             "%65 = OpLoad %6 %11\n"
554             "%66 = OpIAdd %6 %65 %47\n"
555             "OpStore %11 %66\n"
556             "OpBranch %64\n"
557             "%64 = OpLabel\n"
558             "%67 = OpAccessChain %7 %20 %9\n"
559             "%68 = OpLoad %6 %67\n"
560             "%69 = OpLoad %6 %10\n"
561             "%70 = OpBitwiseAnd %6 %68 %69\n"
562             "%71 = OpUGreaterThan %16 %70 %12\n"
563             "OpSelectionMerge %73 None\n"
564             "OpBranchConditional %71 %72 %73\n"
565             "%72 = OpLabel\n"
566             "%74 = OpLoad %6 %11\n"
567             "%75 = OpIAdd %6 %74 %47\n"
568             "OpStore %11 %75\n"
569             "OpBranch %73\n"
570             "%73 = OpLabel\n"
571             "%77 = OpAccessChain %7 %20 %76\n"
572             "%78 = OpLoad %6 %77\n"
573             "%79 = OpLoad %6 %10\n"
574             "%80 = OpBitwiseAnd %6 %78 %79\n"
575             "%81 = OpUGreaterThan %16 %80 %12\n"
576             "OpSelectionMerge %83 None\n"
577             "OpBranchConditional %81 %82 %83\n"
578             "%82 = OpLabel\n"
579             "%84 = OpLoad %6 %11\n"
580             "%85 = OpIAdd %6 %84 %47\n"
581             "OpStore %11 %85\n"
582             "OpBranch %83\n"
583             "%83 = OpLabel\n"
584             "%86 = OpAccessChain %7 %20 %18\n"
585             "%87 = OpLoad %6 %86\n"
586             "%88 = OpLoad %6 %10\n"
587             "%89 = OpBitwiseAnd %6 %87 %88\n"
588             "%90 = OpUGreaterThan %16 %89 %12\n"
589             "OpSelectionMerge %92 None\n"
590             "OpBranchConditional %90 %91 %92\n"
591             "%91 = OpLabel\n"
592             "%93 = OpLoad %6 %11\n"
593             "%94 = OpIAdd %6 %93 %47\n"
594             "OpStore %11 %94\n"
595             "OpBranch %92\n"
596             "%92 = OpLabel\n"
597             "%95 = OpLoad %6 %10\n"
598             "%96 = OpShiftLeftLogical %6 %95 %47\n"
599             "OpStore %10 %96\n"
600             "OpBranch %53\n"
601             "%53 = OpLabel\n"
602             "%97 = OpLoad %6 %49\n"
603             "%98 = OpIAdd %6 %97 %47\n"
604             "OpStore %49 %98\n"
605             "OpBranch %50\n"
606             "%52 = OpLabel\n"
607             "%99 = OpLoad %13 %20\n"
608             "%100 = OpGroupNonUniformBallotBitCount %6 %18 Reduce %99\n"
609             "%101 = OpLoad %6 %11\n"
610             "%102 = OpINotEqual %16 %100 %101\n"
611             "OpSelectionMerge %104 None\n"
612             "OpBranchConditional %102 %103 %104\n"
613             "%103 = OpLabel\n"
614             "OpStore %8 %12\n"
615             "OpBranch %104\n"
616             "%104 = OpLabel\n"
617             "%108 = OpLoad %6 %8\n"
618             "%109 = OpConvertUToF %105 %108\n"
619             "OpStore %107 %109\n"
620             "%122 = OpAccessChain %121 %120 %115 %115\n"
621             "%123 = OpLoad %110 %122\n"
622             "%124 = OpAccessChain %121 %120 %47 %115\n"
623             "%125 = OpLoad %110 %124\n"
624             "%130 = OpAccessChain %129 %128 %12\n"
625             "%131 = OpLoad %105 %130\n"
626             "%132 = OpCompositeConstruct %110 %131 %131 %131 %131\n"
627             "%133 = OpExtInst %110 %1 FMix %123 %125 %132\n"
628             "%135 = OpAccessChain %134 %114 %115\n"
629             "OpStore %135 %133\n"
630             "OpReturn\n"
631             "OpFunctionEnd\n";
632         programCollection.spirvAsmSources.add("tese") << evaluationSource << buildOptionsSpr;
633         subgroups::setTesCtrlShaderFrameBuffer(programCollection);
634     }
635     else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
636     {
637         /*
638             const string bdy = subgroupMask(caseDef);
639             const string  controlSource =
640             "#version 450\n"
641             "#extension GL_EXT_tessellation_shader : require\n"
642             "#extension GL_KHR_shader_subgroup_ballot: enable\n"
643             "layout(vertices = 2) out;\n"
644             "layout(location = 0) out float out_color[];\n"
645             "void main (void)\n"
646             "{\n"
647             "  if (gl_InvocationID == 0)\n"
648             "  {\n"
649             "    gl_TessLevelOuter[0] = 1.0f;\n"
650             "    gl_TessLevelOuter[1] = 1.0f;\n"
651             "  }\n"
652             + bdy +
653             "  out_color[gl_InvocationID] = float(tempResult);\n"
654             "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
655             "}\n";
656             programCollection.glslSources.add("tesc")
657             << glu::TessellationControlSource(controlSource) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
658         */
659         const string controlSource = "; SPIR-V\n"
660                                      "; Version: 1.3\n"
661                                      "; Generator: Khronos Glslang Reference Front End; 2\n"
662                                      "; Bound: 146\n"
663                                      "; Schema: 0\n"
664                                      "OpCapability Tessellation\n"
665                                      "OpCapability GroupNonUniform\n"
666                                      "OpCapability GroupNonUniformBallot\n"
667                                      "%1 = OpExtInstImport \"GLSL.std.450\"\n"
668                                      "OpMemoryModel Logical GLSL450\n"
669                                      "OpEntryPoint TessellationControl %4 \"main\" %8 %20 %40 %50 %54 %123 %133 %139\n"
670                                      "OpExecutionMode %4 OutputVertices 2\n"
671                                      "OpDecorate %8 BuiltIn InvocationId\n"
672                                      "OpDecorate %20 Patch\n"
673                                      "OpDecorate %20 BuiltIn TessLevelOuter\n" +
674                                      mask +
675                                      "OpDecorate %50 RelaxedPrecision\n"
676                                      "OpDecorate %50 BuiltIn SubgroupSize\n"
677                                      "OpDecorate %51 RelaxedPrecision\n"
678                                      "OpDecorate %54 RelaxedPrecision\n"
679                                      "OpDecorate %54 BuiltIn SubgroupLocalInvocationId\n"
680                                      "OpDecorate %55 RelaxedPrecision\n"
681                                      "OpDecorate %123 Location 0\n"
682                                      "OpMemberDecorate %130 0 BuiltIn Position\n"
683                                      "OpMemberDecorate %130 1 BuiltIn PointSize\n"
684                                      "OpMemberDecorate %130 2 BuiltIn ClipDistance\n"
685                                      "OpMemberDecorate %130 3 BuiltIn CullDistance\n"
686                                      "OpDecorate %130 Block\n"
687                                      "OpMemberDecorate %135 0 BuiltIn Position\n"
688                                      "OpMemberDecorate %135 1 BuiltIn PointSize\n"
689                                      "OpMemberDecorate %135 2 BuiltIn ClipDistance\n"
690                                      "OpMemberDecorate %135 3 BuiltIn CullDistance\n"
691                                      "OpDecorate %135 Block\n"
692                                      "%2 = OpTypeVoid\n"
693                                      "%3 = OpTypeFunction %2\n"
694                                      "%6 = OpTypeInt 32 1\n"
695                                      "%7 = OpTypePointer Input %6\n"
696                                      "%8 = OpVariable %7 Input\n"
697                                      "%10 = OpConstant %6 0\n"
698                                      "%11 = OpTypeBool\n"
699                                      "%15 = OpTypeFloat 32\n"
700                                      "%16 = OpTypeInt 32 0\n"
701                                      "%17 = OpConstant %16 4\n"
702                                      "%18 = OpTypeArray %15 %17\n"
703                                      "%19 = OpTypePointer Output %18\n"
704                                      "%20 = OpVariable %19 Output\n"
705                                      "%21 = OpConstant %15 1\n"
706                                      "%22 = OpTypePointer Output %15\n"
707                                      "%24 = OpConstant %6 1\n"
708                                      "%26 = OpTypePointer Function %16\n"
709                                      "%28 = OpConstant %16 1\n"
710                                      "%31 = OpConstant %16 0\n"
711                                      "%32 = OpTypeVector %16 4\n"
712                                      "%33 = OpTypePointer Function %32\n"
713                                      "%35 = OpConstantTrue %11\n"
714                                      "%36 = OpConstant %16 3\n"
715                                      "%39 = OpTypePointer Input %32\n"
716                                      "%40 = OpVariable %39 Input\n"
717                                      "%49 = OpTypePointer Input %16\n"
718                                      "%50 = OpVariable %49 Input\n"
719                                      "%54 = OpVariable %49 Input\n"
720                                      "%72 = OpConstant %16 32\n"
721                                      "%92 = OpConstant %16 2\n"
722                                      "%121 = OpTypeArray %15 %92\n"
723                                      "%122 = OpTypePointer Output %121\n"
724                                      "%123 = OpVariable %122 Output\n"
725                                      "%128 = OpTypeVector %15 4\n"
726                                      "%129 = OpTypeArray %15 %28\n"
727                                      "%130 = OpTypeStruct %128 %15 %129 %129\n"
728                                      "%131 = OpTypeArray %130 %92\n"
729                                      "%132 = OpTypePointer Output %131\n"
730                                      "%133 = OpVariable %132 Output\n"
731                                      "%135 = OpTypeStruct %128 %15 %129 %129\n"
732                                      "%136 = OpConstant %16 32\n"
733                                      "%137 = OpTypeArray %135 %136\n"
734                                      "%138 = OpTypePointer Input %137\n"
735                                      "%139 = OpVariable %138 Input\n"
736                                      "%141 = OpTypePointer Input %128\n"
737                                      "%144 = OpTypePointer Output %128\n"
738                                      "%4 = OpFunction %2 None %3\n"
739                                      "%5 = OpLabel\n"
740                                      "%27 = OpVariable %26 Function\n"
741                                      "%29 = OpVariable %26 Function\n"
742                                      "%30 = OpVariable %26 Function\n"
743                                      "%34 = OpVariable %33 Function\n"
744                                      "%38 = OpVariable %33 Function\n"
745                                      "%42 = OpVariable %26 Function\n"
746                                      "%65 = OpVariable %26 Function\n"
747                                      "%9 = OpLoad %6 %8\n"
748                                      "%12 = OpIEqual %11 %9 %10\n"
749                                      "OpSelectionMerge %14 None\n"
750                                      "OpBranchConditional %12 %13 %14\n"
751                                      "%13 = OpLabel\n"
752                                      "%23 = OpAccessChain %22 %20 %10\n"
753                                      "OpStore %23 %21\n"
754                                      "%25 = OpAccessChain %22 %20 %24\n"
755                                      "OpStore %25 %21\n"
756                                      "OpBranch %14\n"
757                                      "%14 = OpLabel\n"
758                                      "OpStore %27 %28\n"
759                                      "OpStore %29 %28\n"
760                                      "OpStore %30 %31\n"
761                                      "%37 = OpGroupNonUniformBallot %32 %36 %35\n"
762                                      "OpStore %34 %37\n"
763                                      "%41 = OpLoad %32 %40\n"
764                                      "OpStore %38 %41\n"
765                                      "OpStore %42 %31\n"
766                                      "OpBranch %43\n"
767                                      "%43 = OpLabel\n"
768                                      "OpLoopMerge %45 %46 None\n"
769                                      "OpBranch %47\n"
770                                      "%47 = OpLabel\n"
771                                      "%48 = OpLoad %16 %42\n"
772                                      "%51 = OpLoad %16 %50\n"
773                                      "%52 = OpULessThan %11 %48 %51\n"
774                                      "OpBranchConditional %52 %44 %45\n"
775                                      "%44 = OpLabel\n"
776                                      "%53 = OpLoad %16 %42\n"
777                                      "%55 = OpLoad %16 %54\n" +
778                                      comparison +
779                                      "%57 = OpLoad %32 %38\n"
780                                      "%58 = OpLoad %16 %42\n"
781                                      "%59 = OpGroupNonUniformBallotBitExtract %11 %36 %57 %58\n"
782                                      "%60 = OpLogicalNotEqual %11 %56 %59\n"
783                                      "OpSelectionMerge %62 None\n"
784                                      "OpBranchConditional %60 %61 %62\n"
785                                      "%61 = OpLabel\n"
786                                      "OpStore %27 %31\n"
787                                      "OpBranch %62\n"
788                                      "%62 = OpLabel\n"
789                                      "OpBranch %46\n"
790                                      "%46 = OpLabel\n"
791                                      "%63 = OpLoad %16 %42\n"
792                                      "%64 = OpIAdd %16 %63 %24\n"
793                                      "OpStore %42 %64\n"
794                                      "OpBranch %43\n"
795                                      "%45 = OpLabel\n"
796                                      "OpStore %65 %31\n"
797                                      "OpBranch %66\n"
798                                      "%66 = OpLabel\n"
799                                      "OpLoopMerge %68 %69 None\n"
800                                      "OpBranch %70\n"
801                                      "%70 = OpLabel\n"
802                                      "%71 = OpLoad %16 %65\n"
803                                      "%73 = OpULessThan %11 %71 %72\n"
804                                      "OpBranchConditional %73 %67 %68\n"
805                                      "%67 = OpLabel\n"
806                                      "%74 = OpAccessChain %26 %38 %31\n"
807                                      "%75 = OpLoad %16 %74\n"
808                                      "%76 = OpLoad %16 %29\n"
809                                      "%77 = OpBitwiseAnd %16 %75 %76\n"
810                                      "%78 = OpUGreaterThan %11 %77 %31\n"
811                                      "OpSelectionMerge %80 None\n"
812                                      "OpBranchConditional %78 %79 %80\n"
813                                      "%79 = OpLabel\n"
814                                      "%81 = OpLoad %16 %30\n"
815                                      "%82 = OpIAdd %16 %81 %24\n"
816                                      "OpStore %30 %82\n"
817                                      "OpBranch %80\n"
818                                      "%80 = OpLabel\n"
819                                      "%83 = OpAccessChain %26 %38 %28\n"
820                                      "%84 = OpLoad %16 %83\n"
821                                      "%85 = OpLoad %16 %29\n"
822                                      "%86 = OpBitwiseAnd %16 %84 %85\n"
823                                      "%87 = OpUGreaterThan %11 %86 %31\n"
824                                      "OpSelectionMerge %89 None\n"
825                                      "OpBranchConditional %87 %88 %89\n"
826                                      "%88 = OpLabel\n"
827                                      "%90 = OpLoad %16 %30\n"
828                                      "%91 = OpIAdd %16 %90 %24\n"
829                                      "OpStore %30 %91\n"
830                                      "OpBranch %89\n"
831                                      "%89 = OpLabel\n"
832                                      "%93 = OpAccessChain %26 %38 %92\n"
833                                      "%94 = OpLoad %16 %93\n"
834                                      "%95 = OpLoad %16 %29\n"
835                                      "%96 = OpBitwiseAnd %16 %94 %95\n"
836                                      "%97 = OpUGreaterThan %11 %96 %31\n"
837                                      "OpSelectionMerge %99 None\n"
838                                      "OpBranchConditional %97 %98 %99\n"
839                                      "%98 = OpLabel\n"
840                                      "%100 = OpLoad %16 %30\n"
841                                      "%101 = OpIAdd %16 %100 %24\n"
842                                      "OpStore %30 %101\n"
843                                      "OpBranch %99\n"
844                                      "%99 = OpLabel\n"
845                                      "%102 = OpAccessChain %26 %38 %36\n"
846                                      "%103 = OpLoad %16 %102\n"
847                                      "%104 = OpLoad %16 %29\n"
848                                      "%105 = OpBitwiseAnd %16 %103 %104\n"
849                                      "%106 = OpUGreaterThan %11 %105 %31\n"
850                                      "OpSelectionMerge %108 None\n"
851                                      "OpBranchConditional %106 %107 %108\n"
852                                      "%107 = OpLabel\n"
853                                      "%109 = OpLoad %16 %30\n"
854                                      "%110 = OpIAdd %16 %109 %24\n"
855                                      "OpStore %30 %110\n"
856                                      "OpBranch %108\n"
857                                      "%108 = OpLabel\n"
858                                      "%111 = OpLoad %16 %29\n"
859                                      "%112 = OpShiftLeftLogical %16 %111 %24\n"
860                                      "OpStore %29 %112\n"
861                                      "OpBranch %69\n"
862                                      "%69 = OpLabel\n"
863                                      "%113 = OpLoad %16 %65\n"
864                                      "%114 = OpIAdd %16 %113 %24\n"
865                                      "OpStore %65 %114\n"
866                                      "OpBranch %66\n"
867                                      "%68 = OpLabel\n"
868                                      "%115 = OpLoad %32 %38\n"
869                                      "%116 = OpGroupNonUniformBallotBitCount %16 %36 Reduce %115\n"
870                                      "%117 = OpLoad %16 %30\n"
871                                      "%118 = OpINotEqual %11 %116 %117\n"
872                                      "OpSelectionMerge %120 None\n"
873                                      "OpBranchConditional %118 %119 %120\n"
874                                      "%119 = OpLabel\n"
875                                      "OpStore %27 %31\n"
876                                      "OpBranch %120\n"
877                                      "%120 = OpLabel\n"
878                                      "%124 = OpLoad %6 %8\n"
879                                      "%125 = OpLoad %16 %27\n"
880                                      "%126 = OpConvertUToF %15 %125\n"
881                                      "%127 = OpAccessChain %22 %123 %124\n"
882                                      "OpStore %127 %126\n"
883                                      "%134 = OpLoad %6 %8\n"
884                                      "%140 = OpLoad %6 %8\n"
885                                      "%142 = OpAccessChain %141 %139 %140 %10\n"
886                                      "%143 = OpLoad %128 %142\n"
887                                      "%145 = OpAccessChain %144 %133 %134 %10\n"
888                                      "OpStore %145 %143\n"
889                                      "OpReturn\n"
890                                      "OpFunctionEnd\n";
891         programCollection.spirvAsmSources.add("tesc") << controlSource << buildOptionsSpr;
892         subgroups::setTesEvalShaderFrameBuffer(programCollection);
893     }
894     else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
895     {
896         /*
897         const string bdy = subgroupMask(caseDef);
898         const string geometry =
899         "#version 450\n"
900         "#extension GL_KHR_shader_subgroup_ballot: enable\n"
901         "layout(points) in;\n"
902         "layout(points, max_vertices = 1) out;\n"
903         "layout(location = 0) out float out_color;\n"
904         "\n"
905         "void main (void)\n"
906         "{\n"
907         + bdy +
908         "  out_color = float(tempResult);\n"
909         "  gl_Position = gl_in[0].gl_Position;\n"
910         "  gl_PointSize = gl_in[0].gl_PointSize;\n"
911         "  EmitVertex();\n"
912         "  EndPrimitive();\n"
913         "}\n";
914         programCollection.glslSources.add("geometry")
915             << glu::GeometrySource(geometry) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
916         */
917 
918         ostringstream geometry;
919         geometry << "; SPIR-V\n"
920                  << "; Version: 1.3\n"
921                  << "; Generator: Khronos Glslang Reference Front End; 2\n"
922                  << "; Bound: 125\n"
923                  << "; Schema: 0\n"
924                  << "OpCapability Geometry\n"
925                  << (*caseDef.geometryPointSizeSupported ? "OpCapability GeometryPointSize\n" : "")
926                  << "OpCapability GroupNonUniform\n"
927                  << "OpCapability GroupNonUniformBallot\n"
928                  << "%1 = OpExtInstImport \"GLSL.std.450\"\n"
929                  << "OpMemoryModel Logical GLSL450\n"
930                  << "OpEntryPoint Geometry %4 \"main\" %22 %32 %36 %107 %114 %119\n"
931                  << "OpExecutionMode %4 InputPoints\n"
932                  << "OpExecutionMode %4 Invocations 1\n"
933                  << "OpExecutionMode %4 OutputPoints\n"
934                  << "OpExecutionMode %4 OutputVertices 1\n"
935                  << mask << "OpDecorate %32 RelaxedPrecision\n"
936                  << "OpDecorate %32 BuiltIn SubgroupSize\n"
937                  << "OpDecorate %33 RelaxedPrecision\n"
938                  << "OpDecorate %36 RelaxedPrecision\n"
939                  << "OpDecorate %36 BuiltIn SubgroupLocalInvocationId\n"
940                  << "OpDecorate %37 RelaxedPrecision\n"
941                  << "OpDecorate %107 Location 0\n"
942                  << "OpMemberDecorate %112 0 BuiltIn Position\n"
943                  << "OpMemberDecorate %112 1 BuiltIn PointSize\n"
944                  << "OpMemberDecorate %112 2 BuiltIn ClipDistance\n"
945                  << "OpMemberDecorate %112 3 BuiltIn CullDistance\n"
946                  << "OpDecorate %112 Block\n"
947                  << "OpMemberDecorate %116 0 BuiltIn Position\n"
948                  << "OpMemberDecorate %116 1 BuiltIn PointSize\n"
949                  << "OpMemberDecorate %116 2 BuiltIn ClipDistance\n"
950                  << "OpMemberDecorate %116 3 BuiltIn CullDistance\n"
951                  << "OpDecorate %116 Block\n"
952                  << "%2 = OpTypeVoid\n"
953                  << "%3 = OpTypeFunction %2\n"
954                  << "%6 = OpTypeInt 32 0\n"
955                  << "%7 = OpTypePointer Function %6\n"
956                  << "%9 = OpConstant %6 1\n"
957                  << "%12 = OpConstant %6 0\n"
958                  << "%13 = OpTypeVector %6 4\n"
959                  << "%14 = OpTypePointer Function %13\n"
960                  << "%16 = OpTypeBool\n"
961                  << "%17 = OpConstantTrue %16\n"
962                  << "%18 = OpConstant %6 3\n"
963                  << "%21 = OpTypePointer Input %13\n"
964                  << "%22 = OpVariable %21 Input\n"
965                  << "%31 = OpTypePointer Input %6\n"
966                  << "%32 = OpVariable %31 Input\n"
967                  << "%36 = OpVariable %31 Input\n"
968                  << "%46 = OpTypeInt 32 1\n"
969                  << "%47 = OpConstant %46 1\n"
970                  << "%56 = OpConstant %6 32\n"
971                  << "%76 = OpConstant %6 2\n"
972                  << "%105 = OpTypeFloat 32\n"
973                  << "%106 = OpTypePointer Output %105\n"
974                  << "%107 = OpVariable %106 Output\n"
975                  << "%110 = OpTypeVector %105 4\n"
976                  << "%111 = OpTypeArray %105 %9\n"
977                  << "%112 = OpTypeStruct %110 %105 %111 %111\n"
978                  << "%113 = OpTypePointer Output %112\n"
979                  << "%114 = OpVariable %113 Output\n"
980                  << "%115 = OpConstant %46 0\n"
981                  << "%116 = OpTypeStruct %110 %105 %111 %111\n"
982                  << "%117 = OpTypeArray %116 %9\n"
983                  << "%118 = OpTypePointer Input %117\n"
984                  << "%119 = OpVariable %118 Input\n"
985                  << "%120 = OpTypePointer Input %110\n"
986                  << "%123 = OpTypePointer Output %110\n"
987                  << (*caseDef.geometryPointSizeSupported ? "%125 = OpTypePointer Input %105\n"
988                                                            "%126 = OpTypePointer Output %105\n" :
989                                                            "")
990                  << "%4 = OpFunction %2 None %3\n"
991                  << "%5 = OpLabel\n"
992                  << "%8 = OpVariable %7 Function\n"
993                  << "%10 = OpVariable %7 Function\n"
994                  << "%11 = OpVariable %7 Function\n"
995                  << "%15 = OpVariable %14 Function\n"
996                  << "%20 = OpVariable %14 Function\n"
997                  << "%24 = OpVariable %7 Function\n"
998                  << "%49 = OpVariable %7 Function\n"
999                  << "OpStore %8 %9\n"
1000                  << "OpStore %10 %9\n"
1001                  << "OpStore %11 %12\n"
1002                  << "%19 = OpGroupNonUniformBallot %13 %18 %17\n"
1003                  << "OpStore %15 %19\n"
1004                  << "%23 = OpLoad %13 %22\n"
1005                  << "OpStore %20 %23\n"
1006                  << "OpStore %24 %12\n"
1007                  << "OpBranch %25\n"
1008                  << "%25 = OpLabel\n"
1009                  << "OpLoopMerge %27 %28 None\n"
1010                  << "OpBranch %29\n"
1011                  << "%29 = OpLabel\n"
1012                  << "%30 = OpLoad %6 %24\n"
1013                  << "%33 = OpLoad %6 %32\n"
1014                  << "%34 = OpULessThan %16 %30 %33\n"
1015                  << "OpBranchConditional %34 %26 %27\n"
1016                  << "%26 = OpLabel\n"
1017                  << "%35 = OpLoad %6 %24\n"
1018                  << "%37 = OpLoad %6 %36\n"
1019                  << comparison << "%39 = OpLoad %13 %20\n"
1020                  << "%40 = OpLoad %6 %24\n"
1021                  << "%41 = OpGroupNonUniformBallotBitExtract %16 %18 %39 %40\n"
1022                  << "%42 = OpLogicalNotEqual %16 %38 %41\n"
1023                  << "OpSelectionMerge %44 None\n"
1024                  << "OpBranchConditional %42 %43 %44\n"
1025                  << "%43 = OpLabel\n"
1026                  << "OpStore %8 %12\n"
1027                  << "OpBranch %44\n"
1028                  << "%44 = OpLabel\n"
1029                  << "OpBranch %28\n"
1030                  << "%28 = OpLabel\n"
1031                  << "%45 = OpLoad %6 %24\n"
1032                  << "%48 = OpIAdd %6 %45 %47\n"
1033                  << "OpStore %24 %48\n"
1034                  << "OpBranch %25\n"
1035                  << "%27 = OpLabel\n"
1036                  << "OpStore %49 %12\n"
1037                  << "OpBranch %50\n"
1038                  << "%50 = OpLabel\n"
1039                  << "OpLoopMerge %52 %53 None\n"
1040                  << "OpBranch %54\n"
1041                  << "%54 = OpLabel\n"
1042                  << "%55 = OpLoad %6 %49\n"
1043                  << "%57 = OpULessThan %16 %55 %56\n"
1044                  << "OpBranchConditional %57 %51 %52\n"
1045                  << "%51 = OpLabel\n"
1046                  << "%58 = OpAccessChain %7 %20 %12\n"
1047                  << "%59 = OpLoad %6 %58\n"
1048                  << "%60 = OpLoad %6 %10\n"
1049                  << "%61 = OpBitwiseAnd %6 %59 %60\n"
1050                  << "%62 = OpUGreaterThan %16 %61 %12\n"
1051                  << "OpSelectionMerge %64 None\n"
1052                  << "OpBranchConditional %62 %63 %64\n"
1053                  << "%63 = OpLabel\n"
1054                  << "%65 = OpLoad %6 %11\n"
1055                  << "%66 = OpIAdd %6 %65 %47\n"
1056                  << "OpStore %11 %66\n"
1057                  << "OpBranch %64\n"
1058                  << "%64 = OpLabel\n"
1059                  << "%67 = OpAccessChain %7 %20 %9\n"
1060                  << "%68 = OpLoad %6 %67\n"
1061                  << "%69 = OpLoad %6 %10\n"
1062                  << "%70 = OpBitwiseAnd %6 %68 %69\n"
1063                  << "%71 = OpUGreaterThan %16 %70 %12\n"
1064                  << "OpSelectionMerge %73 None\n"
1065                  << "OpBranchConditional %71 %72 %73\n"
1066                  << "%72 = OpLabel\n"
1067                  << "%74 = OpLoad %6 %11\n"
1068                  << "%75 = OpIAdd %6 %74 %47\n"
1069                  << "OpStore %11 %75\n"
1070                  << "OpBranch %73\n"
1071                  << "%73 = OpLabel\n"
1072                  << "%77 = OpAccessChain %7 %20 %76\n"
1073                  << "%78 = OpLoad %6 %77\n"
1074                  << "%79 = OpLoad %6 %10\n"
1075                  << "%80 = OpBitwiseAnd %6 %78 %79\n"
1076                  << "%81 = OpUGreaterThan %16 %80 %12\n"
1077                  << "OpSelectionMerge %83 None\n"
1078                  << "OpBranchConditional %81 %82 %83\n"
1079                  << "%82 = OpLabel\n"
1080                  << "%84 = OpLoad %6 %11\n"
1081                  << "%85 = OpIAdd %6 %84 %47\n"
1082                  << "OpStore %11 %85\n"
1083                  << "OpBranch %83\n"
1084                  << "%83 = OpLabel\n"
1085                  << "%86 = OpAccessChain %7 %20 %18\n"
1086                  << "%87 = OpLoad %6 %86\n"
1087                  << "%88 = OpLoad %6 %10\n"
1088                  << "%89 = OpBitwiseAnd %6 %87 %88\n"
1089                  << "%90 = OpUGreaterThan %16 %89 %12\n"
1090                  << "OpSelectionMerge %92 None\n"
1091                  << "OpBranchConditional %90 %91 %92\n"
1092                  << "%91 = OpLabel\n"
1093                  << "%93 = OpLoad %6 %11\n"
1094                  << "%94 = OpIAdd %6 %93 %47\n"
1095                  << "OpStore %11 %94\n"
1096                  << "OpBranch %92\n"
1097                  << "%92 = OpLabel\n"
1098                  << "%95 = OpLoad %6 %10\n"
1099                  << "%96 = OpShiftLeftLogical %6 %95 %47\n"
1100                  << "OpStore %10 %96\n"
1101                  << "OpBranch %53\n"
1102                  << "%53 = OpLabel\n"
1103                  << "%97 = OpLoad %6 %49\n"
1104                  << "%98 = OpIAdd %6 %97 %47\n"
1105                  << "OpStore %49 %98\n"
1106                  << "OpBranch %50\n"
1107                  << "%52 = OpLabel\n"
1108                  << "%99 = OpLoad %13 %20\n"
1109                  << "%100 = OpGroupNonUniformBallotBitCount %6 %18 Reduce %99\n"
1110                  << "%101 = OpLoad %6 %11\n"
1111                  << "%102 = OpINotEqual %16 %100 %101\n"
1112                  << "OpSelectionMerge %104 None\n"
1113                  << "OpBranchConditional %102 %103 %104\n"
1114                  << "%103 = OpLabel\n"
1115                  << "OpStore %8 %12\n"
1116                  << "OpBranch %104\n"
1117                  << "%104 = OpLabel\n"
1118                  << "%108 = OpLoad %6 %8\n"
1119                  << "%109 = OpConvertUToF %105 %108\n"
1120                  << "OpStore %107 %109\n"
1121                  << "%121 = OpAccessChain %120 %119 %115 %115\n"
1122                  << "%122 = OpLoad %110 %121\n"
1123                  << "%124 = OpAccessChain %123 %114 %115\n"
1124                  << "OpStore %124 %122\n"
1125                  << (*caseDef.geometryPointSizeSupported ? "%127 = OpAccessChain %125 %119 %115 %47\n"
1126                                                            "%128 = OpLoad %105 %127\n"
1127                                                            "%129 = OpAccessChain %126 %114 %47\n"
1128                                                            "OpStore %129 %128\n" :
1129                                                            "")
1130                  << "OpEmitVertex\n"
1131                  << "OpEndPrimitive\n"
1132                  << "OpReturn\n"
1133                  << "OpFunctionEnd\n";
1134 
1135         programCollection.spirvAsmSources.add("geometry") << geometry.str() << buildOptionsSpr;
1136     }
1137     else
1138     {
1139         DE_FATAL("Unsupported shader stage");
1140     }
1141 }
1142 
getExtHeader(const CaseDefinition &)1143 string getExtHeader(const CaseDefinition &)
1144 {
1145     return "#extension GL_KHR_shader_subgroup_ballot: enable\n";
1146 }
1147 
getPerStageHeadDeclarations(const CaseDefinition & caseDef)1148 vector<string> getPerStageHeadDeclarations(const CaseDefinition &caseDef)
1149 {
1150     const uint32_t stageCount = subgroups::getStagesCount(caseDef.shaderStage);
1151     const bool fragment       = (caseDef.shaderStage & VK_SHADER_STAGE_FRAGMENT_BIT) != 0;
1152     vector<string> result(stageCount, string());
1153 
1154     if (fragment)
1155         result.reserve(result.size() + 1);
1156 
1157     for (size_t i = 0; i < result.size(); ++i)
1158     {
1159         result[i] = "layout(set = 0, binding = " + de::toString(i) +
1160                     ", std430) buffer Output\n"
1161                     "{\n"
1162                     "  uint result[];\n"
1163                     "};\n";
1164     }
1165 
1166     if (fragment)
1167     {
1168         const string fragPart = "layout(location = 0) out uint result;\n";
1169 
1170         result.push_back(fragPart);
1171     }
1172 
1173     return result;
1174 }
1175 
initPrograms(SourceCollections & programCollection,CaseDefinition caseDef)1176 void initPrograms(SourceCollections &programCollection, CaseDefinition caseDef)
1177 {
1178 #ifndef CTS_USES_VULKANSC
1179     const bool spirv14required =
1180         (isAllRayTracingStages(caseDef.shaderStage) || isAllMeshShadingStages(caseDef.shaderStage));
1181 #else
1182     const bool spirv14required = false;
1183 #endif // CTS_USES_VULKANSC
1184     const SpirvVersion spirvVersion = (spirv14required ? SPIRV_VERSION_1_4 : SPIRV_VERSION_1_3);
1185     const ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, spirvVersion, 0u, spirv14required);
1186     const string extHeader                = getExtHeader(caseDef);
1187     const string testSrc                  = subgroupMask(caseDef);
1188     const vector<string> headDeclarations = getPerStageHeadDeclarations(caseDef);
1189 
1190     subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, VK_FORMAT_R32_UINT, true,
1191                                extHeader, testSrc, "", headDeclarations);
1192 }
1193 
supportedCheck(Context & context,CaseDefinition caseDef)1194 void supportedCheck(Context &context, CaseDefinition caseDef)
1195 {
1196     if (!subgroups::isSubgroupSupported(context))
1197         TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
1198 
1199     if (caseDef.requiredSubgroupSize)
1200     {
1201         context.requireDeviceFunctionality("VK_EXT_subgroup_size_control");
1202 
1203 #ifndef CTS_USES_VULKANSC
1204         const VkPhysicalDeviceSubgroupSizeControlFeatures &subgroupSizeControlFeatures =
1205             context.getSubgroupSizeControlFeatures();
1206         const VkPhysicalDeviceSubgroupSizeControlProperties &subgroupSizeControlProperties =
1207             context.getSubgroupSizeControlProperties();
1208 #else
1209         const VkPhysicalDeviceSubgroupSizeControlFeaturesEXT &subgroupSizeControlFeatures =
1210             context.getSubgroupSizeControlFeaturesEXT();
1211         const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT &subgroupSizeControlProperties =
1212             context.getSubgroupSizeControlPropertiesEXT();
1213 #endif // CTS_USES_VULKANSC
1214 
1215         if (subgroupSizeControlFeatures.subgroupSizeControl == false)
1216             TCU_THROW(NotSupportedError, "Device does not support varying subgroup sizes nor required subgroup size");
1217 
1218         if (subgroupSizeControlFeatures.computeFullSubgroups == false)
1219             TCU_THROW(NotSupportedError, "Device does not support full subgroups in compute shaders");
1220 
1221         if ((subgroupSizeControlProperties.requiredSubgroupSizeStages & caseDef.shaderStage) != caseDef.shaderStage)
1222             TCU_THROW(NotSupportedError, "Required subgroup size is not supported for shader stage");
1223     }
1224 
1225     *caseDef.geometryPointSizeSupported = subgroups::isTessellationAndGeometryPointSizeSupported(context);
1226 
1227     vkt::subgroups::supportedCheckShader(context, caseDef.shaderStage);
1228 
1229     if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BALLOT_BIT))
1230     {
1231         TCU_THROW(NotSupportedError, "Device does not support subgroup ballot operations");
1232     }
1233 
1234 #ifndef CTS_USES_VULKANSC
1235     if (isAllRayTracingStages(caseDef.shaderStage))
1236     {
1237         context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1238     }
1239     else if (isAllMeshShadingStages(caseDef.shaderStage))
1240     {
1241         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
1242         context.requireDeviceFunctionality("VK_EXT_mesh_shader");
1243 
1244         if ((caseDef.shaderStage & VK_SHADER_STAGE_TASK_BIT_EXT) != 0u)
1245         {
1246             const auto &features = context.getMeshShaderFeaturesEXT();
1247             if (!features.taskShader)
1248                 TCU_THROW(NotSupportedError, "Task shaders not supported");
1249         }
1250     }
1251 #endif // CTS_USES_VULKANSC
1252 }
1253 
noSSBOtest(Context & context,const CaseDefinition caseDef)1254 TestStatus noSSBOtest(Context &context, const CaseDefinition caseDef)
1255 {
1256     switch (caseDef.shaderStage)
1257     {
1258     case VK_SHADER_STAGE_VERTEX_BIT:
1259         return makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStages);
1260     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
1261         return makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL,
1262                                                          checkVertexPipelineStages);
1263     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
1264         return makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL,
1265                                                          checkVertexPipelineStages);
1266     case VK_SHADER_STAGE_GEOMETRY_BIT:
1267         return makeGeometryFrameBufferTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStages);
1268     default:
1269         TCU_THROW(InternalError, "Unhandled shader stage");
1270     }
1271 }
1272 
test(Context & context,const CaseDefinition caseDef)1273 TestStatus test(Context &context, const CaseDefinition caseDef)
1274 {
1275     const bool isCompute = isAllComputeStages(caseDef.shaderStage);
1276 #ifndef CTS_USES_VULKANSC
1277     const bool isMesh = isAllMeshShadingStages(caseDef.shaderStage);
1278 #else
1279     const bool isMesh = false;
1280 #endif // CTS_USES_VULKANSC
1281     DE_ASSERT(!(isCompute && isMesh));
1282 
1283     if (isCompute || isMesh)
1284     {
1285 #ifndef CTS_USES_VULKANSC
1286         const VkPhysicalDeviceSubgroupSizeControlProperties &subgroupSizeControlProperties =
1287             context.getSubgroupSizeControlProperties();
1288 #else
1289         const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT &subgroupSizeControlProperties =
1290             context.getSubgroupSizeControlPropertiesEXT();
1291 #endif // CTS_USES_VULKANSC
1292         TestLog &log = context.getTestContext().getLog();
1293 
1294         if (caseDef.requiredSubgroupSize == false)
1295         {
1296             if (isCompute)
1297                 return makeComputeTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkComputeOrMeshStage);
1298             else
1299                 return makeMeshTest(context, VK_FORMAT_R32_UINT, nullptr, 0, nullptr, checkComputeOrMeshStage);
1300         }
1301 
1302         log << TestLog::Message << "Testing required subgroup size range ["
1303             << subgroupSizeControlProperties.minSubgroupSize << ", " << subgroupSizeControlProperties.maxSubgroupSize
1304             << "]" << TestLog::EndMessage;
1305 
1306         // According to the spec, requiredSubgroupSize must be a power-of-two integer.
1307         for (uint32_t size = subgroupSizeControlProperties.minSubgroupSize;
1308              size <= subgroupSizeControlProperties.maxSubgroupSize; size *= 2)
1309         {
1310             TestStatus result(QP_TEST_RESULT_INTERNAL_ERROR, "Internal Error");
1311 
1312             if (isCompute)
1313                 result = subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL,
1314                                                     checkComputeOrMeshStage, size);
1315             else
1316                 result = subgroups::makeMeshTest(context, VK_FORMAT_R32_UINT, nullptr, 0, nullptr,
1317                                                  checkComputeOrMeshStage, size);
1318 
1319             if (result.getCode() != QP_TEST_RESULT_PASS)
1320             {
1321                 log << TestLog::Message << "subgroupSize " << size << " failed" << TestLog::EndMessage;
1322                 return result;
1323             }
1324         }
1325 
1326         return TestStatus::pass("OK");
1327     }
1328     else if (isAllGraphicsStages(caseDef.shaderStage))
1329     {
1330         const VkShaderStageFlags stages = subgroups::getPossibleGraphicsSubgroupStages(context, caseDef.shaderStage);
1331 
1332         return subgroups::allStages(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStages,
1333                                     stages);
1334     }
1335 #ifndef CTS_USES_VULKANSC
1336     else if (isAllRayTracingStages(caseDef.shaderStage))
1337     {
1338         const VkShaderStageFlags stages = subgroups::getPossibleRayTracingSubgroupStages(context, caseDef.shaderStage);
1339 
1340         return subgroups::allRayTracingStages(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL,
1341                                               checkVertexPipelineStages, stages);
1342     }
1343 #endif // CTS_USES_VULKANSC
1344     else
1345         TCU_THROW(InternalError, "Unknown stage or invalid stage set");
1346 }
1347 
createSubgroupsBuiltinMaskVarTests(TestContext & testCtx)1348 TestCaseGroup *createSubgroupsBuiltinMaskVarTests(TestContext &testCtx)
1349 {
1350     de::MovePtr<TestCaseGroup> group(new TestCaseGroup(testCtx, "builtin_mask_var"));
1351     de::MovePtr<TestCaseGroup> graphicGroup(new TestCaseGroup(testCtx, "graphics"));
1352     de::MovePtr<TestCaseGroup> computeGroup(new TestCaseGroup(testCtx, "compute"));
1353     de::MovePtr<TestCaseGroup> framebufferGroup(new TestCaseGroup(testCtx, "framebuffer"));
1354 #ifndef CTS_USES_VULKANSC
1355     de::MovePtr<TestCaseGroup> raytracingGroup(new TestCaseGroup(testCtx, "ray_tracing"));
1356     de::MovePtr<TestCaseGroup> meshGroup(new TestCaseGroup(testCtx, "mesh"));
1357 #endif // CTS_USES_VULKANSC
1358     const TestType allStagesBuiltinVars[] = {
1359         TEST_TYPE_SUBGROUP_EQ_MASK, TEST_TYPE_SUBGROUP_GE_MASK, TEST_TYPE_SUBGROUP_GT_MASK,
1360         TEST_TYPE_SUBGROUP_LE_MASK, TEST_TYPE_SUBGROUP_LT_MASK,
1361     };
1362     const VkShaderStageFlags fbStages[] = {
1363         VK_SHADER_STAGE_VERTEX_BIT,
1364         VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1365         VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1366         VK_SHADER_STAGE_GEOMETRY_BIT,
1367     };
1368 #ifndef CTS_USES_VULKANSC
1369     const VkShaderStageFlags meshStages[] = {
1370         VK_SHADER_STAGE_MESH_BIT_EXT,
1371         VK_SHADER_STAGE_TASK_BIT_EXT,
1372     };
1373 #endif // CTS_USES_VULKANSC
1374     const bool boolValues[] = {false, true};
1375 
1376     for (int a = 0; a < DE_LENGTH_OF_ARRAY(allStagesBuiltinVars); ++a)
1377     {
1378         const TestType testType = allStagesBuiltinVars[a];
1379         const string name       = getTestName(testType);
1380 
1381         {
1382             const CaseDefinition caseDef = {
1383                 testType,                      //  TestType testType;
1384                 VK_SHADER_STAGE_ALL_GRAPHICS,  //  VkShaderStageFlags shaderStage;
1385                 de::SharedPtr<bool>(new bool), //  de::SharedPtr<bool> geometryPointSizeSupported;
1386                 false                          //  bool requiredSubgroupSize;
1387             };
1388 
1389             addFunctionCaseWithPrograms(graphicGroup.get(), name, supportedCheck, initPrograms, test, caseDef);
1390         }
1391 
1392 #ifndef CTS_USES_VULKANSC
1393         {
1394             const CaseDefinition caseDef = {
1395                 testType,                      //  TestType testType;
1396                 SHADER_STAGE_ALL_RAY_TRACING,  //  VkShaderStageFlags shaderStage;
1397                 de::SharedPtr<bool>(new bool), //  de::SharedPtr<bool> geometryPointSizeSupported;
1398                 false                          //  bool requiredSubgroupSize;
1399             };
1400 
1401             addFunctionCaseWithPrograms(raytracingGroup.get(), name, supportedCheck, initPrograms, test, caseDef);
1402         }
1403 #endif // CTS_USES_VULKANSC
1404 
1405         for (size_t groupSizeNdx = 0; groupSizeNdx < DE_LENGTH_OF_ARRAY(boolValues); ++groupSizeNdx)
1406         {
1407             const bool requiredSubgroupSize = boolValues[groupSizeNdx];
1408             const string testName           = name + (requiredSubgroupSize ? "_requiredsubgroupsize" : "");
1409             const CaseDefinition caseDef    = {
1410                 testType,                      //  TestType testType;
1411                 VK_SHADER_STAGE_COMPUTE_BIT,   //  VkShaderStageFlags shaderStage;
1412                 de::SharedPtr<bool>(new bool), //  de::SharedPtr<bool> geometryPointSizeSupported;
1413                 requiredSubgroupSize           //  bool requiredSubgroupSize;
1414             };
1415 
1416             addFunctionCaseWithPrograms(computeGroup.get(), testName, supportedCheck, initPrograms, test, caseDef);
1417         }
1418 
1419 #ifndef CTS_USES_VULKANSC
1420         for (size_t groupSizeNdx = 0; groupSizeNdx < DE_LENGTH_OF_ARRAY(boolValues); ++groupSizeNdx)
1421         {
1422             for (const auto &stage : meshStages)
1423             {
1424                 const bool requiredSubgroupSize = boolValues[groupSizeNdx];
1425                 const string testName =
1426                     name + (requiredSubgroupSize ? "_requiredsubgroupsize" : "") + "_" + getShaderStageName(stage);
1427                 const CaseDefinition caseDef = {
1428                     testType,                      //  TestType testType;
1429                     stage,                         //  VkShaderStageFlags shaderStage;
1430                     de::SharedPtr<bool>(new bool), //  de::SharedPtr<bool> geometryPointSizeSupported;
1431                     requiredSubgroupSize           //  bool requiredSubgroupSize;
1432                 };
1433 
1434                 addFunctionCaseWithPrograms(meshGroup.get(), testName, supportedCheck, initPrograms, test, caseDef);
1435             }
1436         }
1437 #endif // CTS_USES_VULKANSC
1438 
1439         for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(fbStages); ++stageIndex)
1440         {
1441             const CaseDefinition caseDef = {
1442                 testType,                      //  TestType testType;
1443                 fbStages[stageIndex],          //  VkShaderStageFlags shaderStage;
1444                 de::SharedPtr<bool>(new bool), //  de::SharedPtr<bool> geometryPointSizeSupported;
1445                 false                          //  bool requiredSubgroupSize;
1446             };
1447             const string testName = name + +"_" + getShaderStageName(caseDef.shaderStage);
1448 
1449             addFunctionCaseWithPrograms(framebufferGroup.get(), testName, supportedCheck, initFrameBufferPrograms,
1450                                         noSSBOtest, caseDef);
1451         }
1452     }
1453 
1454     group->addChild(graphicGroup.release());
1455     group->addChild(computeGroup.release());
1456     group->addChild(framebufferGroup.release());
1457 #ifndef CTS_USES_VULKANSC
1458     group->addChild(raytracingGroup.release());
1459     group->addChild(meshGroup.release());
1460 #endif // CTS_USES_VULKANSC
1461 
1462     return group.release();
1463 }
1464 } // namespace subgroups
1465 } // namespace vkt
1466