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 "vktSubgroupsBallotBroadcastTests.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 using namespace vkt;
36
37 namespace
38 {
39 enum OpType
40 {
41 OPTYPE_BROADCAST = 0,
42 OPTYPE_BROADCAST_NONCONST,
43 OPTYPE_BROADCAST_FIRST,
44 OPTYPE_LAST
45 };
46
47 struct CaseDefinition
48 {
49 OpType opType;
50 VkShaderStageFlags shaderStage;
51 VkFormat format;
52 de::SharedPtr<bool> geometryPointSizeSupported;
53 deBool extShaderSubGroupBallotTests;
54 deBool subgroupSizeControl;
55 deUint32 requiredSubgroupSize;
56 };
57
checkVertexPipelineStages(const void * internalData,vector<const void * > datas,deUint32 width,deUint32)58 bool checkVertexPipelineStages (const void* internalData,
59 vector<const void*> datas,
60 deUint32 width,
61 deUint32)
62 {
63 DE_UNREF(internalData);
64
65 return subgroups::check(datas, width, 3);
66 }
67
checkCompute(const void * internalData,vector<const void * > datas,const deUint32 numWorkgroups[3],const deUint32 localSize[3],deUint32)68 bool checkCompute (const void* internalData,
69 vector<const void*> datas,
70 const deUint32 numWorkgroups[3],
71 const deUint32 localSize[3],
72 deUint32)
73 {
74 DE_UNREF(internalData);
75
76 return subgroups::checkCompute(datas, numWorkgroups, localSize, 3);
77 }
78
getOpTypeCaseName(OpType opType)79 string getOpTypeCaseName (OpType opType)
80 {
81 switch (opType)
82 {
83 case OPTYPE_BROADCAST: return "subgroupbroadcast";
84 case OPTYPE_BROADCAST_NONCONST: return "subgroupbroadcast_nonconst";
85 case OPTYPE_BROADCAST_FIRST: return "subgroupbroadcastfirst";
86 default: TCU_THROW(InternalError, "Unsupported op type");
87 }
88 }
89
getExtHeader(const CaseDefinition & caseDef)90 string getExtHeader (const CaseDefinition& caseDef)
91 {
92 return (caseDef.extShaderSubGroupBallotTests ? "#extension GL_ARB_shader_ballot: enable\n"
93 "#extension GL_KHR_shader_subgroup_basic: enable\n"
94 "#extension GL_ARB_gpu_shader_int64: enable\n"
95 : "#extension GL_KHR_shader_subgroup_ballot: enable\n")
96 + subgroups::getAdditionalExtensionForFormat(caseDef.format);
97 }
98
getTestSrc(const CaseDefinition & caseDef)99 string getTestSrc (const CaseDefinition &caseDef)
100 {
101 ostringstream bdy;
102 string broadcast;
103 string broadcastFirst;
104 string mask;
105 int max;
106 const string fmt = subgroups::getFormatNameForGLSL(caseDef.format);
107
108 if (caseDef.extShaderSubGroupBallotTests)
109 {
110 broadcast = "readInvocationARB";
111 broadcastFirst = "readFirstInvocationARB";
112 mask = "mask = ballotARB(true);\n";
113 max = 64;
114
115 bdy << " uint64_t mask;\n"
116 << mask
117 << " uint sgSize = gl_SubGroupSizeARB;\n"
118 << " uint sgInvocation = gl_SubGroupInvocationARB;\n";
119 }
120 else
121 {
122 broadcast = "subgroupBroadcast";
123 broadcastFirst = "subgroupBroadcastFirst";
124 mask = "mask = subgroupBallot(true);\n";
125
126 if (caseDef.subgroupSizeControl)
127 max = caseDef.requiredSubgroupSize;
128 else
129 max = (int)subgroups::maxSupportedSubgroupSize();
130
131 bdy << " uvec4 mask = subgroupBallot(true);\n"
132 << " uint sgSize = gl_SubgroupSize;\n"
133 << " uint sgInvocation = gl_SubgroupInvocationID;\n";
134 }
135
136 if (caseDef.opType == OPTYPE_BROADCAST)
137 {
138 bdy << " tempRes = 0x3;\n"
139 << " " << fmt << " ops[" << max << "];\n"
140 << " " << fmt << " d = data[sgInvocation];\n";
141
142 for (int i = 0; i < max; i++)
143 bdy << " ops[" << i << "] = " << broadcast << "(d, " << i << "u);\n";
144
145 bdy << " for(int id = 0; id < sgSize; id++)\n"
146 << " {\n"
147 << " if (subgroupBallotBitExtract(mask, id) && ops[id] != data[id])\n"
148 << " {\n"
149 << " tempRes = 0;\n"
150 << " }\n"
151 << " };\n";
152 }
153 else if (caseDef.opType == OPTYPE_BROADCAST_NONCONST)
154 {
155 const string validate = " if (subgroupBallotBitExtract(mask, id) && op != data[id])\n"
156 " tempRes = 0;\n";
157
158 bdy << " tempRes= 0x3;\n"
159 << " for (uint id = 0; id < sgSize; id++)\n"
160 << " {\n"
161 << " " << fmt << " op = " << broadcast << "(data[sgInvocation], id);\n"
162 << validate
163 << " }\n"
164 << " // Test lane id that is only uniform across active lanes\n"
165 << " if (sgInvocation >= sgSize / 2)\n"
166 << " {\n"
167 << " uint id = sgInvocation & ~((sgSize / 2) - 1);\n"
168 << " " << fmt << " op = " << broadcast << "(data[sgInvocation], id);\n"
169 << validate
170 << " }\n";
171 }
172 else if (caseDef.opType == OPTYPE_BROADCAST_FIRST)
173 {
174 bdy << " tempRes = 0;\n"
175 << " uint firstActive = 0;\n"
176 << " for (uint i = 0; i < sgSize; i++)\n"
177 << " {\n"
178 << " if (subgroupBallotBitExtract(mask, i))\n"
179 << " {\n"
180 << " firstActive = i;\n"
181 << " break;\n"
182 << " }\n"
183 << " }\n"
184 << " tempRes |= (" << broadcastFirst << "(data[sgInvocation]) == data[firstActive]) ? 0x1 : 0;\n"
185 << " // make the firstActive invocation inactive now\n"
186 << " if (firstActive != sgInvocation)\n"
187 << " {\n"
188 << mask
189 << " for (uint i = 0; i < sgSize; i++)\n"
190 << " {\n"
191 << " if (subgroupBallotBitExtract(mask, i))\n"
192 << " {\n"
193 << " firstActive = i;\n"
194 << " break;\n"
195 << " }\n"
196 << " }\n"
197 << " tempRes |= (" << broadcastFirst << "(data[sgInvocation]) == data[firstActive]) ? 0x2 : 0;\n"
198 << " }\n"
199 << " else\n"
200 << " {\n"
201 << " // the firstActive invocation didn't partake in the second result so set it to true\n"
202 << " tempRes |= 0x2;\n"
203 << " }\n";
204 }
205 else
206 TCU_THROW(InternalError, "Unknown operation type");
207
208 return bdy.str();
209 }
210
getHelperFunctionARB(const CaseDefinition & caseDef)211 string getHelperFunctionARB (const CaseDefinition &caseDef)
212 {
213 ostringstream bdy;
214
215 if (caseDef.extShaderSubGroupBallotTests == DE_FALSE)
216 return "";
217
218 bdy << "bool subgroupBallotBitExtract(uint64_t value, uint index)\n";
219 bdy << "{\n";
220 bdy << " if (index > 63)\n";
221 bdy << " return false;\n";
222 bdy << " uint64_t mask = 1ul << index;\n";
223 bdy << " if (bool((value & mask)) == true)\n";
224 bdy << " return true;\n";
225 bdy << " return false;\n";
226 bdy << "}\n";
227
228 return bdy.str();
229 }
230
initFrameBufferPrograms(SourceCollections & programCollection,CaseDefinition caseDef)231 void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
232 {
233 const SpirvVersion spirvVersion = (caseDef.opType == OPTYPE_BROADCAST_NONCONST) ? SPIRV_VERSION_1_5 : SPIRV_VERSION_1_3;
234 const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, spirvVersion, 0u);
235 const string extHeader = getExtHeader(caseDef);
236 const string testSrc = getTestSrc(caseDef);
237 const string helperStr = getHelperFunctionARB(caseDef);
238
239 subgroups::initStdFrameBufferPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, extHeader, testSrc, helperStr);
240 }
241
initPrograms(SourceCollections & programCollection,CaseDefinition caseDef)242 void initPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
243 {
244 const bool spirv15required = caseDef.opType == OPTYPE_BROADCAST_NONCONST;
245 const bool spirv14required = isAllRayTracingStages(caseDef.shaderStage);
246 const SpirvVersion spirvVersion = spirv15required ? SPIRV_VERSION_1_5
247 : spirv14required ? SPIRV_VERSION_1_4
248 : SPIRV_VERSION_1_3;
249 const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, spirvVersion, 0u);
250 const string extHeader = getExtHeader(caseDef);
251 const string testSrc = getTestSrc(caseDef);
252 const string helperStr = getHelperFunctionARB(caseDef);
253
254 subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, extHeader, testSrc, helperStr);
255 }
256
supportedCheck(Context & context,CaseDefinition caseDef)257 void supportedCheck (Context& context, CaseDefinition caseDef)
258 {
259 if (!subgroups::isSubgroupSupported(context))
260 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
261
262 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BALLOT_BIT))
263 TCU_THROW(NotSupportedError, "Device does not support subgroup ballot operations");
264
265 if (!subgroups::isFormatSupportedForDevice(context, caseDef.format))
266 TCU_THROW(NotSupportedError, "Device does not support the specified format in subgroup operations");
267
268 if (caseDef.extShaderSubGroupBallotTests)
269 {
270 context.requireDeviceFunctionality("VK_EXT_shader_subgroup_ballot");
271
272 if (!subgroups::isInt64SupportedForDevice(context))
273 TCU_THROW(NotSupportedError, "Device does not support int64 data types");
274 }
275
276 if ((caseDef.opType == OPTYPE_BROADCAST_NONCONST) && !subgroups::isSubgroupBroadcastDynamicIdSupported(context))
277 TCU_THROW(NotSupportedError, "Device does not support SubgroupBroadcastDynamicId");
278
279 if (caseDef.subgroupSizeControl)
280 {
281 context.requireDeviceFunctionality("VK_EXT_subgroup_size_control");
282
283 const VkPhysicalDeviceSubgroupSizeControlFeaturesEXT& subgroupSizeControlFeatures = context.getSubgroupSizeControlFeaturesEXT();
284 const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& subgroupSizeControlProperties = context.getSubgroupSizeControlPropertiesEXT();
285
286 if (subgroupSizeControlFeatures.subgroupSizeControl == DE_FALSE)
287 TCU_THROW(NotSupportedError, "Device does not support varying subgroup sizes nor required subgroup size");
288
289 if (subgroupSizeControlFeatures.computeFullSubgroups == DE_FALSE)
290 TCU_THROW(NotSupportedError, "Device does not support full subgroups in compute shaders");
291
292 if (caseDef.requiredSubgroupSize < subgroupSizeControlProperties.minSubgroupSize
293 || caseDef.requiredSubgroupSize > subgroupSizeControlProperties.maxSubgroupSize)
294 {
295 TCU_THROW(NotSupportedError, "Unsupported subgroup size");
296 }
297
298 if ((subgroupSizeControlProperties.requiredSubgroupSizeStages & caseDef.shaderStage) != caseDef.shaderStage)
299 TCU_THROW(NotSupportedError, "Required subgroup size is not supported for shader stage");
300 }
301
302 *caseDef.geometryPointSizeSupported = subgroups::isTessellationAndGeometryPointSizeSupported(context);
303
304 if (isAllRayTracingStages(caseDef.shaderStage))
305 {
306 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
307 }
308
309 subgroups::supportedCheckShader(context, caseDef.shaderStage);
310 }
311
noSSBOtest(Context & context,const CaseDefinition caseDef)312 TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
313 {
314 const VkDeviceSize numElements = caseDef.extShaderSubGroupBallotTests ? 64u : subgroups::maxSupportedSubgroupSize();
315 const subgroups::SSBOData inputData =
316 {
317 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
318 subgroups::SSBOData::LayoutStd140, // InputDataLayoutType layout;
319 caseDef.format, // vk::VkFormat format;
320 numElements, // vk::VkDeviceSize numElements;
321 };
322
323 switch (caseDef.shaderStage)
324 {
325 case VK_SHADER_STAGE_VERTEX_BIT: return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages);
326 case VK_SHADER_STAGE_GEOMETRY_BIT: return subgroups::makeGeometryFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages);
327 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, caseDef.shaderStage);
328 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, caseDef.shaderStage);
329 default: TCU_THROW(InternalError, "Unhandled shader stage");
330 }
331 }
332
test(Context & context,const CaseDefinition caseDef)333 TestStatus test (Context& context, const CaseDefinition caseDef)
334 {
335 const VkDeviceSize numElements = caseDef.extShaderSubGroupBallotTests ? 64u : subgroups::maxSupportedSubgroupSize();
336
337 if (isAllComputeStages(caseDef.shaderStage))
338 {
339 const subgroups::SSBOData inputData =
340 {
341 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
342 subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout;
343 caseDef.format, // vk::VkFormat format;
344 numElements, // vk::VkDeviceSize numElements;
345 };
346
347 if (caseDef.subgroupSizeControl)
348 return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkCompute, caseDef.requiredSubgroupSize, VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT);
349 else
350 return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkCompute);
351 }
352 else if (isAllGraphicsStages(caseDef.shaderStage))
353 {
354 const VkShaderStageFlags stages = subgroups::getPossibleGraphicsSubgroupStages(context, caseDef.shaderStage);
355 const subgroups::SSBOData inputData =
356 {
357 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
358 subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout;
359 caseDef.format, // vk::VkFormat format;
360 numElements, // vk::VkDeviceSize numElements;
361 false, // bool isImage;
362 4u, // deUint32 binding;
363 stages, // vk::VkShaderStageFlagBits stages;
364 };
365
366 return subgroups::allStages(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, stages);
367 }
368 else if (isAllRayTracingStages(caseDef.shaderStage))
369 {
370 const VkShaderStageFlags stages = subgroups::getPossibleRayTracingSubgroupStages(context, caseDef.shaderStage);
371 const subgroups::SSBOData inputData =
372 {
373 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
374 subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout;
375 caseDef.format, // vk::VkFormat format;
376 numElements, // vk::VkDeviceSize numElements;
377 false, // bool isImage;
378 6u, // deUint32 binding;
379 stages, // vk::VkShaderStageFlagBits stages;
380 };
381
382 return subgroups::allRayTracingStages(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, stages);
383 }
384 else
385 TCU_THROW(InternalError, "Unknown stage or invalid stage set");
386 }
387 }
388
389 namespace vkt
390 {
391 namespace subgroups
392 {
createSubgroupsBallotBroadcastTests(TestContext & testCtx)393 TestCaseGroup* createSubgroupsBallotBroadcastTests (TestContext& testCtx)
394 {
395 de::MovePtr<TestCaseGroup> group (new TestCaseGroup(testCtx, "ballot_broadcast", "Subgroup ballot broadcast category tests"));
396 de::MovePtr<TestCaseGroup> graphicGroup (new TestCaseGroup(testCtx, "graphics", "Subgroup ballot broadcast category tests: graphics"));
397 de::MovePtr<TestCaseGroup> computeGroup (new TestCaseGroup(testCtx, "compute", "Subgroup ballot broadcast category tests: compute"));
398 de::MovePtr<TestCaseGroup> framebufferGroup (new TestCaseGroup(testCtx, "framebuffer", "Subgroup ballot broadcast category tests: framebuffer"));
399 de::MovePtr<TestCaseGroup> raytracingGroup (new TestCaseGroup(testCtx, "ray_tracing", "Subgroup ballot broadcast category tests: ray tracing"));
400
401 de::MovePtr<TestCaseGroup> groupARB (new TestCaseGroup(testCtx, "ext_shader_subgroup_ballot", "VK_EXT_shader_subgroup_ballot category tests"));
402 de::MovePtr<TestCaseGroup> graphicGroupARB (new TestCaseGroup(testCtx, "graphics", "Subgroup ballot broadcast category tests: graphics"));
403 de::MovePtr<TestCaseGroup> computeGroupARB (new TestCaseGroup(testCtx, "compute", "Subgroup ballot broadcast category tests: compute"));
404 de::MovePtr<TestCaseGroup> framebufferGroupARB (new TestCaseGroup(testCtx, "framebuffer", "Subgroup ballot broadcast category tests: framebuffer"));
405
406 const VkShaderStageFlags stages[] =
407 {
408 VK_SHADER_STAGE_VERTEX_BIT,
409 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
410 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
411 VK_SHADER_STAGE_GEOMETRY_BIT,
412 };
413 const deBool boolValues[] =
414 {
415 DE_FALSE,
416 DE_TRUE
417 };
418
419 {
420 const vector<VkFormat> formats = subgroups::getAllFormats();
421
422 for (size_t formatIndex = 0; formatIndex < formats.size(); ++formatIndex)
423 {
424 const VkFormat format = formats[formatIndex];
425 // Vector, boolean and double types are not supported by functions defined in VK_EXT_shader_subgroup_ballot.
426 const bool formatTypeIsSupportedARB = format == VK_FORMAT_R32_SINT || format == VK_FORMAT_R32_UINT || format == VK_FORMAT_R32_SFLOAT;
427
428 for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
429 {
430 const OpType opType = static_cast<OpType>(opTypeIndex);
431 const string name = getOpTypeCaseName(opType) + "_" + subgroups::getFormatNameForGLSL(format);
432
433 for (size_t extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(boolValues); ++extNdx)
434 {
435 const deBool extShaderSubGroupBallotTests = boolValues[extNdx];
436
437 if (extShaderSubGroupBallotTests && !formatTypeIsSupportedARB)
438 continue;
439
440 {
441 TestCaseGroup* testGroup = extShaderSubGroupBallotTests ? computeGroupARB.get() : computeGroup.get();
442 {
443 const CaseDefinition caseDef =
444 {
445 opType, // OpType opType;
446 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags shaderStage;
447 format, // VkFormat format;
448 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
449 extShaderSubGroupBallotTests, // deBool extShaderSubGroupBallotTests;
450 DE_FALSE, // deBool subgroupSizeControl;
451 0u // deUint32 requiredSubgroupSize;
452 };
453
454 addFunctionCaseWithPrograms(testGroup, name, "", supportedCheck, initPrograms, test, caseDef);
455 }
456
457 for (deUint32 subgroupSize = 1; subgroupSize <= subgroups::maxSupportedSubgroupSize(); subgroupSize *= 2)
458 {
459 const CaseDefinition caseDef =
460 {
461 opType, // OpType opType;
462 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags shaderStage;
463 format, // VkFormat format;
464 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
465 extShaderSubGroupBallotTests, // deBool extShaderSubGroupBallotTests;
466 DE_TRUE, // deBool subgroupSizeControl;
467 subgroupSize, // deUint32 requiredSubgroupSize;
468 };
469 const string testName = name + "_requiredsubgroupsize" + de::toString(subgroupSize);
470
471 addFunctionCaseWithPrograms(testGroup, testName, "", supportedCheck, initPrograms, test, caseDef);
472 }
473 }
474
475 {
476 TestCaseGroup* testGroup = extShaderSubGroupBallotTests ? graphicGroupARB.get() : graphicGroup.get();
477 const CaseDefinition caseDef =
478 {
479 opType, // OpType opType;
480 VK_SHADER_STAGE_ALL_GRAPHICS, // VkShaderStageFlags shaderStage;
481 format, // VkFormat format;
482 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
483 extShaderSubGroupBallotTests, // deBool extShaderSubGroupBallotTests;
484 DE_FALSE, // deBool subgroupSizeControl;
485 0u // deUint32 requiredSubgroupSize;
486 };
487
488 addFunctionCaseWithPrograms(testGroup, name, "", supportedCheck, initPrograms, test, caseDef);
489 }
490
491 {
492 TestCaseGroup* testGroup = extShaderSubGroupBallotTests ? framebufferGroupARB.get() : framebufferGroup.get();
493
494 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
495 {
496 const CaseDefinition caseDef =
497 {
498 opType, // OpType opType;
499 stages[stageIndex], // VkShaderStageFlags shaderStage;
500 format, // VkFormat format;
501 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
502 extShaderSubGroupBallotTests, // deBool extShaderSubGroupBallotTests;
503 DE_FALSE, // deBool subgroupSizeControl;
504 0u // deUint32 requiredSubgroupSize;
505 };
506
507 addFunctionCaseWithPrograms(testGroup, name + getShaderStageName(caseDef.shaderStage), "", supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
508 }
509 }
510 }
511 }
512 }
513 }
514
515 {
516 const vector<VkFormat> formats = subgroups::getAllRayTracingFormats();
517
518 for (size_t formatIndex = 0; formatIndex < formats.size(); ++formatIndex)
519 {
520 const VkFormat format = formats[formatIndex];
521 const string formatName = subgroups::getFormatNameForGLSL(format);
522
523 for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
524 {
525 const OpType opType = static_cast<OpType>(opTypeIndex);
526 const string name = getOpTypeCaseName(opType) + "_" + formatName;
527 const CaseDefinition caseDef =
528 {
529 opType, // OpType opType;
530 SHADER_STAGE_ALL_RAY_TRACING, // VkShaderStageFlags shaderStage;
531 format, // VkFormat format;
532 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
533 DE_FALSE, // deBool extShaderSubGroupBallotTests;
534 DE_FALSE, // deBool subgroupSizeControl;
535 0 // int requiredSubgroupSize;
536 };
537
538 addFunctionCaseWithPrograms(raytracingGroup.get(), name, "", supportedCheck, initPrograms, test, caseDef);
539 }
540 }
541 }
542
543 groupARB->addChild(graphicGroupARB.release());
544 groupARB->addChild(computeGroupARB.release());
545 groupARB->addChild(framebufferGroupARB.release());
546
547 group->addChild(graphicGroup.release());
548 group->addChild(computeGroup.release());
549 group->addChild(framebufferGroup.release());
550 group->addChild(raytracingGroup.release());
551 group->addChild(groupARB.release());
552
553 return group.release();
554 }
555 } // subgroups
556 } // vkt
557