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
1021 #ifndef CTS_USES_VULKANSC
getPerStageHeadDeclarations(const CaseDefinition & caseDef)1022 vector<string> getPerStageHeadDeclarations (const CaseDefinition& caseDef)
1023 {
1024 const deUint32 stageCount = subgroups::getStagesCount(caseDef.shaderStage);
1025 vector<string> result (stageCount, string());
1026
1027 for (size_t i = 0; i < result.size(); ++i)
1028 {
1029 result[i] =
1030 "layout(set = 0, binding = " + de::toString(i) + ", std430) buffer Buffer1\n"
1031 "{\n"
1032 " uvec4 result[];\n"
1033 "};\n";
1034 }
1035
1036 return result;
1037 }
1038 #endif // CTS_USES_VULKANSC
1039
initPrograms(SourceCollections & programCollection,CaseDefinition caseDef)1040 void initPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
1041 {
1042 if (isAllComputeStages(caseDef.shaderStage))
1043 {
1044 const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, SPIRV_VERSION_1_3, 0u);
1045
1046 ostringstream src;
1047
1048 src << "#version 450\n"
1049 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1050 << "layout (local_size_x_id = 0, local_size_y_id = 1, "
1051 "local_size_z_id = 2) in;\n"
1052 << "layout(set = 0, binding = 0, std430) buffer Output\n"
1053 << "{\n"
1054 << " uvec4 result[];\n"
1055 << "};\n"
1056 << "\n"
1057 << "void main (void)\n"
1058 << "{\n"
1059 << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
1060 << " highp uint offset = globalSize.x * ((globalSize.y * "
1061 "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
1062 "gl_GlobalInvocationID.x;\n"
1063 << " result[offset] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, gl_NumSubgroups, gl_SubgroupID);\n"
1064 << "}\n";
1065
1066 programCollection.glslSources.add("comp") << glu::ComputeSource(src.str()) << buildOptions;
1067 }
1068 #ifndef CTS_USES_VULKANSC
1069 else if (isAllMeshShadingStages(caseDef.shaderStage))
1070 {
1071 const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, SPIRV_VERSION_1_4, 0u, true);
1072 const string extHeader = "#extension GL_KHR_shader_subgroup_basic : require\n";
1073 const string tempRes = " uvec4 tempRes;\n";
1074 const string testSrc = " tempRes = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, gl_NumSubgroups, gl_SubgroupID);\n";
1075 const vector<string> headDeclarations = getPerStageHeadDeclarations(caseDef);
1076
1077 subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, VK_FORMAT_R32G32B32A32_UINT, false, extHeader, testSrc, "", headDeclarations, false, tempRes);
1078 }
1079 #endif // CTS_USES_VULKANSC
1080 else if (isAllGraphicsStages(caseDef.shaderStage))
1081 {
1082 const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, SPIRV_VERSION_1_3, 0u);
1083 const SpirVAsmBuildOptions buildOptionsSpr (programCollection.usedVulkanVersion, SPIRV_VERSION_1_3);
1084
1085 {
1086 /*
1087 "#version 450\n"
1088 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1089 "layout(set = 0, binding = 0, std430) buffer Output\n"
1090 "{\n"
1091 " uvec4 result[];\n"
1092 "};\n"
1093 "\n"
1094 "void main (void)\n"
1095 "{\n"
1096 " result[gl_VertexIndex] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID + 1024, 0, 0);\n"
1097 " float pixelSize = 2.0f/1024.0f;\n"
1098 " float pixelPosition = pixelSize/2.0f - 1.0f;\n"
1099 " gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
1100 " gl_PointSize = 1.0f;\n"
1101 "}\n";
1102 */
1103 const string vertex =
1104 "; SPIR-V\n"
1105 "; Version: 1.3\n"
1106 "; Generator: Khronos Glslang Reference Front End; 1\n"
1107 "; Bound: 52\n"
1108 "; Schema: 0\n"
1109 "OpCapability Shader\n"
1110 "OpCapability GroupNonUniform\n"
1111 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1112 "OpMemoryModel Logical GLSL450\n"
1113 "OpEntryPoint Vertex %4 \"main\" %15 %18 %20 %41\n"
1114 "OpDecorate %8 ArrayStride 16\n"
1115 "OpMemberDecorate %9 0 Offset 0\n"
1116 "OpDecorate %9 BufferBlock\n"
1117 "OpDecorate %11 DescriptorSet 0\n"
1118 "OpDecorate %11 Binding 0\n"
1119 "OpDecorate %15 BuiltIn VertexIndex\n"
1120 "OpDecorate %18 RelaxedPrecision\n"
1121 "OpDecorate %18 BuiltIn SubgroupSize\n"
1122 "OpDecorate %19 RelaxedPrecision\n"
1123 "OpDecorate %20 RelaxedPrecision\n"
1124 "OpDecorate %20 BuiltIn SubgroupLocalInvocationId\n"
1125 "OpDecorate %21 RelaxedPrecision\n"
1126 "OpMemberDecorate %39 0 BuiltIn Position\n"
1127 "OpMemberDecorate %39 1 BuiltIn PointSize\n"
1128 "OpMemberDecorate %39 2 BuiltIn ClipDistance\n"
1129 "OpMemberDecorate %39 3 BuiltIn CullDistance\n"
1130 "OpDecorate %39 Block\n"
1131 "%2 = OpTypeVoid\n"
1132 "%3 = OpTypeFunction %2\n"
1133 "%6 = OpTypeInt 32 0\n"
1134 "%7 = OpTypeVector %6 4\n"
1135 "%8 = OpTypeRuntimeArray %7\n"
1136 "%9 = OpTypeStruct %8\n"
1137 "%10 = OpTypePointer Uniform %9\n"
1138 "%11 = OpVariable %10 Uniform\n"
1139 "%12 = OpTypeInt 32 1\n"
1140 "%13 = OpConstant %12 0\n"
1141 "%14 = OpTypePointer Input %12\n"
1142 "%15 = OpVariable %14 Input\n"
1143 "%17 = OpTypePointer Input %6\n"
1144 "%18 = OpVariable %17 Input\n"
1145 "%20 = OpVariable %17 Input\n"
1146 "%22 = OpConstant %6 0\n"
1147 "%24 = OpTypePointer Uniform %7\n"
1148 "%26 = OpTypeFloat 32\n"
1149 "%27 = OpTypePointer Function %26\n"
1150 "%29 = OpConstant %26 0.00195313\n"
1151 "%32 = OpConstant %26 2\n"
1152 "%34 = OpConstant %26 1\n"
1153 "%36 = OpTypeVector %26 4\n"
1154 "%37 = OpConstant %6 1\n"
1155 "%38 = OpTypeArray %26 %37\n"
1156 "%39 = OpTypeStruct %36 %26 %38 %38\n"
1157 "%40 = OpTypePointer Output %39\n"
1158 "%41 = OpVariable %40 Output\n"
1159 "%48 = OpConstant %26 0\n"
1160 "%50 = OpTypePointer Output %36\n"
1161 "%52 = OpConstant %12 1\n"
1162 "%99 = OpConstant %6 1024\n"
1163 "%53 = OpTypePointer Output %26\n"
1164 "%4 = OpFunction %2 None %3\n"
1165 "%5 = OpLabel\n"
1166 "%28 = OpVariable %27 Function\n"
1167 "%30 = OpVariable %27 Function\n"
1168 "%16 = OpLoad %12 %15\n"
1169 "%19 = OpLoad %6 %18\n"
1170 "%98 = OpLoad %6 %20\n"
1171 "%21 = OpIAdd %6 %98 %99\n"
1172 "%23 = OpCompositeConstruct %7 %19 %21 %22 %22\n"
1173 "%25 = OpAccessChain %24 %11 %13 %16\n"
1174 "OpStore %25 %23\n"
1175 "OpStore %28 %29\n"
1176 "%31 = OpLoad %26 %28\n"
1177 "%33 = OpFDiv %26 %31 %32\n"
1178 "%35 = OpFSub %26 %33 %34\n"
1179 "OpStore %30 %35\n"
1180 "%42 = OpLoad %12 %15\n"
1181 "%43 = OpConvertSToF %26 %42\n"
1182 "%44 = OpLoad %26 %28\n"
1183 "%45 = OpFMul %26 %43 %44\n"
1184 "%46 = OpLoad %26 %30\n"
1185 "%47 = OpFAdd %26 %45 %46\n"
1186 "%49 = OpCompositeConstruct %36 %47 %48 %48 %34\n"
1187 "%51 = OpAccessChain %50 %41 %13\n"
1188 "OpStore %51 %49\n"
1189 "%54 = OpAccessChain %53 %41 %52\n"
1190 "OpStore %54 %34\n"
1191 "OpReturn\n"
1192 "OpFunctionEnd\n";
1193 programCollection.spirvAsmSources.add("vert") << vertex << buildOptionsSpr;
1194 }
1195
1196 {
1197 /*
1198 "#version 450\n"
1199 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1200 "layout(vertices=1) out;\n"
1201 "layout(set = 0, binding = 1, std430) buffer Output\n"
1202 "{\n"
1203 " uvec4 result[];\n"
1204 "};\n"
1205 "\n"
1206 "void main (void)\n"
1207 "{\n"
1208 " result[gl_PrimitiveID] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID + 1024, 0, 0);\n"
1209 " if (gl_InvocationID == 0)\n"
1210 " {\n"
1211 " gl_TessLevelOuter[0] = 1.0f;\n"
1212 " gl_TessLevelOuter[1] = 1.0f;\n"
1213 " }\n"
1214 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1215 #if GEOMETRY_POINT_SIZE_SUPPORTED
1216 " gl_out[gl_InvocationID].gl_PointSize = gl_in[gl_InvocationID].gl_PointSize;\n"
1217 #endif
1218 "}\n";
1219 */
1220
1221 const string pointSizeCapability = (*caseDef.geometryPointSizeSupported ? "OpCapability TessellationPointSize\n" : "");
1222
1223 const string tesc =
1224 "; SPIR-V\n"
1225 "; Version: 1.3\n"
1226 "; Generator: Khronos Glslang Reference Front End; 1\n"
1227 "; Bound: 61\n"
1228 "; Schema: 0\n"
1229 "OpCapability Tessellation\n"
1230 "OpCapability GroupNonUniform\n"
1231 + pointSizeCapability +
1232 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1233 "OpMemoryModel Logical GLSL450\n"
1234 "OpEntryPoint TessellationControl %4 \"main\" %15 %18 %20 %26 %36 %48 %54\n"
1235 "OpExecutionMode %4 OutputVertices 1\n"
1236 "OpDecorate %8 ArrayStride 16\n"
1237 "OpMemberDecorate %9 0 Offset 0\n"
1238 "OpDecorate %9 BufferBlock\n"
1239 "OpDecorate %11 DescriptorSet 0\n"
1240 "OpDecorate %11 Binding 1\n"
1241 "OpDecorate %15 BuiltIn PrimitiveId\n"
1242 "OpDecorate %18 RelaxedPrecision\n"
1243 "OpDecorate %18 BuiltIn SubgroupSize\n"
1244 "OpDecorate %19 RelaxedPrecision\n"
1245 "OpDecorate %20 RelaxedPrecision\n"
1246 "OpDecorate %20 BuiltIn SubgroupLocalInvocationId\n"
1247 "OpDecorate %21 RelaxedPrecision\n"
1248 "OpDecorate %26 BuiltIn InvocationId\n"
1249 "OpDecorate %36 Patch\n"
1250 "OpDecorate %36 BuiltIn TessLevelOuter\n"
1251 "OpMemberDecorate %45 0 BuiltIn Position\n"
1252 "OpMemberDecorate %45 1 BuiltIn PointSize\n"
1253 "OpMemberDecorate %45 2 BuiltIn ClipDistance\n"
1254 "OpMemberDecorate %45 3 BuiltIn CullDistance\n"
1255 "OpDecorate %45 Block\n"
1256 "OpMemberDecorate %50 0 BuiltIn Position\n"
1257 "OpMemberDecorate %50 1 BuiltIn PointSize\n"
1258 "OpMemberDecorate %50 2 BuiltIn ClipDistance\n"
1259 "OpMemberDecorate %50 3 BuiltIn CullDistance\n"
1260 "OpDecorate %50 Block\n"
1261 "%2 = OpTypeVoid\n"
1262 "%3 = OpTypeFunction %2\n"
1263 "%6 = OpTypeInt 32 0\n"
1264 "%7 = OpTypeVector %6 4\n"
1265 "%8 = OpTypeRuntimeArray %7\n"
1266 "%9 = OpTypeStruct %8\n"
1267 "%10 = OpTypePointer Uniform %9\n"
1268 "%11 = OpVariable %10 Uniform\n"
1269 "%12 = OpTypeInt 32 1\n"
1270 "%13 = OpConstant %12 0\n"
1271 "%14 = OpTypePointer Input %12\n"
1272 "%15 = OpVariable %14 Input\n"
1273 "%17 = OpTypePointer Input %6\n"
1274 "%18 = OpVariable %17 Input\n"
1275 "%20 = OpVariable %17 Input\n"
1276 "%22 = OpConstant %6 0\n"
1277 "%24 = OpTypePointer Uniform %7\n"
1278 "%26 = OpVariable %14 Input\n"
1279 "%28 = OpTypeBool\n"
1280 "%32 = OpTypeFloat 32\n"
1281 "%33 = OpConstant %6 4\n"
1282 "%34 = OpTypeArray %32 %33\n"
1283 "%35 = OpTypePointer Output %34\n"
1284 "%36 = OpVariable %35 Output\n"
1285 "%37 = OpConstant %32 1\n"
1286 "%38 = OpTypePointer Output %32\n"
1287 "%40 = OpConstant %12 1\n"
1288 "%42 = OpTypeVector %32 4\n"
1289 "%43 = OpConstant %6 1\n"
1290 "%44 = OpTypeArray %32 %43\n"
1291 "%45 = OpTypeStruct %42 %32 %44 %44\n"
1292 "%46 = OpTypeArray %45 %43\n"
1293 "%47 = OpTypePointer Output %46\n"
1294 "%48 = OpVariable %47 Output\n"
1295 "%50 = OpTypeStruct %42 %32 %44 %44\n"
1296 "%51 = OpConstant %6 32\n"
1297 "%52 = OpTypeArray %50 %51\n"
1298 "%53 = OpTypePointer Input %52\n"
1299 "%54 = OpVariable %53 Input\n"
1300 "%56 = OpTypePointer Input %42\n"
1301 "%59 = OpTypePointer Output %42\n"
1302 + (*caseDef.geometryPointSizeSupported ?
1303 "%61 = OpTypePointer Input %32\n"
1304 "%62 = OpTypePointer Output %32\n"
1305 "%63 = OpConstant %12 1\n" : "") +
1306 "%99 = OpConstant %6 1024\n"
1307 "%4 = OpFunction %2 None %3\n"
1308 "%5 = OpLabel\n"
1309 "%16 = OpLoad %12 %15\n"
1310 "%19 = OpLoad %6 %18\n"
1311 "%98 = OpLoad %6 %20\n"
1312 "%21 = OpIAdd %6 %98 %99\n"
1313 "%23 = OpCompositeConstruct %7 %19 %21 %22 %22\n"
1314 "%25 = OpAccessChain %24 %11 %13 %16\n"
1315 "OpStore %25 %23\n"
1316 "%27 = OpLoad %12 %26\n"
1317 "%29 = OpIEqual %28 %27 %13\n"
1318 "OpSelectionMerge %31 None\n"
1319 "OpBranchConditional %29 %30 %31\n"
1320 "%30 = OpLabel\n"
1321 "%39 = OpAccessChain %38 %36 %13\n"
1322 "OpStore %39 %37\n"
1323 "%41 = OpAccessChain %38 %36 %40\n"
1324 "OpStore %41 %37\n"
1325 "OpBranch %31\n"
1326 "%31 = OpLabel\n"
1327 "%49 = OpLoad %12 %26\n"
1328 "%55 = OpLoad %12 %26\n"
1329 "%57 = OpAccessChain %56 %54 %55 %13\n"
1330 "%58 = OpLoad %42 %57\n"
1331 "%60 = OpAccessChain %59 %48 %49 %13\n"
1332 "OpStore %60 %58\n"
1333 + (*caseDef.geometryPointSizeSupported ?
1334 "%64 = OpAccessChain %61 %54 %49 %63\n"
1335 "%65 = OpLoad %32 %64\n"
1336 "%66 = OpAccessChain %62 %48 %49 %63\n"
1337 "OpStore %66 %65\n" : "") +
1338 "OpReturn\n"
1339 "OpFunctionEnd\n";
1340 programCollection.spirvAsmSources.add("tesc") << tesc << buildOptionsSpr;
1341 }
1342
1343 {
1344 /*
1345 "#version 450\n"
1346 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1347 "layout(isolines) in;\n"
1348 "layout(set = 0, binding = 2, std430) buffer Output\n"
1349 "{\n"
1350 " uvec4 result[];\n"
1351 "};\n"
1352 "\n"
1353 "void main (void)\n"
1354 "{\n"
1355 " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID + 1024, 0, 0);\n"
1356 " float pixelSize = 2.0f/1024.0f;\n"
1357 " gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
1358 #if GEOMETRY_POINT_SIZE_SUPPORTED
1359 " gl_PointSize = gl_in[0].gl_PointSize;\n"
1360 #endif
1361 "}\n";
1362 */
1363
1364 const string pointSizeCapability = (*caseDef.geometryPointSizeSupported ? "OpCapability TessellationPointSize\n" : "");
1365
1366 const string tese =
1367 "; SPIR - V\n"
1368 "; Version: 1.3\n"
1369 "; Generator: Khronos Glslang Reference Front End; 2\n"
1370 "; Bound: 67\n"
1371 "; Schema: 0\n"
1372 "OpCapability Tessellation\n"
1373 "OpCapability GroupNonUniform\n"
1374 + pointSizeCapability +
1375 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1376 "OpMemoryModel Logical GLSL450\n"
1377 "OpEntryPoint TessellationEvaluation %4 \"main\" %15 %23 %33 %35 %48 %53\n"
1378 "OpExecutionMode %4 Isolines\n"
1379 "OpExecutionMode %4 SpacingEqual\n"
1380 "OpExecutionMode %4 VertexOrderCcw\n"
1381 "OpDecorate %8 ArrayStride 16\n"
1382 "OpMemberDecorate %9 0 Offset 0\n"
1383 "OpDecorate %9 BufferBlock\n"
1384 "OpDecorate %11 DescriptorSet 0\n"
1385 "OpDecorate %11 Binding 2\n"
1386 "OpDecorate %15 BuiltIn PrimitiveId\n"
1387 "OpDecorate %23 BuiltIn TessCoord\n"
1388 "OpDecorate %33 RelaxedPrecision\n"
1389 "OpDecorate %33 BuiltIn SubgroupSize\n"
1390 "OpDecorate %34 RelaxedPrecision\n"
1391 "OpDecorate %35 RelaxedPrecision\n"
1392 "OpDecorate %35 BuiltIn SubgroupLocalInvocationId\n"
1393 "OpDecorate %36 RelaxedPrecision\n"
1394 "OpMemberDecorate %46 0 BuiltIn Position\n"
1395 "OpMemberDecorate %46 1 BuiltIn PointSize\n"
1396 "OpMemberDecorate %46 2 BuiltIn ClipDistance\n"
1397 "OpMemberDecorate %46 3 BuiltIn CullDistance\n"
1398 "OpDecorate %46 Block\n"
1399 "OpMemberDecorate %49 0 BuiltIn Position\n"
1400 "OpMemberDecorate %49 1 BuiltIn PointSize\n"
1401 "OpMemberDecorate %49 2 BuiltIn ClipDistance\n"
1402 "OpMemberDecorate %49 3 BuiltIn CullDistance\n"
1403 "OpDecorate %49 Block\n"
1404 "%2 = OpTypeVoid\n"
1405 "%3 = OpTypeFunction %2\n"
1406 "%6 = OpTypeInt 32 0\n"
1407 "%7 = OpTypeVector %6 4\n"
1408 "%8 = OpTypeRuntimeArray %7\n"
1409 "%9 = OpTypeStruct %8\n"
1410 "%10 = OpTypePointer Uniform %9\n"
1411 "%11 = OpVariable %10 Uniform\n"
1412 "%12 = OpTypeInt 32 1\n"
1413 "%13 = OpConstant %12 0\n"
1414 "%14 = OpTypePointer Input %12\n"
1415 "%15 = OpVariable %14 Input\n"
1416 "%17 = OpConstant %12 2\n"
1417 "%20 = OpTypeFloat 32\n"
1418 "%21 = OpTypeVector %20 3\n"
1419 "%22 = OpTypePointer Input %21\n"
1420 "%23 = OpVariable %22 Input\n"
1421 "%24 = OpConstant %6 0\n"
1422 "%25 = OpTypePointer Input %20\n"
1423 "%28 = OpConstant %20 0.5\n"
1424 "%32 = OpTypePointer Input %6\n"
1425 "%33 = OpVariable %32 Input\n"
1426 "%35 = OpVariable %32 Input\n"
1427 "%38 = OpTypePointer Uniform %7\n"
1428 "%40 = OpTypePointer Function %20\n"
1429 "%42 = OpConstant %20 0.00195313\n"
1430 "%43 = OpTypeVector %20 4\n"
1431 "%44 = OpConstant %6 1\n"
1432 "%45 = OpTypeArray %20 %44\n"
1433 "%46 = OpTypeStruct %43 %20 %45 %45\n"
1434 "%47 = OpTypePointer Output %46\n"
1435 "%48 = OpVariable %47 Output\n"
1436 "%49 = OpTypeStruct %43 %20 %45 %45\n"
1437 "%50 = OpConstant %6 32\n"
1438 "%51 = OpTypeArray %49 %50\n"
1439 "%52 = OpTypePointer Input %51\n"
1440 "%53 = OpVariable %52 Input\n"
1441 "%54 = OpTypePointer Input %43\n"
1442 "%61 = OpConstant %20 2\n"
1443 "%65 = OpTypePointer Output %43\n"
1444 + (*caseDef.geometryPointSizeSupported ?
1445 "%67 = OpTypePointer Input %20\n"
1446 "%68 = OpTypePointer Output %20\n"
1447 "%69 = OpConstant %12 1\n" : "") +
1448 "%99 = OpConstant %6 1024\n"
1449 "%4 = OpFunction %2 None %3\n"
1450 "%5 = OpLabel\n"
1451 "%41 = OpVariable %40 Function\n"
1452 "%16 = OpLoad %12 %15\n"
1453 "%18 = OpIMul %12 %16 %17\n"
1454 "%19 = OpBitcast %6 %18\n"
1455 "%26 = OpAccessChain %25 %23 %24\n"
1456 "%27 = OpLoad %20 %26\n"
1457 "%29 = OpFAdd %20 %27 %28\n"
1458 "%30 = OpConvertFToU %6 %29\n"
1459 "%31 = OpIAdd %6 %19 %30\n"
1460 "%34 = OpLoad %6 %33\n"
1461 "%98 = OpLoad %6 %35\n"
1462 "%36 = OpIAdd %6 %98 %99\n"
1463 "%37 = OpCompositeConstruct %7 %34 %36 %24 %24\n"
1464 "%39 = OpAccessChain %38 %11 %13 %31\n"
1465 "OpStore %39 %37\n"
1466 "OpStore %41 %42\n"
1467 "%55 = OpAccessChain %54 %53 %13 %13\n"
1468 "%56 = OpLoad %43 %55\n"
1469 "%57 = OpAccessChain %25 %23 %24\n"
1470 "%58 = OpLoad %20 %57\n"
1471 "%59 = OpLoad %20 %41\n"
1472 "%60 = OpFMul %20 %58 %59\n"
1473 "%62 = OpFDiv %20 %60 %61\n"
1474 "%63 = OpCompositeConstruct %43 %62 %62 %62 %62\n"
1475 "%64 = OpFAdd %43 %56 %63\n"
1476 "%66 = OpAccessChain %65 %48 %13\n"
1477 "OpStore %66 %64\n"
1478 + (*caseDef.geometryPointSizeSupported ?
1479 "%70 = OpAccessChain %67 %53 %13 %69\n"
1480 "%71 = OpLoad %20 %70\n"
1481 "%72 = OpAccessChain %68 %48 %69\n"
1482 "OpStore %72 %71\n" : "") +
1483 "OpReturn\n"
1484 "OpFunctionEnd\n";
1485 programCollection.spirvAsmSources.add("tese") << tese << buildOptionsSpr;
1486 }
1487
1488 {
1489 /*
1490 "#version 450\n"
1491 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1492 "// Note: ${TOPOLOGY} variable is substituted manually at SPIR-V ASM level"
1493 "layout(${TOPOLOGY}) in;\n"
1494 "layout(points, max_vertices = 1) out;\n"
1495 "layout(set = 0, binding = 3, std430) buffer Output\n"
1496 "{\n"
1497 " uvec4 result[];\n"
1498 "};\n"
1499 "\n"
1500 "void main (void)\n"
1501 "{\n"
1502 " result[gl_PrimitiveIDIn] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID + 1024, 0, 0);\n"
1503 " gl_Position = gl_in[0].gl_Position;\n"
1504 #if GEOMETRY_POINT_SIZE_SUPPORTED
1505 " gl_PointSize = gl_in[0].gl_PointSize;\n"
1506 #endif
1507 " EmitVertex();\n"
1508 " EndPrimitive();\n"
1509 "}\n";
1510 */
1511
1512 const string pointSizeCapability = (*caseDef.geometryPointSizeSupported ? "OpCapability GeometryPointSize\n" : "");
1513
1514 const string geometry =
1515 "; SPIR-V\n"
1516 "; Version: 1.3\n"
1517 "; Generator: Khronos Glslang Reference Front End; 1\n"
1518 "; Bound: 42\n"
1519 "; Schema: 0\n"
1520 "OpCapability Geometry\n"
1521 "OpCapability GroupNonUniform\n"
1522 + pointSizeCapability +
1523 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1524 "OpMemoryModel Logical GLSL450\n"
1525 "OpEntryPoint Geometry %4 \"main\" %15 %18 %20 %32 %36\n"
1526 "OpExecutionMode %4 ${TOPOLOGY}\n"
1527 "OpExecutionMode %4 Invocations 1\n"
1528 "OpExecutionMode %4 OutputPoints\n"
1529 "OpExecutionMode %4 OutputVertices 1\n"
1530 "OpDecorate %8 ArrayStride 16\n"
1531 "OpMemberDecorate %9 0 Offset 0\n"
1532 "OpDecorate %9 BufferBlock\n"
1533 "OpDecorate %11 DescriptorSet 0\n"
1534 "OpDecorate %11 Binding 3\n"
1535 "OpDecorate %15 BuiltIn PrimitiveId\n"
1536 "OpDecorate %18 RelaxedPrecision\n"
1537 "OpDecorate %18 BuiltIn SubgroupSize\n"
1538 "OpDecorate %19 RelaxedPrecision\n"
1539 "OpDecorate %20 RelaxedPrecision\n"
1540 "OpDecorate %20 BuiltIn SubgroupLocalInvocationId\n"
1541 "OpDecorate %21 RelaxedPrecision\n"
1542 "OpMemberDecorate %30 0 BuiltIn Position\n"
1543 "OpMemberDecorate %30 1 BuiltIn PointSize\n"
1544 "OpMemberDecorate %30 2 BuiltIn ClipDistance\n"
1545 "OpMemberDecorate %30 3 BuiltIn CullDistance\n"
1546 "OpDecorate %30 Block\n"
1547 "OpMemberDecorate %33 0 BuiltIn Position\n"
1548 "OpMemberDecorate %33 1 BuiltIn PointSize\n"
1549 "OpMemberDecorate %33 2 BuiltIn ClipDistance\n"
1550 "OpMemberDecorate %33 3 BuiltIn CullDistance\n"
1551 "OpDecorate %33 Block\n"
1552 "%2 = OpTypeVoid\n"
1553 "%3 = OpTypeFunction %2\n"
1554 "%6 = OpTypeInt 32 0\n"
1555 "%7 = OpTypeVector %6 4\n"
1556 "%8 = OpTypeRuntimeArray %7\n"
1557 "%9 = OpTypeStruct %8\n"
1558 "%10 = OpTypePointer Uniform %9\n"
1559 "%11 = OpVariable %10 Uniform\n"
1560 "%12 = OpTypeInt 32 1\n"
1561 "%13 = OpConstant %12 0\n"
1562 "%14 = OpTypePointer Input %12\n"
1563 "%15 = OpVariable %14 Input\n"
1564 "%17 = OpTypePointer Input %6\n"
1565 "%18 = OpVariable %17 Input\n"
1566 "%20 = OpVariable %17 Input\n"
1567 "%22 = OpConstant %6 0\n"
1568 "%24 = OpTypePointer Uniform %7\n"
1569 "%26 = OpTypeFloat 32\n"
1570 "%27 = OpTypeVector %26 4\n"
1571 "%28 = OpConstant %6 1\n"
1572 "%29 = OpTypeArray %26 %28\n"
1573 "%30 = OpTypeStruct %27 %26 %29 %29\n"
1574 "%31 = OpTypePointer Output %30\n"
1575 "%32 = OpVariable %31 Output\n"
1576 "%33 = OpTypeStruct %27 %26 %29 %29\n"
1577 "%34 = OpTypeArray %33 %28\n"
1578 "%35 = OpTypePointer Input %34\n"
1579 "%36 = OpVariable %35 Input\n"
1580 "%37 = OpTypePointer Input %27\n"
1581 "%40 = OpTypePointer Output %27\n"
1582 + (*caseDef.geometryPointSizeSupported ?
1583 "%42 = OpTypePointer Input %26\n"
1584 "%43 = OpTypePointer Output %26\n"
1585 "%44 = OpConstant %12 1\n" : "") +
1586 "%99 = OpConstant %6 1024\n"
1587 "%4 = OpFunction %2 None %3\n"
1588 "%5 = OpLabel\n"
1589 "%16 = OpLoad %12 %15\n"
1590 "%19 = OpLoad %6 %18\n"
1591 "%98 = OpLoad %6 %20\n"
1592 "%21 = OpIAdd %6 %98 %99\n"
1593 "%23 = OpCompositeConstruct %7 %19 %21 %22 %22\n"
1594 "%25 = OpAccessChain %24 %11 %13 %16\n"
1595 "OpStore %25 %23\n"
1596 "%38 = OpAccessChain %37 %36 %13 %13\n"
1597 "%39 = OpLoad %27 %38\n"
1598 "%41 = OpAccessChain %40 %32 %13\n"
1599 "OpStore %41 %39\n"
1600 + (*caseDef.geometryPointSizeSupported ?
1601 "%45 = OpAccessChain %42 %36 %13 %44\n"
1602 "%46 = OpLoad %26 %45\n"
1603 "%47 = OpAccessChain %43 %32 %44\n"
1604 "OpStore %47 %46\n" : "") +
1605 "OpEmitVertex\n"
1606 "OpEndPrimitive\n"
1607 "OpReturn\n"
1608 "OpFunctionEnd\n";
1609
1610 addGeometryShadersFromTemplate(geometry, buildOptionsSpr, programCollection.spirvAsmSources);
1611 }
1612
1613 {
1614 /*
1615 "#version 450\n"
1616 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1617 "layout(location = 0) out uvec4 data;\n"
1618 "void main (void)\n"
1619 "{\n"
1620 " data = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID + 1024, 0, 0);\n"
1621 "}\n";
1622 */
1623 const string fragment =
1624 "; SPIR-V\n"
1625 "; Version: 1.3\n"
1626 "; Generator: Khronos Glslang Reference Front End; 1\n"
1627 "; Bound: 17\n"
1628 "; Schema: 0\n"
1629 "OpCapability Shader\n"
1630 "OpCapability GroupNonUniform\n"
1631 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1632 "OpMemoryModel Logical GLSL450\n"
1633 "OpEntryPoint Fragment %4 \"main\" %9 %11 %13\n"
1634 "OpExecutionMode %4 OriginUpperLeft\n"
1635 "OpDecorate %9 Location 0\n"
1636 "OpDecorate %11 RelaxedPrecision\n"
1637 "OpDecorate %11 Flat\n"
1638 "OpDecorate %11 BuiltIn SubgroupSize\n"
1639 "OpDecorate %12 RelaxedPrecision\n"
1640 "OpDecorate %13 RelaxedPrecision\n"
1641 "OpDecorate %13 Flat\n"
1642 "OpDecorate %13 BuiltIn SubgroupLocalInvocationId\n"
1643 "OpDecorate %14 RelaxedPrecision\n"
1644 "%2 = OpTypeVoid\n"
1645 "%3 = OpTypeFunction %2\n"
1646 "%6 = OpTypeInt 32 0\n"
1647 "%7 = OpTypeVector %6 4\n"
1648 "%8 = OpTypePointer Output %7\n"
1649 "%9 = OpVariable %8 Output\n"
1650 "%10 = OpTypePointer Input %6\n"
1651 "%11 = OpVariable %10 Input\n"
1652 "%13 = OpVariable %10 Input\n"
1653 "%15 = OpConstant %6 0\n"
1654 "%99 = OpConstant %6 1024\n"
1655 "%4 = OpFunction %2 None %3\n"
1656 "%5 = OpLabel\n"
1657 "%12 = OpLoad %6 %11\n"
1658 "%98 = OpLoad %6 %13\n"
1659 "%14 = OpIAdd %6 %98 %99\n"
1660 "%16 = OpCompositeConstruct %7 %12 %14 %15 %15\n"
1661 "OpStore %9 %16\n"
1662 "OpReturn\n"
1663 "OpFunctionEnd\n";
1664
1665 programCollection.spirvAsmSources.add("fragment") << fragment << buildOptionsSpr;
1666 }
1667
1668 subgroups::addNoSubgroupShader(programCollection);
1669 }
1670 #ifndef CTS_USES_VULKANSC
1671 else if (isAllRayTracingStages(caseDef.shaderStage))
1672 {
1673 const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, SPIRV_VERSION_1_4, 0u, true);
1674 const string extHeader = "#extension GL_KHR_shader_subgroup_basic : require\n";
1675 const string tempRes = " uvec4 tempRes;\n";
1676 const string testSrc = " tempRes = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID + 1024, 0, 0);\n";
1677 const vector<string> headDeclarations = getPerStageHeadDeclarations(caseDef);
1678
1679 subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, VK_FORMAT_R32G32B32A32_UINT, false, extHeader, testSrc, "", headDeclarations, false, tempRes);
1680 }
1681 #endif // CTS_USES_VULKANSC
1682 else
1683 TCU_THROW(InternalError, "Unknown stage");
1684 }
1685
supportedCheck(Context & context,CaseDefinition caseDef)1686 void supportedCheck (Context& context, CaseDefinition caseDef)
1687 {
1688 if (!subgroups::isSubgroupSupported(context))
1689 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
1690
1691 if (caseDef.requiredSubgroupSize)
1692 {
1693 context.requireDeviceFunctionality("VK_EXT_subgroup_size_control");
1694
1695 #ifndef CTS_USES_VULKANSC
1696 const VkPhysicalDeviceSubgroupSizeControlFeatures& subgroupSizeControlFeatures = context.getSubgroupSizeControlFeatures();
1697 const VkPhysicalDeviceSubgroupSizeControlProperties& subgroupSizeControlProperties = context.getSubgroupSizeControlProperties();
1698 #else
1699 const VkPhysicalDeviceSubgroupSizeControlFeaturesEXT& subgroupSizeControlFeatures = context.getSubgroupSizeControlFeaturesEXT();
1700 const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& subgroupSizeControlProperties = context.getSubgroupSizeControlPropertiesEXT();
1701 #endif // CTS_USES_VULKANSC
1702
1703 if (subgroupSizeControlFeatures.subgroupSizeControl == DE_FALSE)
1704 TCU_THROW(NotSupportedError, "Device does not support varying subgroup sizes nor required subgroup size");
1705
1706 if (subgroupSizeControlFeatures.computeFullSubgroups == DE_FALSE)
1707 TCU_THROW(NotSupportedError, "Device does not support full subgroups in compute shaders");
1708
1709 if ((subgroupSizeControlProperties.requiredSubgroupSizeStages & caseDef.shaderStage) != caseDef.shaderStage)
1710 TCU_THROW(NotSupportedError, "Required subgroup size is not supported for shader stage");
1711 }
1712
1713 *caseDef.geometryPointSizeSupported = subgroups::isTessellationAndGeometryPointSizeSupported(context);
1714
1715 #ifndef CTS_USES_VULKANSC
1716 if (isAllRayTracingStages(caseDef.shaderStage))
1717 {
1718 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1719 }
1720 else if (isAllMeshShadingStages(caseDef.shaderStage))
1721 {
1722 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
1723 context.requireDeviceFunctionality("VK_EXT_mesh_shader");
1724
1725 if ((caseDef.shaderStage & VK_SHADER_STAGE_TASK_BIT_EXT) != 0u)
1726 {
1727 const auto& features = context.getMeshShaderFeaturesEXT();
1728 if (!features.taskShader)
1729 TCU_THROW(NotSupportedError, "Task shaders not supported");
1730 }
1731 }
1732 #endif // CTS_USES_VULKANSC
1733
1734 vkt::subgroups::supportedCheckShader(context, caseDef.shaderStage);
1735 }
1736
noSSBOtest(Context & context,const CaseDefinition caseDef)1737 TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
1738 {
1739 if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
1740 {
1741 switch (caseDef.testType)
1742 {
1743 case TEST_TYPE_SUBGROUP_SIZE: return makeVertexFrameBufferTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStagesSubgroupSize);
1744 case TEST_TYPE_SUBGROUP_INVOCATION_ID: return makeVertexFrameBufferTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStagesSubgroupInvocationID);
1745 default: TCU_THROW(InternalError, "Unknown builtin");
1746 }
1747 }
1748 else if ((VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) & caseDef.shaderStage)
1749 {
1750 switch (caseDef.testType)
1751 {
1752 case TEST_TYPE_SUBGROUP_SIZE: return makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStagesSubgroupSize);
1753 case TEST_TYPE_SUBGROUP_INVOCATION_ID: return makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStagesSubgroupInvocationID);
1754 default: TCU_THROW(InternalError, "Unknown builtin");
1755 }
1756 }
1757 else if (VK_SHADER_STAGE_GEOMETRY_BIT & caseDef.shaderStage)
1758 {
1759 switch (caseDef.testType)
1760 {
1761 case TEST_TYPE_SUBGROUP_SIZE: return makeGeometryFrameBufferTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStagesSubgroupSize);
1762 case TEST_TYPE_SUBGROUP_INVOCATION_ID: return makeGeometryFrameBufferTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStagesSubgroupInvocationID);
1763 default: TCU_THROW(InternalError, "Unknown builtin");
1764 }
1765 }
1766 else
1767 {
1768 TCU_THROW(InternalError, "Unhandled shader stage");
1769 }
1770 }
1771
test(Context & context,const CaseDefinition caseDef)1772 TestStatus test (Context& context, const CaseDefinition caseDef)
1773 {
1774 const bool isCompute = isAllComputeStages(caseDef.shaderStage);
1775 #ifndef CTS_USES_VULKANSC
1776 const bool isMesh = isAllMeshShadingStages(caseDef.shaderStage);
1777 #else
1778 const bool isMesh = false;
1779 #endif // CTS_USES_VULKANSC
1780 DE_ASSERT(!(isCompute && isMesh));
1781
1782 if (isCompute || isMesh)
1783 {
1784 #ifndef CTS_USES_VULKANSC
1785 const VkPhysicalDeviceSubgroupSizeControlProperties& subgroupSizeControlProperties = context.getSubgroupSizeControlProperties();
1786 #else
1787 const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& subgroupSizeControlProperties = context.getSubgroupSizeControlPropertiesEXT();
1788 #endif // CTS_USES_VULKANSC
1789 TestLog& log = context.getTestContext().getLog();
1790
1791 switch (caseDef.testType)
1792 {
1793 case TEST_TYPE_SUBGROUP_SIZE:
1794 {
1795 if (caseDef.requiredSubgroupSize == DE_FALSE)
1796 {
1797 if (isCompute)
1798 return makeComputeTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkComputeSubgroupSize);
1799 else
1800 return makeMeshTest(context, VK_FORMAT_R32G32B32A32_UINT, nullptr, 0, nullptr, checkComputeSubgroupSize);
1801 }
1802
1803 log << TestLog::Message << "Testing required subgroup size range [" << subgroupSizeControlProperties.minSubgroupSize << ", "
1804 << subgroupSizeControlProperties.maxSubgroupSize << "]" << TestLog::EndMessage;
1805
1806 // According to the spec, requiredSubgroupSize must be a power-of-two integer.
1807 for (deUint32 size = subgroupSizeControlProperties.minSubgroupSize; size <= subgroupSizeControlProperties.maxSubgroupSize; size *= 2)
1808 {
1809 TestStatus result (QP_TEST_RESULT_INTERNAL_ERROR, "Internal Error");
1810
1811 if (isCompute)
1812 result = subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkComputeSubgroupSize, size);
1813 else
1814 result = subgroups::makeMeshTest(context, VK_FORMAT_R32_UINT, nullptr, 0, nullptr, checkComputeSubgroupSize, size);
1815
1816 if (result.getCode() != QP_TEST_RESULT_PASS)
1817 {
1818 log << TestLog::Message << "subgroupSize " << size << " failed" << TestLog::EndMessage;
1819
1820 return result;
1821 }
1822 }
1823
1824 return TestStatus::pass("OK");
1825 }
1826
1827 case TEST_TYPE_SUBGROUP_INVOCATION_ID:
1828 {
1829 if (caseDef.requiredSubgroupSize == DE_FALSE)
1830 {
1831 if (isCompute)
1832 return makeComputeTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkComputeSubgroupInvocationID);
1833 else
1834 return makeMeshTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkComputeSubgroupInvocationID);
1835 }
1836
1837 log << TestLog::Message << "Testing required subgroup size range [" << subgroupSizeControlProperties.minSubgroupSize << ", "
1838 << subgroupSizeControlProperties.maxSubgroupSize << "]" << TestLog::EndMessage;
1839
1840 // According to the spec, requiredSubgroupSize must be a power-of-two integer.
1841 for (deUint32 size = subgroupSizeControlProperties.minSubgroupSize; size <= subgroupSizeControlProperties.maxSubgroupSize; size *= 2)
1842 {
1843 TestStatus result (QP_TEST_RESULT_INTERNAL_ERROR, "Internal Error");
1844
1845 if (isCompute)
1846 result = subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkComputeSubgroupInvocationID, size);
1847 else
1848 result = subgroups::makeMeshTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkComputeSubgroupInvocationID, size);
1849
1850 if (result.getCode() != QP_TEST_RESULT_PASS)
1851 {
1852 log << TestLog::Message << "subgroupSize " << size << " failed" << TestLog::EndMessage;
1853
1854 return result;
1855 }
1856 }
1857
1858 return TestStatus::pass("OK");
1859 }
1860
1861 case TEST_TYPE_SUBGROUP_NUM_SUBGROUPS:
1862 {
1863 if (caseDef.requiredSubgroupSize == DE_FALSE)
1864 {
1865 if (isCompute)
1866 return makeComputeTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkComputeNumSubgroups);
1867 else
1868 return makeMeshTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkComputeNumSubgroups);
1869 }
1870
1871 log << TestLog::Message << "Testing required subgroup size range [" << subgroupSizeControlProperties.minSubgroupSize << ", "
1872 << subgroupSizeControlProperties.maxSubgroupSize << "]" << TestLog::EndMessage;
1873
1874 // According to the spec, requiredSubgroupSize must be a power-of-two integer.
1875 for (deUint32 size = subgroupSizeControlProperties.minSubgroupSize; size <= subgroupSizeControlProperties.maxSubgroupSize; size *= 2)
1876 {
1877 TestStatus result (QP_TEST_RESULT_INTERNAL_ERROR, "Internal Error");
1878
1879 if (isCompute)
1880 result = subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkComputeNumSubgroups, size);
1881 else
1882 result = subgroups::makeMeshTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkComputeNumSubgroups, size);
1883
1884 if (result.getCode() != QP_TEST_RESULT_PASS)
1885 {
1886 log << TestLog::Message << "subgroupSize " << size << " failed" << TestLog::EndMessage;
1887
1888 return result;
1889 }
1890 }
1891
1892 return TestStatus::pass("OK");
1893 }
1894
1895 case TEST_TYPE_SUBGROUP_NUM_SUBGROUP_ID:
1896 {
1897 if (caseDef.requiredSubgroupSize == DE_FALSE)
1898 {
1899 if (isCompute)
1900 return makeComputeTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkComputeSubgroupID);
1901 else
1902 return makeMeshTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkComputeSubgroupID);
1903 }
1904
1905 log << TestLog::Message << "Testing required subgroup size range [" << subgroupSizeControlProperties.minSubgroupSize << ", "
1906 << subgroupSizeControlProperties.maxSubgroupSize << "]" << TestLog::EndMessage;
1907
1908 // According to the spec, requiredSubgroupSize must be a power-of-two integer.
1909 for (deUint32 size = subgroupSizeControlProperties.minSubgroupSize; size <= subgroupSizeControlProperties.maxSubgroupSize; size *= 2)
1910 {
1911 TestStatus result (QP_TEST_RESULT_INTERNAL_ERROR, "Internal Error");
1912
1913 if (isCompute)
1914 result = subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkComputeSubgroupID, size);
1915 else
1916 result = subgroups::makeMeshTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, DE_NULL, checkComputeSubgroupID, size);
1917
1918 if (result.getCode() != QP_TEST_RESULT_PASS)
1919 {
1920 log << TestLog::Message << "subgroupSize " << size << " failed" << TestLog::EndMessage;
1921
1922 return result;
1923 }
1924 }
1925
1926 return TestStatus::pass("OK");
1927 }
1928
1929 default:
1930 TCU_THROW(InternalError, "Unknown builtin");
1931 }
1932 }
1933 else if (isAllGraphicsStages(caseDef.shaderStage))
1934 {
1935 const VkShaderStageFlags stages = subgroups::getPossibleGraphicsSubgroupStages(context, caseDef.shaderStage);
1936
1937 switch (caseDef.testType)
1938 {
1939 case TEST_TYPE_SUBGROUP_SIZE: return subgroups::allStages(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStagesSubgroupSize, stages);
1940 case TEST_TYPE_SUBGROUP_INVOCATION_ID: return subgroups::allStages(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStagesSubgroupInvocationID, stages);
1941 default: TCU_THROW(InternalError, "Unknown builtin");
1942 }
1943 }
1944 #ifndef CTS_USES_VULKANSC
1945 else if (isAllRayTracingStages(caseDef.shaderStage))
1946 {
1947 const VkShaderStageFlags stages = subgroups::getPossibleRayTracingSubgroupStages(context, caseDef.shaderStage);
1948
1949 switch (caseDef.testType)
1950 {
1951 case TEST_TYPE_SUBGROUP_SIZE: return subgroups::allRayTracingStages(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStagesSubgroupSize, stages);
1952 case TEST_TYPE_SUBGROUP_INVOCATION_ID: return subgroups::allRayTracingStages(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, DE_NULL, checkVertexPipelineStagesSubgroupInvocationID, stages);
1953 default: TCU_THROW(InternalError, "Unknown builtin");
1954 }
1955 }
1956 #endif // CTS_USES_VULKANSC
1957 else
1958 TCU_THROW(InternalError, "Unknown stage or invalid stage set");
1959 }
1960
createSubgroupsBuiltinVarTests(TestContext & testCtx)1961 TestCaseGroup* createSubgroupsBuiltinVarTests (TestContext& testCtx)
1962 {
1963 de::MovePtr<TestCaseGroup> group (new TestCaseGroup(testCtx, "builtin_var", "Subgroup builtin variable tests"));
1964 de::MovePtr<TestCaseGroup> graphicGroup (new TestCaseGroup(testCtx, "graphics", "Subgroup builtin variable tests: graphics"));
1965 de::MovePtr<TestCaseGroup> computeGroup (new TestCaseGroup(testCtx, "compute", "Subgroup builtin variable tests: compute"));
1966 de::MovePtr<TestCaseGroup> framebufferGroup (new TestCaseGroup(testCtx, "framebuffer", "Subgroup builtin variable tests: framebuffer"));
1967 #ifndef CTS_USES_VULKANSC
1968 de::MovePtr<TestCaseGroup> raytracingGroup (new TestCaseGroup(testCtx, "ray_tracing", "Subgroup builtin variable tests: ray tracing"));
1969 de::MovePtr<TestCaseGroup> meshGroup (new TestCaseGroup(testCtx, "mesh", "Subgroup builtin variable tests: mesh shading"));
1970 #endif // CTS_USES_VULKANSC
1971 const TestType allStagesBuiltinVars[] =
1972 {
1973 TEST_TYPE_SUBGROUP_SIZE,
1974 TEST_TYPE_SUBGROUP_INVOCATION_ID,
1975 };
1976 const TestType computeOnlyBuiltinVars[] =
1977 {
1978 TEST_TYPE_SUBGROUP_NUM_SUBGROUPS,
1979 TEST_TYPE_SUBGROUP_NUM_SUBGROUP_ID,
1980 };
1981 const VkShaderStageFlags fbStages[] =
1982 {
1983 VK_SHADER_STAGE_VERTEX_BIT,
1984 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1985 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1986 VK_SHADER_STAGE_GEOMETRY_BIT,
1987 };
1988 #ifndef CTS_USES_VULKANSC
1989 const VkShaderStageFlags meshStages[] =
1990 {
1991 VK_SHADER_STAGE_MESH_BIT_EXT,
1992 VK_SHADER_STAGE_TASK_BIT_EXT,
1993 };
1994 #endif // CTS_USES_VULKANSC
1995 const deBool boolValues[] =
1996 {
1997 DE_FALSE,
1998 DE_TRUE
1999 };
2000
2001 for (int a = 0; a < DE_LENGTH_OF_ARRAY(allStagesBuiltinVars); ++a)
2002 {
2003 const TestType testType = allStagesBuiltinVars[a];
2004 const string varLower = de::toLower(getTestName(testType));
2005
2006 {
2007 const CaseDefinition caseDef =
2008 {
2009 testType, // TestType testType;
2010 VK_SHADER_STAGE_ALL_GRAPHICS, // VkShaderStageFlags shaderStage;
2011 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
2012 DE_FALSE // deBool requiredSubgroupSize;
2013 };
2014
2015 addFunctionCaseWithPrograms(graphicGroup.get(), varLower, "", supportedCheck, initPrograms, test, caseDef);
2016 }
2017
2018 #ifndef CTS_USES_VULKANSC
2019 {
2020 const CaseDefinition caseDef =
2021 {
2022 testType, // TestType testType;
2023 SHADER_STAGE_ALL_RAY_TRACING, // VkShaderStageFlags shaderStage;
2024 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
2025 DE_FALSE // deBool requiredSubgroupSize;
2026 };
2027
2028 addFunctionCaseWithPrograms(raytracingGroup.get(), varLower, "", supportedCheck, initPrograms, test, caseDef);
2029 }
2030 #endif // CTS_USES_VULKANSC
2031
2032 for (size_t groupSizeNdx = 0; groupSizeNdx < DE_LENGTH_OF_ARRAY(boolValues); ++groupSizeNdx)
2033 {
2034 const deBool requiredSubgroupSize = boolValues[groupSizeNdx];
2035 const string testNameSuffix = requiredSubgroupSize ? "_requiredsubgroupsize" : "";
2036 const CaseDefinition caseDef =
2037 {
2038 testType, // TestType testType;
2039 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags shaderStage;
2040 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
2041 requiredSubgroupSize // deBool requiredSubgroupSize;
2042 };
2043 const string testName = varLower + "_" + getShaderStageName(caseDef.shaderStage) + testNameSuffix;
2044
2045 addFunctionCaseWithPrograms(computeGroup.get(), testName, "", supportedCheck, initPrograms, test, caseDef);
2046 }
2047
2048 #ifndef CTS_USES_VULKANSC
2049 for (size_t groupSizeNdx = 0; groupSizeNdx < DE_LENGTH_OF_ARRAY(boolValues); ++groupSizeNdx)
2050 {
2051 for (const auto& stage : meshStages)
2052 {
2053 const deBool requiredSubgroupSize = boolValues[groupSizeNdx];
2054 const string testNameSuffix = requiredSubgroupSize ? "_requiredsubgroupsize" : "";
2055 const CaseDefinition caseDef =
2056 {
2057 testType, // TestType testType;
2058 stage, // VkShaderStageFlags shaderStage;
2059 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
2060 requiredSubgroupSize // deBool requiredSubgroupSize;
2061 };
2062 const string testName = varLower + "_" + getShaderStageName(caseDef.shaderStage) + testNameSuffix;
2063
2064 addFunctionCaseWithPrograms(meshGroup.get(), testName, "", supportedCheck, initPrograms, test, caseDef);
2065 }
2066 }
2067 #endif // CTS_USES_VULKANSC
2068
2069 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(fbStages); ++stageIndex)
2070 {
2071 const CaseDefinition caseDef =
2072 {
2073 testType, // TestType testType;
2074 fbStages[stageIndex], // VkShaderStageFlags shaderStage;
2075 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
2076 DE_FALSE // deBool requiredSubgroupSize;
2077 };
2078 const string testName = varLower + "_" + getShaderStageName(caseDef.shaderStage);
2079
2080 addFunctionCaseWithPrograms(framebufferGroup.get(), testName, "", supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
2081 }
2082 }
2083
2084 for (int a = 0; a < DE_LENGTH_OF_ARRAY(computeOnlyBuiltinVars); ++a)
2085 {
2086 const TestType testType = computeOnlyBuiltinVars[a];
2087 const string varLower = de::toLower(getTestName(testType));
2088
2089 for (size_t groupSizeNdx = 0; groupSizeNdx < DE_LENGTH_OF_ARRAY(boolValues); ++groupSizeNdx)
2090 {
2091 const deBool requiredSubgroupSize = boolValues[groupSizeNdx];
2092 const string testNameSuffix = requiredSubgroupSize ? "_requiredsubgroupsize" : "";
2093 const CaseDefinition caseDef =
2094 {
2095 testType, // TestType testType;
2096 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags shaderStage;
2097 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
2098 requiredSubgroupSize // deBool requiredSubgroupSize;
2099 };
2100 const string testName = varLower + testNameSuffix;
2101
2102 addFunctionCaseWithPrograms(computeGroup.get(), testName, "", supportedCheck, initPrograms, test, caseDef);
2103 }
2104
2105 #ifndef CTS_USES_VULKANSC
2106 for (size_t groupSizeNdx = 0; groupSizeNdx < DE_LENGTH_OF_ARRAY(boolValues); ++groupSizeNdx)
2107 {
2108 for (const auto& stage : meshStages)
2109 {
2110 const deBool requiredSubgroupSize = boolValues[groupSizeNdx];
2111 const string testNameSuffix = requiredSubgroupSize ? "_requiredsubgroupsize" : "";
2112 const CaseDefinition caseDef =
2113 {
2114 testType, // TestType testType;
2115 stage, // VkShaderStageFlags shaderStage;
2116 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
2117 requiredSubgroupSize // deBool requiredSubgroupSize;
2118 };
2119 const string testName = varLower + testNameSuffix + "_" + getShaderStageName(stage);
2120
2121 addFunctionCaseWithPrograms(meshGroup.get(), testName, "", supportedCheck, initPrograms, test, caseDef);
2122 }
2123 }
2124 #endif // CTS_USES_VULKANSC
2125 }
2126
2127 group->addChild(graphicGroup.release());
2128 group->addChild(computeGroup.release());
2129 #ifndef CTS_USES_VULKANSC
2130 group->addChild(raytracingGroup.release());
2131 group->addChild(meshGroup.release());
2132 #endif // CTS_USES_VULKANSC
2133 group->addChild(framebufferGroup.release());
2134
2135 return group.release();
2136 }
2137
2138 } // subgroups
2139 } // vkt
2140