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