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