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 "vktSubgroupsBuiltinVarTests.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
checkVertexPipelineStagesSubgroupSize(std::vector<const void * > datas,deUint32 width,deUint32 subgroupSize)40 bool checkVertexPipelineStagesSubgroupSize(std::vector<const void*> datas,
41 deUint32 width, deUint32 subgroupSize)
42 {
43 const deUint32* data =
44 reinterpret_cast<const deUint32*>(datas[0]);
45 for (deUint32 x = 0; x < width; ++x)
46 {
47 deUint32 val = data[x * 4];
48
49 if (subgroupSize != val)
50 return false;
51 }
52
53 return true;
54 }
55
checkVertexPipelineStagesSubgroupInvocationID(std::vector<const void * > datas,deUint32 width,deUint32 subgroupSize)56 bool checkVertexPipelineStagesSubgroupInvocationID(std::vector<const void*> datas,
57 deUint32 width, deUint32 subgroupSize)
58 {
59 const deUint32* data =
60 reinterpret_cast<const deUint32*>(datas[0]);
61 vector<deUint32> subgroupInvocationHits(subgroupSize, 0);
62
63 for (deUint32 x = 0; x < width; ++x)
64 {
65 deUint32 subgroupInvocationID = data[(x * 4) + 1];
66
67 if (subgroupInvocationID >= subgroupSize)
68 return false;
69 subgroupInvocationHits[subgroupInvocationID]++;
70 }
71
72 const deUint32 totalSize = width;
73
74 deUint32 totalInvocationsRun = 0;
75 for (deUint32 i = 0; i < subgroupSize; ++i)
76 {
77 totalInvocationsRun += subgroupInvocationHits[i];
78 }
79
80 if (totalInvocationsRun != totalSize)
81 return false;
82
83 return true;
84 }
85
checkComputeSubgroupSize(std::vector<const void * > datas,const deUint32 numWorkgroups[3],const deUint32 localSize[3],deUint32 subgroupSize)86 static bool checkComputeSubgroupSize(std::vector<const void*> datas,
87 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
88 deUint32 subgroupSize)
89 {
90 const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]);
91
92 for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
93 {
94 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
95 {
96 for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
97 {
98 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
99 {
100 for (deUint32 lY = 0; lY < localSize[1]; ++lY)
101 {
102 for (deUint32 lZ = 0; lZ < localSize[2];
103 ++lZ)
104 {
105 const deUint32 globalInvocationX =
106 nX * localSize[0] + lX;
107 const deUint32 globalInvocationY =
108 nY * localSize[1] + lY;
109 const deUint32 globalInvocationZ =
110 nZ * localSize[2] + lZ;
111
112 const deUint32 globalSizeX =
113 numWorkgroups[0] * localSize[0];
114 const deUint32 globalSizeY =
115 numWorkgroups[1] * localSize[1];
116
117 const deUint32 offset =
118 globalSizeX *
119 ((globalSizeY *
120 globalInvocationZ) +
121 globalInvocationY) +
122 globalInvocationX;
123
124 if (subgroupSize != data[offset * 4])
125 return false;
126 }
127 }
128 }
129 }
130 }
131 }
132
133 return true;
134 }
135
checkComputeSubgroupInvocationID(std::vector<const void * > datas,const deUint32 numWorkgroups[3],const deUint32 localSize[3],deUint32 subgroupSize)136 static bool checkComputeSubgroupInvocationID(std::vector<const void*> datas,
137 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
138 deUint32 subgroupSize)
139 {
140 const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]);
141
142 for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
143 {
144 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
145 {
146 for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
147 {
148 const deUint32 totalLocalSize =
149 localSize[0] * localSize[1] * localSize[2];
150 vector<deUint32> subgroupInvocationHits(subgroupSize, 0);
151
152 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
153 {
154 for (deUint32 lY = 0; lY < localSize[1]; ++lY)
155 {
156 for (deUint32 lZ = 0; lZ < localSize[2];
157 ++lZ)
158 {
159 const deUint32 globalInvocationX =
160 nX * localSize[0] + lX;
161 const deUint32 globalInvocationY =
162 nY * localSize[1] + lY;
163 const deUint32 globalInvocationZ =
164 nZ * localSize[2] + lZ;
165
166 const deUint32 globalSizeX =
167 numWorkgroups[0] * localSize[0];
168 const deUint32 globalSizeY =
169 numWorkgroups[1] * localSize[1];
170
171 const deUint32 offset =
172 globalSizeX *
173 ((globalSizeY *
174 globalInvocationZ) +
175 globalInvocationY) +
176 globalInvocationX;
177
178 deUint32 subgroupInvocationID = data[(offset * 4) + 1];
179
180 if (subgroupInvocationID >= subgroupSize)
181 return false;
182
183 subgroupInvocationHits[subgroupInvocationID]++;
184 }
185 }
186 }
187
188 deUint32 totalInvocationsRun = 0;
189 for (deUint32 i = 0; i < subgroupSize; ++i)
190 {
191 totalInvocationsRun += subgroupInvocationHits[i];
192 }
193
194 if (totalInvocationsRun != totalLocalSize)
195 return false;
196 }
197 }
198 }
199
200 return true;
201 }
202
checkComputeNumSubgroups(std::vector<const void * > datas,const deUint32 numWorkgroups[3],const deUint32 localSize[3],deUint32)203 static bool checkComputeNumSubgroups (std::vector<const void*> datas,
204 const deUint32 numWorkgroups[3],
205 const deUint32 localSize[3],
206 deUint32)
207 {
208 const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]);
209
210 for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
211 {
212 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
213 {
214 for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
215 {
216 const deUint32 totalLocalSize =
217 localSize[0] * localSize[1] * localSize[2];
218
219 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
220 {
221 for (deUint32 lY = 0; lY < localSize[1]; ++lY)
222 {
223 for (deUint32 lZ = 0; lZ < localSize[2];
224 ++lZ)
225 {
226 const deUint32 globalInvocationX =
227 nX * localSize[0] + lX;
228 const deUint32 globalInvocationY =
229 nY * localSize[1] + lY;
230 const deUint32 globalInvocationZ =
231 nZ * localSize[2] + lZ;
232
233 const deUint32 globalSizeX =
234 numWorkgroups[0] * localSize[0];
235 const deUint32 globalSizeY =
236 numWorkgroups[1] * localSize[1];
237
238 const deUint32 offset =
239 globalSizeX *
240 ((globalSizeY *
241 globalInvocationZ) +
242 globalInvocationY) +
243 globalInvocationX;
244
245 deUint32 numSubgroups = data[(offset * 4) + 2];
246
247 if (numSubgroups > totalLocalSize)
248 return false;
249 }
250 }
251 }
252 }
253 }
254 }
255
256 return true;
257 }
258
checkComputeSubgroupID(std::vector<const void * > datas,const deUint32 numWorkgroups[3],const deUint32 localSize[3],deUint32)259 static bool checkComputeSubgroupID (std::vector<const void*> datas,
260 const deUint32 numWorkgroups[3],
261 const deUint32 localSize[3],
262 deUint32)
263 {
264 const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]);
265
266 for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
267 {
268 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
269 {
270 for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
271 {
272 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
273 {
274 for (deUint32 lY = 0; lY < localSize[1]; ++lY)
275 {
276 for (deUint32 lZ = 0; lZ < localSize[2];
277 ++lZ)
278 {
279 const deUint32 globalInvocationX =
280 nX * localSize[0] + lX;
281 const deUint32 globalInvocationY =
282 nY * localSize[1] + lY;
283 const deUint32 globalInvocationZ =
284 nZ * localSize[2] + lZ;
285
286 const deUint32 globalSizeX =
287 numWorkgroups[0] * localSize[0];
288 const deUint32 globalSizeY =
289 numWorkgroups[1] * localSize[1];
290
291 const deUint32 offset =
292 globalSizeX *
293 ((globalSizeY *
294 globalInvocationZ) +
295 globalInvocationY) +
296 globalInvocationX;
297
298 deUint32 numSubgroups = data[(offset * 4) + 2];
299 deUint32 subgroupID = data[(offset * 4) + 3];
300
301 if (subgroupID >= numSubgroups)
302 return false;
303 }
304 }
305 }
306 }
307 }
308 }
309
310 return true;
311 }
312
313 namespace
314 {
315 struct CaseDefinition
316 {
317 std::string varName;
318 VkShaderStageFlags shaderStage;
319 };
320 }
321
initFrameBufferPrograms(SourceCollections & programCollection,CaseDefinition caseDef)322 void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
323 {
324 const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
325 const vk::SpirVAsmBuildOptions buildOptionsSpr (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3);
326
327 {
328 /*
329 "layout(location = 0) in vec4 in_color;\n"
330 "layout(location = 0) out uvec4 out_color;\n"
331 "void main()\n"
332 "{\n"
333 " out_color = uvec4(in_color);\n"
334 "}\n";
335 */
336 const string fragment =
337 "; SPIR-V\n"
338 "; Version: 1.3\n"
339 "; Generator: Khronos Glslang Reference Front End; 2\n"
340 "; Bound: 16\n"
341 "; Schema: 0\n"
342 "OpCapability Shader\n"
343 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
344 "OpMemoryModel Logical GLSL450\n"
345 "OpEntryPoint Fragment %4 \"main\" %9 %13\n"
346 "OpExecutionMode %4 OriginUpperLeft\n"
347 "OpDecorate %9 Location 0\n"
348 "OpDecorate %13 Location 0\n"
349 "%2 = OpTypeVoid\n"
350 "%3 = OpTypeFunction %2\n"
351 "%6 = OpTypeInt 32 0\n"
352 "%7 = OpTypeVector %6 4\n"
353 "%8 = OpTypePointer Output %7\n"
354 "%9 = OpVariable %8 Output\n"
355 "%10 = OpTypeFloat 32\n"
356 "%11 = OpTypeVector %10 4\n"
357 "%12 = OpTypePointer Input %11\n"
358 "%13 = OpVariable %12 Input\n"
359 "%4 = OpFunction %2 None %3\n"
360 "%5 = OpLabel\n"
361 "%14 = OpLoad %11 %13\n"
362 "%15 = OpConvertFToU %7 %14\n"
363 "OpStore %9 %15\n"
364 "OpReturn\n"
365 "OpFunctionEnd\n";
366 programCollection.spirvAsmSources.add("fragment") << fragment << buildOptionsSpr;
367 }
368
369 if (VK_SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
370 subgroups::setVertexShaderFrameBuffer(programCollection);
371
372 if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
373 {
374 /*
375 "#extension GL_KHR_shader_subgroup_basic: enable\n"
376 "layout(location = 0) out vec4 out_color;\n"
377 "layout(location = 0) in highp vec4 in_position;\n"
378 "\n"
379 "void main (void)\n"
380 "{\n"
381 " out_color = vec4(gl_SubgroupSize, gl_SubgroupInvocationID, 1.0f, 1.0f);\n"
382 " gl_Position = in_position;\n"
383 " gl_PointSize = 1.0f;\n"
384 "}\n";
385 */
386 const string vertex =
387 "; SPIR-V\n"
388 "; Version: 1.3\n"
389 "; Generator: Khronos Glslang Reference Front End; 2\n"
390 "; Bound: 31\n"
391 "; Schema: 0\n"
392 "OpCapability Shader\n"
393 "OpCapability GroupNonUniform\n"
394 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
395 "OpMemoryModel Logical GLSL450\n"
396 "OpEntryPoint Vertex %4 \"main\" %9 %12 %15 %24 %28\n"
397 "OpDecorate %9 Location 0\n"
398 "OpDecorate %12 RelaxedPrecision\n"
399 "OpDecorate %12 BuiltIn SubgroupSize\n"
400 "OpDecorate %13 RelaxedPrecision\n"
401 "OpDecorate %15 RelaxedPrecision\n"
402 "OpDecorate %15 BuiltIn SubgroupLocalInvocationId\n"
403 "OpDecorate %16 RelaxedPrecision\n"
404 "OpMemberDecorate %22 0 BuiltIn Position\n"
405 "OpMemberDecorate %22 1 BuiltIn PointSize\n"
406 "OpMemberDecorate %22 2 BuiltIn ClipDistance\n"
407 "OpMemberDecorate %22 3 BuiltIn CullDistance\n"
408 "OpDecorate %22 Block\n"
409 "OpDecorate %28 Location 0\n"
410 "%2 = OpTypeVoid\n"
411 "%3 = OpTypeFunction %2\n"
412 "%6 = OpTypeFloat 32\n"
413 "%7 = OpTypeVector %6 4\n"
414 "%8 = OpTypePointer Output %7\n"
415 "%9 = OpVariable %8 Output\n"
416 "%10 = OpTypeInt 32 0\n"
417 "%11 = OpTypePointer Input %10\n"
418 "%12 = OpVariable %11 Input\n"
419 "%15 = OpVariable %11 Input\n"
420 "%18 = OpConstant %6 1\n"
421 "%20 = OpConstant %10 1\n"
422 "%21 = OpTypeArray %6 %20\n"
423 "%22 = OpTypeStruct %7 %6 %21 %21\n"
424 "%23 = OpTypePointer Output %22\n"
425 "%24 = OpVariable %23 Output\n"
426 "%25 = OpTypeInt 32 1\n"
427 "%26 = OpConstant %25 0\n"
428 "%27 = OpTypePointer Input %7\n"
429 "%28 = OpVariable %27 Input\n"
430 "%31 = OpConstant %25 1\n"
431 "%32 = OpTypePointer Output %6\n"
432 "%4 = OpFunction %2 None %3\n"
433 "%5 = OpLabel\n"
434 "%13 = OpLoad %10 %12\n"
435 "%14 = OpConvertUToF %6 %13\n"
436 "%16 = OpLoad %10 %15\n"
437 "%17 = OpConvertUToF %6 %16\n"
438 "%19 = OpCompositeConstruct %7 %14 %17 %18 %18\n"
439 "OpStore %9 %19\n"
440 "%29 = OpLoad %7 %28\n"
441 "%30 = OpAccessChain %8 %24 %26\n"
442 "OpStore %30 %29\n"
443 "%33 = OpAccessChain %32 %24 %31\n"
444 "OpStore %33 %18\n"
445 "OpReturn\n"
446 "OpFunctionEnd\n";
447 programCollection.spirvAsmSources.add("vert") << vertex << buildOptionsSpr;
448 }
449 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
450 {
451 /*
452 "#extension GL_EXT_tessellation_shader : require\n"
453 "layout(vertices = 2) out;\n"
454 "layout(location = 0) out vec4 out_color[];\n"
455 "void main (void)\n"
456 "{\n"
457 " if (gl_InvocationID == 0)\n"
458 {\n"
459 " gl_TessLevelOuter[0] = 1.0f;\n"
460 " gl_TessLevelOuter[1] = 1.0f;\n"
461 " }\n"
462 " out_color[gl_InvocationID] = vec4(0.0f);\n"
463 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
464 "}\n";
465 */
466 const string controlSource =
467 "; SPIR-V\n"
468 "; Version: 1.3\n"
469 "; Generator: Khronos Glslang Reference Front End; 2\n"
470 "; Bound: 53\n"
471 "; Schema: 0\n"
472 "OpCapability Tessellation\n"
473 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
474 "OpMemoryModel Logical GLSL450\n"
475 "OpEntryPoint TessellationControl %4 \"main\" %8 %20 %30 %41 %47\n"
476 "OpExecutionMode %4 OutputVertices 2\n"
477 "OpDecorate %8 BuiltIn InvocationId\n"
478 "OpDecorate %20 Patch\n"
479 "OpDecorate %20 BuiltIn TessLevelOuter\n"
480 "OpDecorate %30 Location 0\n"
481 "OpMemberDecorate %38 0 BuiltIn Position\n"
482 "OpMemberDecorate %38 1 BuiltIn PointSize\n"
483 "OpMemberDecorate %38 2 BuiltIn ClipDistance\n"
484 "OpMemberDecorate %38 3 BuiltIn CullDistance\n"
485 "OpDecorate %38 Block\n"
486 "OpMemberDecorate %43 0 BuiltIn Position\n"
487 "OpMemberDecorate %43 1 BuiltIn PointSize\n"
488 "OpMemberDecorate %43 2 BuiltIn ClipDistance\n"
489 "OpMemberDecorate %43 3 BuiltIn CullDistance\n"
490 "OpDecorate %43 Block\n"
491 "%2 = OpTypeVoid\n"
492 "%3 = OpTypeFunction %2\n"
493 "%6 = OpTypeInt 32 1\n"
494 "%7 = OpTypePointer Input %6\n"
495 "%8 = OpVariable %7 Input\n"
496 "%10 = OpConstant %6 0\n"
497 "%11 = OpTypeBool\n"
498 "%15 = OpTypeFloat 32\n"
499 "%16 = OpTypeInt 32 0\n"
500 "%17 = OpConstant %16 4\n"
501 "%18 = OpTypeArray %15 %17\n"
502 "%19 = OpTypePointer Output %18\n"
503 "%20 = OpVariable %19 Output\n"
504 "%21 = OpConstant %15 1\n"
505 "%22 = OpTypePointer Output %15\n"
506 "%24 = OpConstant %6 1\n"
507 "%26 = OpTypeVector %15 4\n"
508 "%27 = OpConstant %16 2\n"
509 "%28 = OpTypeArray %26 %27\n"
510 "%29 = OpTypePointer Output %28\n"
511 "%30 = OpVariable %29 Output\n"
512 "%32 = OpConstant %15 0\n"
513 "%33 = OpConstantComposite %26 %32 %32 %32 %32\n"
514 "%34 = OpTypePointer Output %26\n"
515 "%36 = OpConstant %16 1\n"
516 "%37 = OpTypeArray %15 %36\n"
517 "%38 = OpTypeStruct %26 %15 %37 %37\n"
518 "%39 = OpTypeArray %38 %27\n"
519 "%40 = OpTypePointer Output %39\n"
520 "%41 = OpVariable %40 Output\n"
521 "%43 = OpTypeStruct %26 %15 %37 %37\n"
522 "%44 = OpConstant %16 32\n"
523 "%45 = OpTypeArray %43 %44\n"
524 "%46 = OpTypePointer Input %45\n"
525 "%47 = OpVariable %46 Input\n"
526 "%49 = OpTypePointer Input %26\n"
527 "%4 = OpFunction %2 None %3\n"
528 "%5 = OpLabel\n"
529 "%9 = OpLoad %6 %8\n"
530 "%12 = OpIEqual %11 %9 %10\n"
531 "OpSelectionMerge %14 None\n"
532 "OpBranchConditional %12 %13 %14\n"
533 "%13 = OpLabel\n"
534 "%23 = OpAccessChain %22 %20 %10\n"
535 "OpStore %23 %21\n"
536 "%25 = OpAccessChain %22 %20 %24\n"
537 "OpStore %25 %21\n"
538 "OpBranch %14\n"
539 "%14 = OpLabel\n"
540 "%31 = OpLoad %6 %8\n"
541 "%35 = OpAccessChain %34 %30 %31\n"
542 "OpStore %35 %33\n"
543 "%42 = OpLoad %6 %8\n"
544 "%48 = OpLoad %6 %8\n"
545 "%50 = OpAccessChain %49 %47 %48 %10\n"
546 "%51 = OpLoad %26 %50\n"
547 "%52 = OpAccessChain %34 %41 %42 %10\n"
548 "OpStore %52 %51\n"
549 "OpReturn\n"
550 "OpFunctionEnd\n";
551 programCollection.spirvAsmSources.add("tesc") << controlSource << buildOptionsSpr;
552
553 /*
554 "#extension GL_KHR_shader_subgroup_basic: enable\n"
555 "#extension GL_EXT_tessellation_shader : require\n"
556 "layout(isolines, equal_spacing, ccw ) in;\n"
557 "layout(location = 0) in vec4 in_color[];\n"
558 "layout(location = 0) out vec4 out_color;\n"
559 "\n"
560 "void main (void)\n"
561 "{\n"
562 " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
563 " out_color = vec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0.0f, 0.0f);\n"
564 "}\n";
565 */
566 const string evaluationSource =
567 "; SPIR-V\n"
568 "; Version: 1.3\n"
569 "; Generator: Khronos Glslang Reference Front End; 2\n"
570 "; Bound: 51\n"
571 "; Schema: 0\n"
572 "OpCapability Tessellation\n"
573 "OpCapability GroupNonUniform\n"
574 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
575 "OpMemoryModel Logical GLSL450\n"
576 "OpEntryPoint TessellationEvaluation %4 \"main\" %13 %20 %29 %38 %40 %43 %50\n"
577 "OpExecutionMode %4 Isolines\n"
578 "OpExecutionMode %4 SpacingEqual\n"
579 "OpExecutionMode %4 VertexOrderCcw\n"
580 "OpMemberDecorate %11 0 BuiltIn Position\n"
581 "OpMemberDecorate %11 1 BuiltIn PointSize\n"
582 "OpMemberDecorate %11 2 BuiltIn ClipDistance\n"
583 "OpMemberDecorate %11 3 BuiltIn CullDistance\n"
584 "OpDecorate %11 Block\n"
585 "OpMemberDecorate %16 0 BuiltIn Position\n"
586 "OpMemberDecorate %16 1 BuiltIn PointSize\n"
587 "OpMemberDecorate %16 2 BuiltIn ClipDistance\n"
588 "OpMemberDecorate %16 3 BuiltIn CullDistance\n"
589 "OpDecorate %16 Block\n"
590 "OpDecorate %29 BuiltIn TessCoord\n"
591 "OpDecorate %38 Location 0\n"
592 "OpDecorate %40 RelaxedPrecision\n"
593 "OpDecorate %40 BuiltIn SubgroupSize\n"
594 "OpDecorate %41 RelaxedPrecision\n"
595 "OpDecorate %43 RelaxedPrecision\n"
596 "OpDecorate %43 BuiltIn SubgroupLocalInvocationId\n"
597 "OpDecorate %44 RelaxedPrecision\n"
598 "OpDecorate %50 Location 0\n"
599 "%2 = OpTypeVoid\n"
600 "%3 = OpTypeFunction %2\n"
601 "%6 = OpTypeFloat 32\n"
602 "%7 = OpTypeVector %6 4\n"
603 "%8 = OpTypeInt 32 0\n"
604 "%9 = OpConstant %8 1\n"
605 "%10 = OpTypeArray %6 %9\n"
606 "%11 = OpTypeStruct %7 %6 %10 %10\n"
607 "%12 = OpTypePointer Output %11\n"
608 "%13 = OpVariable %12 Output\n"
609 "%14 = OpTypeInt 32 1\n"
610 "%15 = OpConstant %14 0\n"
611 "%16 = OpTypeStruct %7 %6 %10 %10\n"
612 "%17 = OpConstant %8 32\n"
613 "%18 = OpTypeArray %16 %17\n"
614 "%19 = OpTypePointer Input %18\n"
615 "%20 = OpVariable %19 Input\n"
616 "%21 = OpTypePointer Input %7\n"
617 "%24 = OpConstant %14 1\n"
618 "%27 = OpTypeVector %6 3\n"
619 "%28 = OpTypePointer Input %27\n"
620 "%29 = OpVariable %28 Input\n"
621 "%30 = OpConstant %8 0\n"
622 "%31 = OpTypePointer Input %6\n"
623 "%36 = OpTypePointer Output %7\n"
624 "%38 = OpVariable %36 Output\n"
625 "%39 = OpTypePointer Input %8\n"
626 "%40 = OpVariable %39 Input\n"
627 "%43 = OpVariable %39 Input\n"
628 "%46 = OpConstant %6 0\n"
629 "%48 = OpTypeArray %7 %17\n"
630 "%49 = OpTypePointer Input %48\n"
631 "%50 = OpVariable %49 Input\n"
632 "%4 = OpFunction %2 None %3\n"
633 "%5 = OpLabel\n"
634 "%22 = OpAccessChain %21 %20 %15 %15\n"
635 "%23 = OpLoad %7 %22\n"
636 "%25 = OpAccessChain %21 %20 %24 %15\n"
637 "%26 = OpLoad %7 %25\n"
638 "%32 = OpAccessChain %31 %29 %30\n"
639 "%33 = OpLoad %6 %32\n"
640 "%34 = OpCompositeConstruct %7 %33 %33 %33 %33\n"
641 "%35 = OpExtInst %7 %1 FMix %23 %26 %34\n"
642 "%37 = OpAccessChain %36 %13 %15\n"
643 "OpStore %37 %35\n"
644 "%41 = OpLoad %8 %40\n"
645 "%42 = OpConvertUToF %6 %41\n"
646 "%44 = OpLoad %8 %43\n"
647 "%45 = OpConvertUToF %6 %44\n"
648 "%47 = OpCompositeConstruct %7 %42 %45 %46 %46\n"
649 "OpStore %38 %47\n"
650 "OpReturn\n"
651 "OpFunctionEnd\n";
652
653 programCollection.spirvAsmSources.add("tese") << evaluationSource << buildOptionsSpr;
654 }
655 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
656 {
657 /*
658 "#extension GL_EXT_tessellation_shader : require\n"
659 "#extension GL_KHR_shader_subgroup_basic: enable\n"
660 "layout(vertices = 2) out;\n"
661 "layout(location = 0) out vec4 out_color[];\n"
662 "void main (void)\n"
663 "{\n"
664 " if (gl_InvocationID == 0)\n"
665 {\n"
666 " gl_TessLevelOuter[0] = 1.0f;\n"
667 " gl_TessLevelOuter[1] = 1.0f;\n"
668 " }\n"
669 " out_color[gl_InvocationID] = vec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
670 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
671 "}\n";
672 */
673 const string controlSource =
674 "; SPIR-V\n"
675 "; Version: 1.3\n"
676 "; Generator: Khronos Glslang Reference Front End; 2\n"
677 "; Bound: 60\n"
678 "; Schema: 0\n"
679 "OpCapability Tessellation\n"
680 "OpCapability GroupNonUniform\n"
681 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
682 "OpMemoryModel Logical GLSL450\n"
683 "OpEntryPoint TessellationControl %4 \"main\" %8 %20 %30 %33 %36 %48 %54\n"
684 "OpExecutionMode %4 OutputVertices 2\n"
685 "OpDecorate %8 BuiltIn InvocationId\n"
686 "OpDecorate %20 Patch\n"
687 "OpDecorate %20 BuiltIn TessLevelOuter\n"
688 "OpDecorate %30 Location 0\n"
689 "OpDecorate %33 RelaxedPrecision\n"
690 "OpDecorate %33 BuiltIn SubgroupSize\n"
691 "OpDecorate %34 RelaxedPrecision\n"
692 "OpDecorate %36 RelaxedPrecision\n"
693 "OpDecorate %36 BuiltIn SubgroupLocalInvocationId\n"
694 "OpDecorate %37 RelaxedPrecision\n"
695 "OpMemberDecorate %45 0 BuiltIn Position\n"
696 "OpMemberDecorate %45 1 BuiltIn PointSize\n"
697 "OpMemberDecorate %45 2 BuiltIn ClipDistance\n"
698 "OpMemberDecorate %45 3 BuiltIn CullDistance\n"
699 "OpDecorate %45 Block\n"
700 "OpMemberDecorate %50 0 BuiltIn Position\n"
701 "OpMemberDecorate %50 1 BuiltIn PointSize\n"
702 "OpMemberDecorate %50 2 BuiltIn ClipDistance\n"
703 "OpMemberDecorate %50 3 BuiltIn CullDistance\n"
704 "OpDecorate %50 Block\n"
705 "%2 = OpTypeVoid\n"
706 "%3 = OpTypeFunction %2\n"
707 "%6 = OpTypeInt 32 1\n"
708 "%7 = OpTypePointer Input %6\n"
709 "%8 = OpVariable %7 Input\n"
710 "%10 = OpConstant %6 0\n"
711 "%11 = OpTypeBool\n"
712 "%15 = OpTypeFloat 32\n"
713 "%16 = OpTypeInt 32 0\n"
714 "%17 = OpConstant %16 4\n"
715 "%18 = OpTypeArray %15 %17\n"
716 "%19 = OpTypePointer Output %18\n"
717 "%20 = OpVariable %19 Output\n"
718 "%21 = OpConstant %15 1\n"
719 "%22 = OpTypePointer Output %15\n"
720 "%24 = OpConstant %6 1\n"
721 "%26 = OpTypeVector %15 4\n"
722 "%27 = OpConstant %16 2\n"
723 "%28 = OpTypeArray %26 %27\n"
724 "%29 = OpTypePointer Output %28\n"
725 "%30 = OpVariable %29 Output\n"
726 "%32 = OpTypePointer Input %16\n"
727 "%33 = OpVariable %32 Input\n"
728 "%36 = OpVariable %32 Input\n"
729 "%39 = OpConstant %15 0\n"
730 "%41 = OpTypePointer Output %26\n"
731 "%43 = OpConstant %16 1\n"
732 "%44 = OpTypeArray %15 %43\n"
733 "%45 = OpTypeStruct %26 %15 %44 %44\n"
734 "%46 = OpTypeArray %45 %27\n"
735 "%47 = OpTypePointer Output %46\n"
736 "%48 = OpVariable %47 Output\n"
737 "%50 = OpTypeStruct %26 %15 %44 %44\n"
738 "%51 = OpConstant %16 32\n"
739 "%52 = OpTypeArray %50 %51\n"
740 "%53 = OpTypePointer Input %52\n"
741 "%54 = OpVariable %53 Input\n"
742 "%56 = OpTypePointer Input %26\n"
743 "%4 = OpFunction %2 None %3\n"
744 "%5 = OpLabel\n"
745 "%9 = OpLoad %6 %8\n"
746 "%12 = OpIEqual %11 %9 %10\n"
747 "OpSelectionMerge %14 None\n"
748 "OpBranchConditional %12 %13 %14\n"
749 "%13 = OpLabel\n"
750 "%23 = OpAccessChain %22 %20 %10\n"
751 "OpStore %23 %21\n"
752 "%25 = OpAccessChain %22 %20 %24\n"
753 "OpStore %25 %21\n"
754 "OpBranch %14\n"
755 "%14 = OpLabel\n"
756 "%31 = OpLoad %6 %8\n"
757 "%34 = OpLoad %16 %33\n"
758 "%35 = OpConvertUToF %15 %34\n"
759 "%37 = OpLoad %16 %36\n"
760 "%38 = OpConvertUToF %15 %37\n"
761 "%40 = OpCompositeConstruct %26 %35 %38 %39 %39\n"
762 "%42 = OpAccessChain %41 %30 %31\n"
763 "OpStore %42 %40\n"
764 "%49 = OpLoad %6 %8\n"
765 "%55 = OpLoad %6 %8\n"
766 "%57 = OpAccessChain %56 %54 %55 %10\n"
767 "%58 = OpLoad %26 %57\n"
768 "%59 = OpAccessChain %41 %48 %49 %10\n"
769 "OpStore %59 %58\n"
770 "OpReturn\n"
771 "OpFunctionEnd\n";
772 programCollection.spirvAsmSources.add("tesc") << controlSource << buildOptionsSpr;
773
774 /*
775 "#extension GL_KHR_shader_subgroup_basic: enable\n"
776 "#extension GL_EXT_tessellation_shader : require\n"
777 "layout(isolines, equal_spacing, ccw ) in;\n"
778 "layout(location = 0) in vec4 in_color[];\n"
779 "layout(location = 0) out vec4 out_color;\n"
780 "\n"
781 "void main (void)\n"
782 "{\n"
783 " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
784 " out_color = in_color[0];\n"
785 "}\n";
786 */
787 const string evaluationSource =
788 "; SPIR-V\n"
789 "; Version: 1.3\n"
790 "; Generator: Khronos Glslang Reference Front End; 2\n"
791 "; Bound: 44\n"
792 "; Schema: 0\n"
793 "OpCapability Tessellation\n"
794 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
795 "OpMemoryModel Logical GLSL450\n"
796 "OpEntryPoint TessellationEvaluation %4 \"main\" %13 %20 %29 %38 %41\n"
797 "OpExecutionMode %4 Isolines\n"
798 "OpExecutionMode %4 SpacingEqual\n"
799 "OpExecutionMode %4 VertexOrderCcw\n"
800 "OpMemberDecorate %11 0 BuiltIn Position\n"
801 "OpMemberDecorate %11 1 BuiltIn PointSize\n"
802 "OpMemberDecorate %11 2 BuiltIn ClipDistance\n"
803 "OpMemberDecorate %11 3 BuiltIn CullDistance\n"
804 "OpDecorate %11 Block\n"
805 "OpMemberDecorate %16 0 BuiltIn Position\n"
806 "OpMemberDecorate %16 1 BuiltIn PointSize\n"
807 "OpMemberDecorate %16 2 BuiltIn ClipDistance\n"
808 "OpMemberDecorate %16 3 BuiltIn CullDistance\n"
809 "OpDecorate %16 Block\n"
810 "OpDecorate %29 BuiltIn TessCoord\n"
811 "OpDecorate %38 Location 0\n"
812 "OpDecorate %41 Location 0\n"
813 "%2 = OpTypeVoid\n"
814 "%3 = OpTypeFunction %2\n"
815 "%6 = OpTypeFloat 32\n"
816 "%7 = OpTypeVector %6 4\n"
817 "%8 = OpTypeInt 32 0\n"
818 "%9 = OpConstant %8 1\n"
819 "%10 = OpTypeArray %6 %9\n"
820 "%11 = OpTypeStruct %7 %6 %10 %10\n"
821 "%12 = OpTypePointer Output %11\n"
822 "%13 = OpVariable %12 Output\n"
823 "%14 = OpTypeInt 32 1\n"
824 "%15 = OpConstant %14 0\n"
825 "%16 = OpTypeStruct %7 %6 %10 %10\n"
826 "%17 = OpConstant %8 32\n"
827 "%18 = OpTypeArray %16 %17\n"
828 "%19 = OpTypePointer Input %18\n"
829 "%20 = OpVariable %19 Input\n"
830 "%21 = OpTypePointer Input %7\n"
831 "%24 = OpConstant %14 1\n"
832 "%27 = OpTypeVector %6 3\n"
833 "%28 = OpTypePointer Input %27\n"
834 "%29 = OpVariable %28 Input\n"
835 "%30 = OpConstant %8 0\n"
836 "%31 = OpTypePointer Input %6\n"
837 "%36 = OpTypePointer Output %7\n"
838 "%38 = OpVariable %36 Output\n"
839 "%39 = OpTypeArray %7 %17\n"
840 "%40 = OpTypePointer Input %39\n"
841 "%41 = OpVariable %40 Input\n"
842 "%4 = OpFunction %2 None %3\n"
843 "%5 = OpLabel\n"
844 "%22 = OpAccessChain %21 %20 %15 %15\n"
845 "%23 = OpLoad %7 %22\n"
846 "%25 = OpAccessChain %21 %20 %24 %15\n"
847 "%26 = OpLoad %7 %25\n"
848 "%32 = OpAccessChain %31 %29 %30\n"
849 "%33 = OpLoad %6 %32\n"
850 "%34 = OpCompositeConstruct %7 %33 %33 %33 %33\n"
851 "%35 = OpExtInst %7 %1 FMix %23 %26 %34\n"
852 "%37 = OpAccessChain %36 %13 %15\n"
853 "OpStore %37 %35\n"
854 "%42 = OpAccessChain %21 %41 %15\n"
855 "%43 = OpLoad %7 %42\n"
856 "OpStore %38 %43\n"
857 "OpReturn\n"
858 "OpFunctionEnd\n";
859 programCollection.spirvAsmSources.add("tese") << evaluationSource << buildOptionsSpr;
860 }
861 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
862 {
863 /*
864 "#version 450\n"
865 "#extension GL_KHR_shader_subgroup_basic: enable\n"
866 "layout(points) in;\n"
867 "layout(points, max_vertices = 1) out;\n"
868 "layout(location = 0) out vec4 out_color;\n"
869 "void main (void)\n"
870 "{\n"
871 " out_color = vec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
872 " gl_Position = gl_in[0].gl_Position;\n"
873 " EmitVertex();\n"
874 " EndPrimitive();\n"
875 "}\n";
876 */
877 const string geometry =
878 "; SPIR-V\n"
879 "; Version: 1.3\n"
880 "; Generator: Khronos Glslang Reference Front End; 2\n"
881 "; Bound: 35\n"
882 "; Schema: 0\n"
883 "OpCapability Geometry\n"
884 "OpCapability GroupNonUniform\n"
885 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
886 "OpMemoryModel Logical GLSL450\n"
887 "OpEntryPoint Geometry %4 \"main\" %9 %12 %15 %24 %30\n"
888 "OpExecutionMode %4 InputPoints\n"
889 "OpExecutionMode %4 Invocations 1\n"
890 "OpExecutionMode %4 OutputPoints\n"
891 "OpExecutionMode %4 OutputVertices 1\n"
892 "OpDecorate %9 Location 0\n"
893 "OpDecorate %12 RelaxedPrecision\n"
894 "OpDecorate %12 BuiltIn SubgroupSize\n"
895 "OpDecorate %13 RelaxedPrecision\n"
896 "OpDecorate %15 RelaxedPrecision\n"
897 "OpDecorate %15 BuiltIn SubgroupLocalInvocationId\n"
898 "OpDecorate %16 RelaxedPrecision\n"
899 "OpMemberDecorate %22 0 BuiltIn Position\n"
900 "OpMemberDecorate %22 1 BuiltIn PointSize\n"
901 "OpMemberDecorate %22 2 BuiltIn ClipDistance\n"
902 "OpMemberDecorate %22 3 BuiltIn CullDistance\n"
903 "OpDecorate %22 Block\n"
904 "OpMemberDecorate %27 0 BuiltIn Position\n"
905 "OpMemberDecorate %27 1 BuiltIn PointSize\n"
906 "OpMemberDecorate %27 2 BuiltIn ClipDistance\n"
907 "OpMemberDecorate %27 3 BuiltIn CullDistance\n"
908 "OpDecorate %27 Block\n"
909 "%2 = OpTypeVoid\n"
910 "%3 = OpTypeFunction %2\n"
911 "%6 = OpTypeFloat 32\n"
912 "%7 = OpTypeVector %6 4\n"
913 "%8 = OpTypePointer Output %7\n"
914 "%9 = OpVariable %8 Output\n"
915 "%10 = OpTypeInt 32 0\n"
916 "%11 = OpTypePointer Input %10\n"
917 "%12 = OpVariable %11 Input\n"
918 "%15 = OpVariable %11 Input\n"
919 "%18 = OpConstant %6 0\n"
920 "%20 = OpConstant %10 1\n"
921 "%21 = OpTypeArray %6 %20\n"
922 "%22 = OpTypeStruct %7 %6 %21 %21\n"
923 "%23 = OpTypePointer Output %22\n"
924 "%24 = OpVariable %23 Output\n"
925 "%25 = OpTypeInt 32 1\n"
926 "%26 = OpConstant %25 0\n"
927 "%27 = OpTypeStruct %7 %6 %21 %21\n"
928 "%28 = OpTypeArray %27 %20\n"
929 "%29 = OpTypePointer Input %28\n"
930 "%30 = OpVariable %29 Input\n"
931 "%31 = OpTypePointer Input %7\n"
932 "%4 = OpFunction %2 None %3\n"
933 "%5 = OpLabel\n"
934 "%13 = OpLoad %10 %12\n"
935 "%14 = OpConvertUToF %6 %13\n"
936 "%16 = OpLoad %10 %15\n"
937 "%17 = OpConvertUToF %6 %16\n"
938 "%19 = OpCompositeConstruct %7 %14 %17 %18 %18\n"
939 "OpStore %9 %19\n"
940 "%32 = OpAccessChain %31 %30 %26 %26\n"
941 "%33 = OpLoad %7 %32\n"
942 "%34 = OpAccessChain %8 %24 %26\n"
943 "OpStore %34 %33\n"
944 "OpEmitVertex\n"
945 "OpEndPrimitive\n"
946 "OpReturn\n"
947 "OpFunctionEnd\n";
948 programCollection.spirvAsmSources.add("geometry") << geometry << buildOptionsSpr;
949 }
950 else
951 {
952 DE_FATAL("Unsupported shader stage");
953 }
954 }
955
initPrograms(SourceCollections & programCollection,CaseDefinition caseDef)956 void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
957 {
958 if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
959 {
960 std::ostringstream src;
961
962 src << "#version 450\n"
963 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
964 << "layout (local_size_x_id = 0, local_size_y_id = 1, "
965 "local_size_z_id = 2) in;\n"
966 << "layout(set = 0, binding = 0, std430) buffer Output\n"
967 << "{\n"
968 << " uvec4 result[];\n"
969 << "};\n"
970 << "\n"
971 << "void main (void)\n"
972 << "{\n"
973 << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
974 << " highp uint offset = globalSize.x * ((globalSize.y * "
975 "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
976 "gl_GlobalInvocationID.x;\n"
977 << " result[offset] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, gl_NumSubgroups, gl_SubgroupID);\n"
978 << "}\n";
979
980 programCollection.glslSources.add("comp")
981 << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
982 }
983 else
984 {
985 {
986 /*
987 "#version 450\n"
988 "#extension GL_KHR_shader_subgroup_basic: enable\n"
989 "layout(set = 0, binding = 0, std430) buffer Output\n"
990 "{\n"
991 " uvec4 result[];\n"
992 "};\n"
993 "\n"
994 "void main (void)\n"
995 "{\n"
996 " result[gl_VertexIndex] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
997 " float pixelSize = 2.0f/1024.0f;\n"
998 " float pixelPosition = pixelSize/2.0f - 1.0f;\n"
999 " gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
1000 " gl_PointSize = 1.0f;\n"
1001 "}\n";
1002 */
1003 const string vertex =
1004 "; SPIR-V\n"
1005 "; Version: 1.3\n"
1006 "; Generator: Khronos Glslang Reference Front End; 1\n"
1007 "; Bound: 52\n"
1008 "; Schema: 0\n"
1009 "OpCapability Shader\n"
1010 "OpCapability GroupNonUniform\n"
1011 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1012 "OpMemoryModel Logical GLSL450\n"
1013 "OpEntryPoint Vertex %4 \"main\" %15 %18 %20 %41\n"
1014 "OpDecorate %8 ArrayStride 16\n"
1015 "OpMemberDecorate %9 0 Offset 0\n"
1016 "OpDecorate %9 BufferBlock\n"
1017 "OpDecorate %11 DescriptorSet 0\n"
1018 "OpDecorate %11 Binding 0\n"
1019 "OpDecorate %15 BuiltIn VertexIndex\n"
1020 "OpDecorate %18 RelaxedPrecision\n"
1021 "OpDecorate %18 BuiltIn SubgroupSize\n"
1022 "OpDecorate %19 RelaxedPrecision\n"
1023 "OpDecorate %20 RelaxedPrecision\n"
1024 "OpDecorate %20 BuiltIn SubgroupLocalInvocationId\n"
1025 "OpDecorate %21 RelaxedPrecision\n"
1026 "OpMemberDecorate %39 0 BuiltIn Position\n"
1027 "OpMemberDecorate %39 1 BuiltIn PointSize\n"
1028 "OpMemberDecorate %39 2 BuiltIn ClipDistance\n"
1029 "OpMemberDecorate %39 3 BuiltIn CullDistance\n"
1030 "OpDecorate %39 Block\n"
1031 "%2 = OpTypeVoid\n"
1032 "%3 = OpTypeFunction %2\n"
1033 "%6 = OpTypeInt 32 0\n"
1034 "%7 = OpTypeVector %6 4\n"
1035 "%8 = OpTypeRuntimeArray %7\n"
1036 "%9 = OpTypeStruct %8\n"
1037 "%10 = OpTypePointer Uniform %9\n"
1038 "%11 = OpVariable %10 Uniform\n"
1039 "%12 = OpTypeInt 32 1\n"
1040 "%13 = OpConstant %12 0\n"
1041 "%14 = OpTypePointer Input %12\n"
1042 "%15 = OpVariable %14 Input\n"
1043 "%17 = OpTypePointer Input %6\n"
1044 "%18 = OpVariable %17 Input\n"
1045 "%20 = OpVariable %17 Input\n"
1046 "%22 = OpConstant %6 0\n"
1047 "%24 = OpTypePointer Uniform %7\n"
1048 "%26 = OpTypeFloat 32\n"
1049 "%27 = OpTypePointer Function %26\n"
1050 "%29 = OpConstant %26 0.00195313\n"
1051 "%32 = OpConstant %26 2\n"
1052 "%34 = OpConstant %26 1\n"
1053 "%36 = OpTypeVector %26 4\n"
1054 "%37 = OpConstant %6 1\n"
1055 "%38 = OpTypeArray %26 %37\n"
1056 "%39 = OpTypeStruct %36 %26 %38 %38\n"
1057 "%40 = OpTypePointer Output %39\n"
1058 "%41 = OpVariable %40 Output\n"
1059 "%48 = OpConstant %26 0\n"
1060 "%50 = OpTypePointer Output %36\n"
1061 "%52 = OpConstant %12 1\n"
1062 "%53 = OpTypePointer Output %26\n"
1063 "%4 = OpFunction %2 None %3\n"
1064 "%5 = OpLabel\n"
1065 "%28 = OpVariable %27 Function\n"
1066 "%30 = OpVariable %27 Function\n"
1067 "%16 = OpLoad %12 %15\n"
1068 "%19 = OpLoad %6 %18\n"
1069 "%21 = OpLoad %6 %20\n"
1070 "%23 = OpCompositeConstruct %7 %19 %21 %22 %22\n"
1071 "%25 = OpAccessChain %24 %11 %13 %16\n"
1072 "OpStore %25 %23\n"
1073 "OpStore %28 %29\n"
1074 "%31 = OpLoad %26 %28\n"
1075 "%33 = OpFDiv %26 %31 %32\n"
1076 "%35 = OpFSub %26 %33 %34\n"
1077 "OpStore %30 %35\n"
1078 "%42 = OpLoad %12 %15\n"
1079 "%43 = OpConvertSToF %26 %42\n"
1080 "%44 = OpLoad %26 %28\n"
1081 "%45 = OpFMul %26 %43 %44\n"
1082 "%46 = OpLoad %26 %30\n"
1083 "%47 = OpFAdd %26 %45 %46\n"
1084 "%49 = OpCompositeConstruct %36 %47 %48 %48 %34\n"
1085 "%51 = OpAccessChain %50 %41 %13\n"
1086 "OpStore %51 %49\n"
1087 "%54 = OpAccessChain %53 %41 %52\n"
1088 "OpStore %54 %34\n"
1089 "OpReturn\n"
1090 "OpFunctionEnd\n";
1091 programCollection.spirvAsmSources.add("vert") << vertex << SpirVAsmBuildOptions(programCollection.usedVulkanVersion, SPIRV_VERSION_1_3);
1092 }
1093
1094 {
1095 /*
1096 "#version 450\n"
1097 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1098 "layout(vertices=1) out;\n"
1099 "layout(set = 0, binding = 1, std430) buffer Output\n"
1100 "{\n"
1101 " uvec4 result[];\n"
1102 "};\n"
1103 "\n"
1104 "void main (void)\n"
1105 "{\n"
1106 " result[gl_PrimitiveID] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
1107 " if (gl_InvocationID == 0)\n"
1108 " {\n"
1109 " gl_TessLevelOuter[0] = 1.0f;\n"
1110 " gl_TessLevelOuter[1] = 1.0f;\n"
1111 " }\n"
1112 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1113 "}\n";
1114 */
1115 const string tesc =
1116 "; SPIR-V\n"
1117 "; Version: 1.3\n"
1118 "; Generator: Khronos Glslang Reference Front End; 1\n"
1119 "; Bound: 61\n"
1120 "; Schema: 0\n"
1121 "OpCapability Tessellation\n"
1122 "OpCapability GroupNonUniform\n"
1123 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1124 "OpMemoryModel Logical GLSL450\n"
1125 "OpEntryPoint TessellationControl %4 \"main\" %15 %18 %20 %26 %36 %48 %54\n"
1126 "OpExecutionMode %4 OutputVertices 1\n"
1127 "OpDecorate %8 ArrayStride 16\n"
1128 "OpMemberDecorate %9 0 Offset 0\n"
1129 "OpDecorate %9 BufferBlock\n"
1130 "OpDecorate %11 DescriptorSet 0\n"
1131 "OpDecorate %11 Binding 1\n"
1132 "OpDecorate %15 BuiltIn PrimitiveId\n"
1133 "OpDecorate %18 RelaxedPrecision\n"
1134 "OpDecorate %18 BuiltIn SubgroupSize\n"
1135 "OpDecorate %19 RelaxedPrecision\n"
1136 "OpDecorate %20 RelaxedPrecision\n"
1137 "OpDecorate %20 BuiltIn SubgroupLocalInvocationId\n"
1138 "OpDecorate %21 RelaxedPrecision\n"
1139 "OpDecorate %26 BuiltIn InvocationId\n"
1140 "OpDecorate %36 Patch\n"
1141 "OpDecorate %36 BuiltIn TessLevelOuter\n"
1142 "OpMemberDecorate %45 0 BuiltIn Position\n"
1143 "OpMemberDecorate %45 1 BuiltIn PointSize\n"
1144 "OpMemberDecorate %45 2 BuiltIn ClipDistance\n"
1145 "OpMemberDecorate %45 3 BuiltIn CullDistance\n"
1146 "OpDecorate %45 Block\n"
1147 "OpMemberDecorate %50 0 BuiltIn Position\n"
1148 "OpMemberDecorate %50 1 BuiltIn PointSize\n"
1149 "OpMemberDecorate %50 2 BuiltIn ClipDistance\n"
1150 "OpMemberDecorate %50 3 BuiltIn CullDistance\n"
1151 "OpDecorate %50 Block\n"
1152 "%2 = OpTypeVoid\n"
1153 "%3 = OpTypeFunction %2\n"
1154 "%6 = OpTypeInt 32 0\n"
1155 "%7 = OpTypeVector %6 4\n"
1156 "%8 = OpTypeRuntimeArray %7\n"
1157 "%9 = OpTypeStruct %8\n"
1158 "%10 = OpTypePointer Uniform %9\n"
1159 "%11 = OpVariable %10 Uniform\n"
1160 "%12 = OpTypeInt 32 1\n"
1161 "%13 = OpConstant %12 0\n"
1162 "%14 = OpTypePointer Input %12\n"
1163 "%15 = OpVariable %14 Input\n"
1164 "%17 = OpTypePointer Input %6\n"
1165 "%18 = OpVariable %17 Input\n"
1166 "%20 = OpVariable %17 Input\n"
1167 "%22 = OpConstant %6 0\n"
1168 "%24 = OpTypePointer Uniform %7\n"
1169 "%26 = OpVariable %14 Input\n"
1170 "%28 = OpTypeBool\n"
1171 "%32 = OpTypeFloat 32\n"
1172 "%33 = OpConstant %6 4\n"
1173 "%34 = OpTypeArray %32 %33\n"
1174 "%35 = OpTypePointer Output %34\n"
1175 "%36 = OpVariable %35 Output\n"
1176 "%37 = OpConstant %32 1\n"
1177 "%38 = OpTypePointer Output %32\n"
1178 "%40 = OpConstant %12 1\n"
1179 "%42 = OpTypeVector %32 4\n"
1180 "%43 = OpConstant %6 1\n"
1181 "%44 = OpTypeArray %32 %43\n"
1182 "%45 = OpTypeStruct %42 %32 %44 %44\n"
1183 "%46 = OpTypeArray %45 %43\n"
1184 "%47 = OpTypePointer Output %46\n"
1185 "%48 = OpVariable %47 Output\n"
1186 "%50 = OpTypeStruct %42 %32 %44 %44\n"
1187 "%51 = OpConstant %6 32\n"
1188 "%52 = OpTypeArray %50 %51\n"
1189 "%53 = OpTypePointer Input %52\n"
1190 "%54 = OpVariable %53 Input\n"
1191 "%56 = OpTypePointer Input %42\n"
1192 "%59 = OpTypePointer Output %42\n"
1193 "%4 = OpFunction %2 None %3\n"
1194 "%5 = OpLabel\n"
1195 "%16 = OpLoad %12 %15\n"
1196 "%19 = OpLoad %6 %18\n"
1197 "%21 = OpLoad %6 %20\n"
1198 "%23 = OpCompositeConstruct %7 %19 %21 %22 %22\n"
1199 "%25 = OpAccessChain %24 %11 %13 %16\n"
1200 "OpStore %25 %23\n"
1201 "%27 = OpLoad %12 %26\n"
1202 "%29 = OpIEqual %28 %27 %13\n"
1203 "OpSelectionMerge %31 None\n"
1204 "OpBranchConditional %29 %30 %31\n"
1205 "%30 = OpLabel\n"
1206 "%39 = OpAccessChain %38 %36 %13\n"
1207 "OpStore %39 %37\n"
1208 "%41 = OpAccessChain %38 %36 %40\n"
1209 "OpStore %41 %37\n"
1210 "OpBranch %31\n"
1211 "%31 = OpLabel\n"
1212 "%49 = OpLoad %12 %26\n"
1213 "%55 = OpLoad %12 %26\n"
1214 "%57 = OpAccessChain %56 %54 %55 %13\n"
1215 "%58 = OpLoad %42 %57\n"
1216 "%60 = OpAccessChain %59 %48 %49 %13\n"
1217 "OpStore %60 %58\n"
1218 "OpReturn\n"
1219 "OpFunctionEnd\n";
1220 programCollection.spirvAsmSources.add("tesc") << tesc << SpirVAsmBuildOptions(programCollection.usedVulkanVersion, SPIRV_VERSION_1_3);
1221 }
1222
1223 {
1224 /*
1225 "#version 450\n"
1226 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1227 "layout(isolines) in;\n"
1228 "layout(set = 0, binding = 2, std430) buffer Output\n"
1229 "{\n"
1230 " uvec4 result[];\n"
1231 "};\n"
1232 "\n"
1233 "void main (void)\n"
1234 "{\n"
1235 " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
1236 " float pixelSize = 2.0f/1024.0f;\n"
1237 " gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
1238 "}\n";
1239 */
1240 const string tese =
1241 "; SPIR - V\n"
1242 "; Version: 1.3\n"
1243 "; Generator: Khronos Glslang Reference Front End; 2\n"
1244 "; Bound: 67\n"
1245 "; Schema: 0\n"
1246 "OpCapability Tessellation\n"
1247 "OpCapability GroupNonUniform\n"
1248 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1249 "OpMemoryModel Logical GLSL450\n"
1250 "OpEntryPoint TessellationEvaluation %4 \"main\" %15 %23 %33 %35 %48 %53\n"
1251 "OpExecutionMode %4 Isolines\n"
1252 "OpExecutionMode %4 SpacingEqual\n"
1253 "OpExecutionMode %4 VertexOrderCcw\n"
1254 "OpDecorate %8 ArrayStride 16\n"
1255 "OpMemberDecorate %9 0 Offset 0\n"
1256 "OpDecorate %9 BufferBlock\n"
1257 "OpDecorate %11 DescriptorSet 0\n"
1258 "OpDecorate %11 Binding 2\n"
1259 "OpDecorate %15 BuiltIn PrimitiveId\n"
1260 "OpDecorate %23 BuiltIn TessCoord\n"
1261 "OpDecorate %33 RelaxedPrecision\n"
1262 "OpDecorate %33 BuiltIn SubgroupSize\n"
1263 "OpDecorate %34 RelaxedPrecision\n"
1264 "OpDecorate %35 RelaxedPrecision\n"
1265 "OpDecorate %35 BuiltIn SubgroupLocalInvocationId\n"
1266 "OpDecorate %36 RelaxedPrecision\n"
1267 "OpMemberDecorate %46 0 BuiltIn Position\n"
1268 "OpMemberDecorate %46 1 BuiltIn PointSize\n"
1269 "OpMemberDecorate %46 2 BuiltIn ClipDistance\n"
1270 "OpMemberDecorate %46 3 BuiltIn CullDistance\n"
1271 "OpDecorate %46 Block\n"
1272 "OpMemberDecorate %49 0 BuiltIn Position\n"
1273 "OpMemberDecorate %49 1 BuiltIn PointSize\n"
1274 "OpMemberDecorate %49 2 BuiltIn ClipDistance\n"
1275 "OpMemberDecorate %49 3 BuiltIn CullDistance\n"
1276 "OpDecorate %49 Block\n"
1277 "%2 = OpTypeVoid\n"
1278 "%3 = OpTypeFunction %2\n"
1279 "%6 = OpTypeInt 32 0\n"
1280 "%7 = OpTypeVector %6 4\n"
1281 "%8 = OpTypeRuntimeArray %7\n"
1282 "%9 = OpTypeStruct %8\n"
1283 "%10 = OpTypePointer Uniform %9\n"
1284 "%11 = OpVariable %10 Uniform\n"
1285 "%12 = OpTypeInt 32 1\n"
1286 "%13 = OpConstant %12 0\n"
1287 "%14 = OpTypePointer Input %12\n"
1288 "%15 = OpVariable %14 Input\n"
1289 "%17 = OpConstant %12 2\n"
1290 "%20 = OpTypeFloat 32\n"
1291 "%21 = OpTypeVector %20 3\n"
1292 "%22 = OpTypePointer Input %21\n"
1293 "%23 = OpVariable %22 Input\n"
1294 "%24 = OpConstant %6 0\n"
1295 "%25 = OpTypePointer Input %20\n"
1296 "%28 = OpConstant %20 0.5\n"
1297 "%32 = OpTypePointer Input %6\n"
1298 "%33 = OpVariable %32 Input\n"
1299 "%35 = OpVariable %32 Input\n"
1300 "%38 = OpTypePointer Uniform %7\n"
1301 "%40 = OpTypePointer Function %20\n"
1302 "%42 = OpConstant %20 0.00195313\n"
1303 "%43 = OpTypeVector %20 4\n"
1304 "%44 = OpConstant %6 1\n"
1305 "%45 = OpTypeArray %20 %44\n"
1306 "%46 = OpTypeStruct %43 %20 %45 %45\n"
1307 "%47 = OpTypePointer Output %46\n"
1308 "%48 = OpVariable %47 Output\n"
1309 "%49 = OpTypeStruct %43 %20 %45 %45\n"
1310 "%50 = OpConstant %6 32\n"
1311 "%51 = OpTypeArray %49 %50\n"
1312 "%52 = OpTypePointer Input %51\n"
1313 "%53 = OpVariable %52 Input\n"
1314 "%54 = OpTypePointer Input %43\n"
1315 "%61 = OpConstant %20 2\n"
1316 "%65 = OpTypePointer Output %43\n"
1317 "%4 = OpFunction %2 None %3\n"
1318 "%5 = OpLabel\n"
1319 "%41 = OpVariable %40 Function\n"
1320 "%16 = OpLoad %12 %15\n"
1321 "%18 = OpIMul %12 %16 %17\n"
1322 "%19 = OpBitcast %6 %18\n"
1323 "%26 = OpAccessChain %25 %23 %24\n"
1324 "%27 = OpLoad %20 %26\n"
1325 "%29 = OpFAdd %20 %27 %28\n"
1326 "%30 = OpConvertFToU %6 %29\n"
1327 "%31 = OpIAdd %6 %19 %30\n"
1328 "%34 = OpLoad %6 %33\n"
1329 "%36 = OpLoad %6 %35\n"
1330 "%37 = OpCompositeConstruct %7 %34 %36 %24 %24\n"
1331 "%39 = OpAccessChain %38 %11 %13 %31\n"
1332 "OpStore %39 %37\n"
1333 "OpStore %41 %42\n"
1334 "%55 = OpAccessChain %54 %53 %13 %13\n"
1335 "%56 = OpLoad %43 %55\n"
1336 "%57 = OpAccessChain %25 %23 %24\n"
1337 "%58 = OpLoad %20 %57\n"
1338 "%59 = OpLoad %20 %41\n"
1339 "%60 = OpFMul %20 %58 %59\n"
1340 "%62 = OpFDiv %20 %60 %61\n"
1341 "%63 = OpCompositeConstruct %43 %62 %62 %62 %62\n"
1342 "%64 = OpFAdd %43 %56 %63\n"
1343 "%66 = OpAccessChain %65 %48 %13\n"
1344 "OpStore %66 %64\n"
1345 "OpReturn\n"
1346 "OpFunctionEnd\n";
1347 programCollection.spirvAsmSources.add("tese") << tese << SpirVAsmBuildOptions(programCollection.usedVulkanVersion, SPIRV_VERSION_1_3);
1348 }
1349
1350 {
1351 /*
1352 "#version 450\n"
1353 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1354 "// Note: ${TOPOLOGY} variable is substituted manually at SPIR-V ASM level"
1355 "layout(${TOPOLOGY}) in;\n"
1356 "layout(points, max_vertices = 1) out;\n"
1357 "layout(set = 0, binding = 3, std430) buffer Output\n"
1358 "{\n"
1359 " uvec4 result[];\n"
1360 "};\n"
1361 "\n"
1362 "void main (void)\n"
1363 "{\n"
1364 " result[gl_PrimitiveIDIn] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
1365 " gl_Position = gl_in[0].gl_Position;\n"
1366 " EmitVertex();\n"
1367 " EndPrimitive();\n"
1368 "}\n";
1369 */
1370 const string geometry =
1371 "; SPIR-V\n"
1372 "; Version: 1.3\n"
1373 "; Generator: Khronos Glslang Reference Front End; 1\n"
1374 "; Bound: 42\n"
1375 "; Schema: 0\n"
1376 "OpCapability Geometry\n"
1377 "OpCapability GroupNonUniform\n"
1378 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1379 "OpMemoryModel Logical GLSL450\n"
1380 "OpEntryPoint Geometry %4 \"main\" %15 %18 %20 %32 %36\n"
1381 "OpExecutionMode %4 ${TOPOLOGY}\n"
1382 "OpExecutionMode %4 Invocations 1\n"
1383 "OpExecutionMode %4 OutputPoints\n"
1384 "OpExecutionMode %4 OutputVertices 1\n"
1385 "OpDecorate %8 ArrayStride 16\n"
1386 "OpMemberDecorate %9 0 Offset 0\n"
1387 "OpDecorate %9 BufferBlock\n"
1388 "OpDecorate %11 DescriptorSet 0\n"
1389 "OpDecorate %11 Binding 3\n"
1390 "OpDecorate %15 BuiltIn PrimitiveId\n"
1391 "OpDecorate %18 RelaxedPrecision\n"
1392 "OpDecorate %18 BuiltIn SubgroupSize\n"
1393 "OpDecorate %19 RelaxedPrecision\n"
1394 "OpDecorate %20 RelaxedPrecision\n"
1395 "OpDecorate %20 BuiltIn SubgroupLocalInvocationId\n"
1396 "OpDecorate %21 RelaxedPrecision\n"
1397 "OpMemberDecorate %30 0 BuiltIn Position\n"
1398 "OpMemberDecorate %30 1 BuiltIn PointSize\n"
1399 "OpMemberDecorate %30 2 BuiltIn ClipDistance\n"
1400 "OpMemberDecorate %30 3 BuiltIn CullDistance\n"
1401 "OpDecorate %30 Block\n"
1402 "OpMemberDecorate %33 0 BuiltIn Position\n"
1403 "OpMemberDecorate %33 1 BuiltIn PointSize\n"
1404 "OpMemberDecorate %33 2 BuiltIn ClipDistance\n"
1405 "OpMemberDecorate %33 3 BuiltIn CullDistance\n"
1406 "OpDecorate %33 Block\n"
1407 "%2 = OpTypeVoid\n"
1408 "%3 = OpTypeFunction %2\n"
1409 "%6 = OpTypeInt 32 0\n"
1410 "%7 = OpTypeVector %6 4\n"
1411 "%8 = OpTypeRuntimeArray %7\n"
1412 "%9 = OpTypeStruct %8\n"
1413 "%10 = OpTypePointer Uniform %9\n"
1414 "%11 = OpVariable %10 Uniform\n"
1415 "%12 = OpTypeInt 32 1\n"
1416 "%13 = OpConstant %12 0\n"
1417 "%14 = OpTypePointer Input %12\n"
1418 "%15 = OpVariable %14 Input\n"
1419 "%17 = OpTypePointer Input %6\n"
1420 "%18 = OpVariable %17 Input\n"
1421 "%20 = OpVariable %17 Input\n"
1422 "%22 = OpConstant %6 0\n"
1423 "%24 = OpTypePointer Uniform %7\n"
1424 "%26 = OpTypeFloat 32\n"
1425 "%27 = OpTypeVector %26 4\n"
1426 "%28 = OpConstant %6 1\n"
1427 "%29 = OpTypeArray %26 %28\n"
1428 "%30 = OpTypeStruct %27 %26 %29 %29\n"
1429 "%31 = OpTypePointer Output %30\n"
1430 "%32 = OpVariable %31 Output\n"
1431 "%33 = OpTypeStruct %27 %26 %29 %29\n"
1432 "%34 = OpTypeArray %33 %28\n"
1433 "%35 = OpTypePointer Input %34\n"
1434 "%36 = OpVariable %35 Input\n"
1435 "%37 = OpTypePointer Input %27\n"
1436 "%40 = OpTypePointer Output %27\n"
1437 "%4 = OpFunction %2 None %3\n"
1438 "%5 = OpLabel\n"
1439 "%16 = OpLoad %12 %15\n"
1440 "%19 = OpLoad %6 %18\n"
1441 "%21 = OpLoad %6 %20\n"
1442 "%23 = OpCompositeConstruct %7 %19 %21 %22 %22\n"
1443 "%25 = OpAccessChain %24 %11 %13 %16\n"
1444 "OpStore %25 %23\n"
1445 "%38 = OpAccessChain %37 %36 %13 %13\n"
1446 "%39 = OpLoad %27 %38\n"
1447 "%41 = OpAccessChain %40 %32 %13\n"
1448 "OpStore %41 %39\n"
1449 "OpEmitVertex\n"
1450 "OpEndPrimitive\n"
1451 "OpReturn\n"
1452 "OpFunctionEnd\n";
1453 addGeometryShadersFromTemplate(geometry, SpirVAsmBuildOptions(programCollection.usedVulkanVersion, SPIRV_VERSION_1_3), programCollection.spirvAsmSources);
1454 }
1455
1456 {
1457 /*
1458 "#version 450\n"
1459 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1460 "layout(location = 0) out uvec4 data;\n"
1461 "void main (void)\n"
1462 "{\n"
1463 " data = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
1464 "}\n";
1465 */
1466 const string fragment =
1467 "; SPIR-V\n"
1468 "; Version: 1.3\n"
1469 "; Generator: Khronos Glslang Reference Front End; 1\n"
1470 "; Bound: 17\n"
1471 "; Schema: 0\n"
1472 "OpCapability Shader\n"
1473 "OpCapability GroupNonUniform\n"
1474 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1475 "OpMemoryModel Logical GLSL450\n"
1476 "OpEntryPoint Fragment %4 \"main\" %9 %11 %13\n"
1477 "OpExecutionMode %4 OriginUpperLeft\n"
1478 "OpDecorate %9 Location 0\n"
1479 "OpDecorate %11 RelaxedPrecision\n"
1480 "OpDecorate %11 Flat\n"
1481 "OpDecorate %11 BuiltIn SubgroupSize\n"
1482 "OpDecorate %12 RelaxedPrecision\n"
1483 "OpDecorate %13 RelaxedPrecision\n"
1484 "OpDecorate %13 Flat\n"
1485 "OpDecorate %13 BuiltIn SubgroupLocalInvocationId\n"
1486 "OpDecorate %14 RelaxedPrecision\n"
1487 "%2 = OpTypeVoid\n"
1488 "%3 = OpTypeFunction %2\n"
1489 "%6 = OpTypeInt 32 0\n"
1490 "%7 = OpTypeVector %6 4\n"
1491 "%8 = OpTypePointer Output %7\n"
1492 "%9 = OpVariable %8 Output\n"
1493 "%10 = OpTypePointer Input %6\n"
1494 "%11 = OpVariable %10 Input\n"
1495 "%13 = OpVariable %10 Input\n"
1496 "%15 = OpConstant %6 0\n"
1497 "%4 = OpFunction %2 None %3\n"
1498 "%5 = OpLabel\n"
1499 "%12 = OpLoad %6 %11\n"
1500 "%14 = OpLoad %6 %13\n"
1501 "%16 = OpCompositeConstruct %7 %12 %14 %15 %15\n"
1502 "OpStore %9 %16\n"
1503 "OpReturn\n"
1504 "OpFunctionEnd\n";
1505
1506 programCollection.spirvAsmSources.add("fragment") << fragment << SpirVAsmBuildOptions(programCollection.usedVulkanVersion, SPIRV_VERSION_1_3);
1507 }
1508
1509 subgroups::addNoSubgroupShader(programCollection);
1510 }
1511 }
1512
supportedCheck(Context & context,CaseDefinition caseDef)1513 void supportedCheck (Context& context, CaseDefinition caseDef)
1514 {
1515 DE_UNREF(caseDef);
1516 if (!subgroups::isSubgroupSupported(context))
1517 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
1518 }
1519
noSSBOtest(Context & context,const CaseDefinition caseDef)1520 tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
1521 {
1522 if (!areSubgroupOperationsSupportedForStage(
1523 context, caseDef.shaderStage))
1524 {
1525 if (areSubgroupOperationsRequiredForStage(caseDef.shaderStage))
1526 {
1527 return tcu::TestStatus::fail(
1528 "Shader stage " + getShaderStageName(caseDef.shaderStage) +
1529 " is required to support subgroup operations!");
1530 }
1531 else
1532 {
1533 TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
1534 }
1535 }
1536
1537 if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
1538 {
1539 if ("gl_SubgroupSize" == caseDef.varName)
1540 {
1541 return makeVertexFrameBufferTest(
1542 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
1543 }
1544 else if ("gl_SubgroupInvocationID" == caseDef.varName)
1545 {
1546 return makeVertexFrameBufferTest(
1547 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
1548 }
1549 else
1550 {
1551 return tcu::TestStatus::fail(
1552 caseDef.varName + " failed (unhandled error checking case " +
1553 caseDef.varName + ")!");
1554 }
1555 }
1556 else if ((VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) & caseDef.shaderStage )
1557 {
1558 if ("gl_SubgroupSize" == caseDef.varName)
1559 {
1560 return makeTessellationEvaluationFrameBufferTest(
1561 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
1562 }
1563 else if ("gl_SubgroupInvocationID" == caseDef.varName)
1564 {
1565 return makeTessellationEvaluationFrameBufferTest(
1566 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
1567 }
1568 else
1569 {
1570 return tcu::TestStatus::fail(
1571 caseDef.varName + " failed (unhandled error checking case " +
1572 caseDef.varName + ")!");
1573 }
1574 }
1575 else if (VK_SHADER_STAGE_GEOMETRY_BIT & caseDef.shaderStage )
1576 {
1577 if ("gl_SubgroupSize" == caseDef.varName)
1578 {
1579 return makeGeometryFrameBufferTest(
1580 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
1581 }
1582 else if ("gl_SubgroupInvocationID" == caseDef.varName)
1583 {
1584 return makeGeometryFrameBufferTest(
1585 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
1586 }
1587 else
1588 {
1589 return tcu::TestStatus::fail(
1590 caseDef.varName + " failed (unhandled error checking case " +
1591 caseDef.varName + ")!");
1592 }
1593 }
1594 else
1595 {
1596 TCU_THROW(InternalError, "Unhandled shader stage");
1597 }
1598 }
1599
1600
test(Context & context,const CaseDefinition caseDef)1601 tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
1602 {
1603 if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
1604 {
1605 if (!areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
1606 {
1607 return tcu::TestStatus::fail(
1608 "Shader stage " + getShaderStageName(caseDef.shaderStage) +
1609 " is required to support subgroup operations!");
1610 }
1611
1612 if ("gl_SubgroupSize" == caseDef.varName)
1613 {
1614 return makeComputeTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeSubgroupSize);
1615 }
1616 else if ("gl_SubgroupInvocationID" == caseDef.varName)
1617 {
1618 return makeComputeTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeSubgroupInvocationID);
1619 }
1620 else if ("gl_NumSubgroups" == caseDef.varName)
1621 {
1622 return makeComputeTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeNumSubgroups);
1623 }
1624 else if ("gl_SubgroupID" == caseDef.varName)
1625 {
1626 return makeComputeTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeSubgroupID);
1627 }
1628 else
1629 {
1630 return tcu::TestStatus::fail(
1631 caseDef.varName + " failed (unhandled error checking case " +
1632 caseDef.varName + ")!");
1633 }
1634 }
1635 else
1636 {
1637 VkPhysicalDeviceSubgroupProperties subgroupProperties;
1638 subgroupProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
1639 subgroupProperties.pNext = DE_NULL;
1640
1641 VkPhysicalDeviceProperties2 properties;
1642 properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1643 properties.pNext = &subgroupProperties;
1644
1645 context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties);
1646
1647 VkShaderStageFlagBits stages = (VkShaderStageFlagBits)(caseDef.shaderStage & subgroupProperties.supportedStages);
1648
1649 if (VK_SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context))
1650 {
1651 if ( (stages & VK_SHADER_STAGE_FRAGMENT_BIT) == 0)
1652 TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
1653 else
1654 stages = VK_SHADER_STAGE_FRAGMENT_BIT;
1655 }
1656
1657 if ((VkShaderStageFlagBits)0u == stages)
1658 TCU_THROW(NotSupportedError, "Subgroup operations are not supported for any graphic shader");
1659
1660 if ("gl_SubgroupSize" == caseDef.varName)
1661 {
1662 return subgroups::allStages(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize, stages);
1663 }
1664 else if ("gl_SubgroupInvocationID" == caseDef.varName)
1665 {
1666 return subgroups::allStages(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID, stages);
1667 }
1668 else
1669 {
1670 return tcu::TestStatus::fail(
1671 caseDef.varName + " failed (unhandled error checking case " +
1672 caseDef.varName + ")!");
1673 }
1674 }
1675 }
1676
createSubgroupsBuiltinVarTests(tcu::TestContext & testCtx)1677 tcu::TestCaseGroup* createSubgroupsBuiltinVarTests(tcu::TestContext& testCtx)
1678 {
1679 de::MovePtr<tcu::TestCaseGroup> graphicGroup(new tcu::TestCaseGroup(
1680 testCtx, "graphics", "Subgroup builtin variable tests: graphics"));
1681 de::MovePtr<tcu::TestCaseGroup> computeGroup(new tcu::TestCaseGroup(
1682 testCtx, "compute", "Subgroup builtin variable tests: compute"));
1683 de::MovePtr<tcu::TestCaseGroup> framebufferGroup(new tcu::TestCaseGroup(
1684 testCtx, "framebuffer", "Subgroup builtin variable tests: framebuffer"));
1685
1686 const char* const all_stages_vars[] =
1687 {
1688 "SubgroupSize",
1689 "SubgroupInvocationID"
1690 };
1691
1692 const char* const compute_only_vars[] =
1693 {
1694 "NumSubgroups",
1695 "SubgroupID"
1696 };
1697
1698 const VkShaderStageFlags stages[] =
1699 {
1700 VK_SHADER_STAGE_VERTEX_BIT,
1701 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1702 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1703 VK_SHADER_STAGE_GEOMETRY_BIT,
1704 };
1705
1706 for (int a = 0; a < DE_LENGTH_OF_ARRAY(all_stages_vars); ++a)
1707 {
1708 const std::string var = all_stages_vars[a];
1709 const std::string varLower = de::toLower(var);
1710
1711 {
1712 const CaseDefinition caseDef = { "gl_" + var, VK_SHADER_STAGE_ALL_GRAPHICS};
1713
1714 addFunctionCaseWithPrograms(graphicGroup.get(),
1715 varLower, "",
1716 supportedCheck, initPrograms, test, caseDef);
1717 }
1718
1719 {
1720 const CaseDefinition caseDef = {"gl_" + var, VK_SHADER_STAGE_COMPUTE_BIT};
1721 addFunctionCaseWithPrograms(computeGroup.get(),
1722 varLower + "_" + getShaderStageName(caseDef.shaderStage), "",
1723 supportedCheck, initPrograms, test, caseDef);
1724 }
1725
1726 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
1727 {
1728 const CaseDefinition caseDef = {"gl_" + var, stages[stageIndex]};
1729 addFunctionCaseWithPrograms(framebufferGroup.get(),
1730 varLower + "_" + getShaderStageName(caseDef.shaderStage), "",
1731 supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
1732 }
1733 }
1734
1735 for (int a = 0; a < DE_LENGTH_OF_ARRAY(compute_only_vars); ++a)
1736 {
1737 const std::string var = compute_only_vars[a];
1738
1739 const CaseDefinition caseDef = {"gl_" + var, VK_SHADER_STAGE_COMPUTE_BIT};
1740
1741 addFunctionCaseWithPrograms(computeGroup.get(), de::toLower(var), "",
1742 supportedCheck, initPrograms, test, caseDef);
1743 }
1744
1745 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(
1746 testCtx, "builtin_var", "Subgroup builtin variable tests"));
1747
1748 group->addChild(graphicGroup.release());
1749 group->addChild(computeGroup.release());
1750 group->addChild(framebufferGroup.release());
1751
1752 return group.release();
1753 }
1754
1755 } // subgroups
1756 } // vkt
1757