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
checkComputeStage(const void * internalData,vector<const void * > datas,const deUint32 numWorkgroups[3],const deUint32 localSize[3],deUint32)127 static bool checkComputeStage (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 checkCompute(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 const SpirvVersion spirvVersion = isAllRayTracingStages(caseDef.shaderStage) ? SPIRV_VERSION_1_4 : SPIRV_VERSION_1_3;
1207 const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, spirvVersion, 0u);
1208 const string extHeader = getExtHeader(caseDef);
1209 const string testSrc = subgroupMask(caseDef);
1210 const vector<string> headDeclarations = getPerStageHeadDeclarations(caseDef);
1211
1212 subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, VK_FORMAT_R32_UINT, true, extHeader, testSrc, "", headDeclarations);
1213 }
1214
supportedCheck(Context & context,CaseDefinition caseDef)1215 void supportedCheck (Context& context, CaseDefinition caseDef)
1216 {
1217 if (!subgroups::isSubgroupSupported(context))
1218 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
1219
1220 if (caseDef.requiredSubgroupSize)
1221 {
1222 context.requireDeviceFunctionality("VK_EXT_subgroup_size_control");
1223
1224 const VkPhysicalDeviceSubgroupSizeControlFeaturesEXT& subgroupSizeControlFeatures = context.getSubgroupSizeControlFeaturesEXT();
1225 const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& subgroupSizeControlProperties = context.getSubgroupSizeControlPropertiesEXT();
1226
1227 if (subgroupSizeControlFeatures.subgroupSizeControl == DE_FALSE)
1228 TCU_THROW(NotSupportedError, "Device does not support varying subgroup sizes nor required subgroup size");
1229
1230 if (subgroupSizeControlFeatures.computeFullSubgroups == DE_FALSE)
1231 TCU_THROW(NotSupportedError, "Device does not support full subgroups in compute shaders");
1232
1233 if ((subgroupSizeControlProperties.requiredSubgroupSizeStages & caseDef.shaderStage) != caseDef.shaderStage)
1234 TCU_THROW(NotSupportedError, "Required subgroup size is not supported for shader stage");
1235 }
1236
1237 *caseDef.geometryPointSizeSupported = subgroups::isTessellationAndGeometryPointSizeSupported(context);
1238
1239 vkt::subgroups::supportedCheckShader(context, caseDef.shaderStage);
1240
1241 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BALLOT_BIT))
1242 {
1243 TCU_THROW(NotSupportedError, "Device does not support subgroup ballot operations");
1244 }
1245
1246 if (isAllRayTracingStages(caseDef.shaderStage))
1247 {
1248 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1249 }
1250 }
1251
noSSBOtest(Context & context,const CaseDefinition caseDef)1252 TestStatus noSSBOtest(Context& context, const CaseDefinition caseDef)
1253 {
1254 switch (caseDef.shaderStage)
1255 {
1256 case VK_SHADER_STAGE_VERTEX_BIT: return makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStages);
1257 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStages);
1258 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStages);
1259 case VK_SHADER_STAGE_GEOMETRY_BIT: return makeGeometryFrameBufferTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStages);
1260 default: TCU_THROW(InternalError, "Unhandled shader stage");
1261 }
1262 }
1263
test(Context & context,const CaseDefinition caseDef)1264 TestStatus test(Context& context, const CaseDefinition caseDef)
1265 {
1266 if (isAllComputeStages(caseDef.shaderStage))
1267 {
1268 const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& subgroupSizeControlProperties = context.getSubgroupSizeControlPropertiesEXT();
1269 TestLog& log = context.getTestContext().getLog();
1270
1271 if (caseDef.requiredSubgroupSize == DE_FALSE)
1272 return makeComputeTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkComputeStage);
1273
1274 log << TestLog::Message << "Testing required subgroup size range [" << subgroupSizeControlProperties.minSubgroupSize << ", "
1275 << subgroupSizeControlProperties.maxSubgroupSize << "]" << TestLog::EndMessage;
1276
1277 // According to the spec, requiredSubgroupSize must be a power-of-two integer.
1278 for (deUint32 size = subgroupSizeControlProperties.minSubgroupSize; size <= subgroupSizeControlProperties.maxSubgroupSize; size *= 2)
1279 {
1280 TestStatus result = subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkComputeStage,
1281 size, VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT);
1282 if (result.getCode() != QP_TEST_RESULT_PASS)
1283 {
1284 log << TestLog::Message << "subgroupSize " << size << " failed" << TestLog::EndMessage;
1285 return result;
1286 }
1287 }
1288
1289 return TestStatus::pass("OK");
1290 }
1291 else if (isAllGraphicsStages(caseDef.shaderStage))
1292 {
1293 const VkShaderStageFlags stages = subgroups::getPossibleGraphicsSubgroupStages(context, caseDef.shaderStage);
1294
1295 return subgroups::allStages(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStages, stages);
1296 }
1297 else if (isAllRayTracingStages(caseDef.shaderStage))
1298 {
1299 const VkShaderStageFlags stages = subgroups::getPossibleRayTracingSubgroupStages(context, caseDef.shaderStage);
1300
1301 return subgroups::allRayTracingStages(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStages, stages);
1302 }
1303 else
1304 TCU_THROW(InternalError, "Unknown stage or invalid stage set");
1305 }
1306
createSubgroupsBuiltinMaskVarTests(TestContext & testCtx)1307 TestCaseGroup* createSubgroupsBuiltinMaskVarTests (TestContext& testCtx)
1308 {
1309 de::MovePtr<TestCaseGroup> group (new TestCaseGroup(testCtx, "builtin_mask_var", "Subgroup builtin mask variable tests"));
1310 de::MovePtr<TestCaseGroup> graphicGroup (new TestCaseGroup(testCtx, "graphics", "Subgroup builtin mask category tests: graphics"));
1311 de::MovePtr<TestCaseGroup> computeGroup (new TestCaseGroup(testCtx, "compute", "Subgroup builtin mask category tests: compute"));
1312 de::MovePtr<TestCaseGroup> framebufferGroup (new TestCaseGroup(testCtx, "framebuffer", "Subgroup builtin mask category tests: framebuffer"));
1313 de::MovePtr<TestCaseGroup> raytracingGroup (new TestCaseGroup(testCtx, "ray_tracing", "Subgroup builtin mask category tests: ray tracing"));
1314 const TestType allStagesBuiltinVars[] =
1315 {
1316 TEST_TYPE_SUBGROUP_EQ_MASK,
1317 TEST_TYPE_SUBGROUP_GE_MASK,
1318 TEST_TYPE_SUBGROUP_GT_MASK,
1319 TEST_TYPE_SUBGROUP_LE_MASK,
1320 TEST_TYPE_SUBGROUP_LT_MASK,
1321 };
1322 const VkShaderStageFlags stages[] =
1323 {
1324 VK_SHADER_STAGE_VERTEX_BIT,
1325 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1326 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1327 VK_SHADER_STAGE_GEOMETRY_BIT,
1328 };
1329 const deBool boolValues[] =
1330 {
1331 DE_FALSE,
1332 DE_TRUE
1333 };
1334
1335 for (int a = 0; a < DE_LENGTH_OF_ARRAY(allStagesBuiltinVars); ++a)
1336 {
1337 const TestType testType = allStagesBuiltinVars[a];
1338 const string name = getTestName(testType);
1339
1340 {
1341 const CaseDefinition caseDef =
1342 {
1343 testType, // TestType testType;
1344 VK_SHADER_STAGE_ALL_GRAPHICS, // VkShaderStageFlags shaderStage;
1345 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
1346 DE_FALSE // deBool requiredSubgroupSize;
1347 };
1348
1349 addFunctionCaseWithPrograms(graphicGroup.get(), name, "", supportedCheck, initPrograms, test, caseDef);
1350 }
1351
1352 {
1353 const CaseDefinition caseDef =
1354 {
1355 testType, // TestType testType;
1356 SHADER_STAGE_ALL_RAY_TRACING, // VkShaderStageFlags shaderStage;
1357 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
1358 DE_FALSE // deBool requiredSubgroupSize;
1359 };
1360
1361 addFunctionCaseWithPrograms(raytracingGroup.get(), name, "", supportedCheck, initPrograms, test, caseDef);
1362 }
1363
1364 for (size_t groupSizeNdx = 0; groupSizeNdx < DE_LENGTH_OF_ARRAY(boolValues); ++groupSizeNdx)
1365 {
1366 const deBool requiredSubgroupSize = boolValues[groupSizeNdx];
1367 const string testName = name + (requiredSubgroupSize ? "_requiredsubgroupsize" : "");
1368 const CaseDefinition caseDef =
1369 {
1370 testType, // TestType testType;
1371 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags shaderStage;
1372 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
1373 requiredSubgroupSize // deBool requiredSubgroupSize;
1374 };
1375
1376 addFunctionCaseWithPrograms(computeGroup.get(), testName, "", supportedCheck, initPrograms, test, caseDef);
1377 }
1378
1379 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
1380 {
1381 const CaseDefinition caseDef =
1382 {
1383 testType, // TestType testType;
1384 stages[stageIndex], // VkShaderStageFlags shaderStage;
1385 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
1386 DE_FALSE // deBool requiredSubgroupSize;
1387 };
1388 const string testName = name + + "_" + getShaderStageName(caseDef.shaderStage);
1389
1390 addFunctionCaseWithPrograms(framebufferGroup.get(), testName, "", supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
1391 }
1392 }
1393
1394 group->addChild(graphicGroup.release());
1395 group->addChild(computeGroup.release());
1396 group->addChild(framebufferGroup.release());
1397 group->addChild(raytracingGroup.release());
1398
1399 return group.release();
1400 }
1401 } // subgroups
1402 } // vkt
1403