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