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