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
checkComputeOrMesh(const void * internalData,vector<const void * > datas,const deUint32 numWorkgroups[3],const deUint32 localSize[3],deUint32)68 bool checkComputeOrMesh (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::checkComputeOrMesh(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 #ifndef CTS_USES_VULKANSC
246 const bool spirv14required = (isAllRayTracingStages(caseDef.shaderStage) || isAllMeshShadingStages(caseDef.shaderStage));
247 #else
248 const bool spirv14required = false;
249 #endif // CTS_USES_VULKANSC
250 const SpirvVersion spirvVersion = spirv15required ? SPIRV_VERSION_1_5
251 : spirv14required ? SPIRV_VERSION_1_4
252 : SPIRV_VERSION_1_3;
253 const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, spirvVersion, 0u, (spirv14required && !spirv15required));
254 const string extHeader = getExtHeader(caseDef);
255 const string testSrc = getTestSrc(caseDef);
256 const string helperStr = getHelperFunctionARB(caseDef);
257
258 subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, extHeader, testSrc, helperStr);
259 }
260
supportedCheck(Context & context,CaseDefinition caseDef)261 void supportedCheck (Context& context, CaseDefinition caseDef)
262 {
263 if (!subgroups::isSubgroupSupported(context))
264 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
265
266 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BALLOT_BIT))
267 TCU_THROW(NotSupportedError, "Device does not support subgroup ballot operations");
268
269 if (!subgroups::isFormatSupportedForDevice(context, caseDef.format))
270 TCU_THROW(NotSupportedError, "Device does not support the specified format in subgroup operations");
271
272 if (caseDef.extShaderSubGroupBallotTests)
273 {
274 context.requireDeviceFunctionality("VK_EXT_shader_subgroup_ballot");
275
276 if (!subgroups::isInt64SupportedForDevice(context))
277 TCU_THROW(NotSupportedError, "Device does not support int64 data types");
278 }
279
280 if ((caseDef.opType == OPTYPE_BROADCAST_NONCONST) && !subgroups::isSubgroupBroadcastDynamicIdSupported(context))
281 TCU_THROW(NotSupportedError, "Device does not support SubgroupBroadcastDynamicId");
282
283 if (caseDef.subgroupSizeControl)
284 {
285 context.requireDeviceFunctionality("VK_EXT_subgroup_size_control");
286
287 #ifndef CTS_USES_VULKANSC
288 const VkPhysicalDeviceSubgroupSizeControlFeatures& subgroupSizeControlFeatures = context.getSubgroupSizeControlFeatures();
289 const VkPhysicalDeviceSubgroupSizeControlProperties& subgroupSizeControlProperties = context.getSubgroupSizeControlProperties();
290 #else
291 const VkPhysicalDeviceSubgroupSizeControlFeaturesEXT& subgroupSizeControlFeatures = context.getSubgroupSizeControlFeaturesEXT();
292 const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& subgroupSizeControlProperties = context.getSubgroupSizeControlPropertiesEXT();
293 #endif // CTS_USES_VULKANSC
294
295 if (subgroupSizeControlFeatures.subgroupSizeControl == DE_FALSE)
296 TCU_THROW(NotSupportedError, "Device does not support varying subgroup sizes nor required subgroup size");
297
298 if (subgroupSizeControlFeatures.computeFullSubgroups == DE_FALSE)
299 TCU_THROW(NotSupportedError, "Device does not support full subgroups in compute shaders");
300
301 if (caseDef.requiredSubgroupSize < subgroupSizeControlProperties.minSubgroupSize
302 || caseDef.requiredSubgroupSize > subgroupSizeControlProperties.maxSubgroupSize)
303 {
304 TCU_THROW(NotSupportedError, "Unsupported subgroup size");
305 }
306
307 if ((subgroupSizeControlProperties.requiredSubgroupSizeStages & caseDef.shaderStage) != caseDef.shaderStage)
308 TCU_THROW(NotSupportedError, "Required subgroup size is not supported for shader stage");
309 }
310
311 *caseDef.geometryPointSizeSupported = subgroups::isTessellationAndGeometryPointSizeSupported(context);
312
313 #ifndef CTS_USES_VULKANSC
314 if (isAllRayTracingStages(caseDef.shaderStage))
315 {
316 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
317 }
318 else if (isAllMeshShadingStages(caseDef.shaderStage))
319 {
320 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
321 context.requireDeviceFunctionality("VK_EXT_mesh_shader");
322
323 if ((caseDef.shaderStage & VK_SHADER_STAGE_TASK_BIT_EXT) != 0u)
324 {
325 const auto& features = context.getMeshShaderFeaturesEXT();
326 if (!features.taskShader)
327 TCU_THROW(NotSupportedError, "Task shaders not supported");
328 }
329 }
330 #endif // CTS_USES_VULKANSC
331
332 subgroups::supportedCheckShader(context, caseDef.shaderStage);
333 }
334
noSSBOtest(Context & context,const CaseDefinition caseDef)335 TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
336 {
337 const VkDeviceSize numElements = caseDef.extShaderSubGroupBallotTests ? 64u : subgroups::maxSupportedSubgroupSize();
338 const subgroups::SSBOData inputData =
339 {
340 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
341 subgroups::SSBOData::LayoutStd140, // InputDataLayoutType layout;
342 caseDef.format, // vk::VkFormat format;
343 numElements, // vk::VkDeviceSize numElements;
344 subgroups::SSBOData::BindingUBO, // BindingType bindingType;
345 };
346
347 switch (caseDef.shaderStage)
348 {
349 case VK_SHADER_STAGE_VERTEX_BIT: return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages);
350 case VK_SHADER_STAGE_GEOMETRY_BIT: return subgroups::makeGeometryFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages);
351 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, caseDef.shaderStage);
352 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, caseDef.shaderStage);
353 default: TCU_THROW(InternalError, "Unhandled shader stage");
354 }
355 }
356
test(Context & context,const CaseDefinition caseDef)357 TestStatus test (Context& context, const CaseDefinition caseDef)
358 {
359 const VkDeviceSize numElements = caseDef.extShaderSubGroupBallotTests ? 64u : subgroups::maxSupportedSubgroupSize();
360 const bool isCompute = isAllComputeStages(caseDef.shaderStage);
361 #ifndef CTS_USES_VULKANSC
362 const bool isMesh = isAllMeshShadingStages(caseDef.shaderStage);
363 #else
364 const bool isMesh = false;
365 #endif // CTS_USES_VULKANSC
366
367 DE_ASSERT(!(isCompute && isMesh));
368
369 if (isCompute || isMesh)
370 {
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 };
378
379 if (isCompute)
380 {
381 if (caseDef.subgroupSizeControl)
382 return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkComputeOrMesh, caseDef.requiredSubgroupSize);
383 else
384 return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkComputeOrMesh);
385 }
386 else
387 {
388 if (caseDef.subgroupSizeControl)
389 return subgroups::makeMeshTest(context, VK_FORMAT_R32_UINT, &inputData, 1, nullptr, checkComputeOrMesh, caseDef.requiredSubgroupSize);
390 else
391 return subgroups::makeMeshTest(context, VK_FORMAT_R32_UINT, &inputData, 1, nullptr, checkComputeOrMesh);
392 }
393 }
394 else if (isAllGraphicsStages(caseDef.shaderStage))
395 {
396 const VkShaderStageFlags stages = subgroups::getPossibleGraphicsSubgroupStages(context, caseDef.shaderStage);
397 const subgroups::SSBOData inputData =
398 {
399 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
400 subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout;
401 caseDef.format, // vk::VkFormat format;
402 numElements, // vk::VkDeviceSize numElements;
403 subgroups::SSBOData::BindingSSBO, // bool isImage;
404 4u, // deUint32 binding;
405 stages, // vk::VkShaderStageFlagBits stages;
406 };
407
408 return subgroups::allStages(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, stages);
409 }
410 #ifndef CTS_USES_VULKANSC
411 else if (isAllRayTracingStages(caseDef.shaderStage))
412 {
413 const VkShaderStageFlags stages = subgroups::getPossibleRayTracingSubgroupStages(context, caseDef.shaderStage);
414 const subgroups::SSBOData inputData =
415 {
416 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
417 subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout;
418 caseDef.format, // vk::VkFormat format;
419 numElements, // vk::VkDeviceSize numElements;
420 subgroups::SSBOData::BindingSSBO, // bool isImage;
421 6u, // deUint32 binding;
422 stages, // vk::VkShaderStageFlagBits stages;
423 };
424
425 return subgroups::allRayTracingStages(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, stages);
426 }
427 #endif // CTS_USES_VULKANSC
428 else
429 TCU_THROW(InternalError, "Unknown stage or invalid stage set");
430 }
431 }
432
433 namespace vkt
434 {
435 namespace subgroups
436 {
createSubgroupsBallotBroadcastTests(TestContext & testCtx)437 TestCaseGroup* createSubgroupsBallotBroadcastTests (TestContext& testCtx)
438 {
439 de::MovePtr<TestCaseGroup> group (new TestCaseGroup(testCtx, "ballot_broadcast", "Subgroup ballot broadcast category tests"));
440 de::MovePtr<TestCaseGroup> graphicGroup (new TestCaseGroup(testCtx, "graphics", "Subgroup ballot broadcast category tests: graphics"));
441 de::MovePtr<TestCaseGroup> computeGroup (new TestCaseGroup(testCtx, "compute", "Subgroup ballot broadcast category tests: compute"));
442 de::MovePtr<TestCaseGroup> framebufferGroup (new TestCaseGroup(testCtx, "framebuffer", "Subgroup ballot broadcast category tests: framebuffer"));
443 #ifndef CTS_USES_VULKANSC
444 de::MovePtr<TestCaseGroup> raytracingGroup (new TestCaseGroup(testCtx, "ray_tracing", "Subgroup ballot broadcast category tests: ray tracing"));
445 de::MovePtr<TestCaseGroup> meshGroup (new TestCaseGroup(testCtx, "mesh", "Subgroup ballot broadcast category tests: mesh"));
446 de::MovePtr<TestCaseGroup> meshGroupARB (new TestCaseGroup(testCtx, "mesh", "Subgroup ballot broadcast category tests: mesh"));
447 #endif // CTS_USES_VULKANSC
448
449 de::MovePtr<TestCaseGroup> groupARB (new TestCaseGroup(testCtx, "ext_shader_subgroup_ballot", "VK_EXT_shader_subgroup_ballot category tests"));
450 de::MovePtr<TestCaseGroup> graphicGroupARB (new TestCaseGroup(testCtx, "graphics", "Subgroup ballot broadcast category tests: graphics"));
451 de::MovePtr<TestCaseGroup> computeGroupARB (new TestCaseGroup(testCtx, "compute", "Subgroup ballot broadcast category tests: compute"));
452 de::MovePtr<TestCaseGroup> framebufferGroupARB (new TestCaseGroup(testCtx, "framebuffer", "Subgroup ballot broadcast category tests: framebuffer"));
453
454 const VkShaderStageFlags fbStages[] =
455 {
456 VK_SHADER_STAGE_VERTEX_BIT,
457 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
458 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
459 VK_SHADER_STAGE_GEOMETRY_BIT,
460 };
461 #ifndef CTS_USES_VULKANSC
462 const VkShaderStageFlags meshStages[] =
463 {
464 VK_SHADER_STAGE_MESH_BIT_EXT,
465 VK_SHADER_STAGE_TASK_BIT_EXT,
466 };
467 #endif // CTS_USES_VULKANSC
468 const deBool boolValues[] =
469 {
470 DE_FALSE,
471 DE_TRUE
472 };
473
474 {
475 const vector<VkFormat> formats = subgroups::getAllFormats();
476
477 for (size_t formatIndex = 0; formatIndex < formats.size(); ++formatIndex)
478 {
479 const VkFormat format = formats[formatIndex];
480 // Vector, boolean and double types are not supported by functions defined in VK_EXT_shader_subgroup_ballot.
481 const bool formatTypeIsSupportedARB = format == VK_FORMAT_R32_SINT || format == VK_FORMAT_R32_UINT || format == VK_FORMAT_R32_SFLOAT;
482
483 for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
484 {
485 const OpType opType = static_cast<OpType>(opTypeIndex);
486 const string name = getOpTypeCaseName(opType) + "_" + subgroups::getFormatNameForGLSL(format);
487
488 for (size_t extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(boolValues); ++extNdx)
489 {
490 const deBool extShaderSubGroupBallotTests = boolValues[extNdx];
491
492 if (extShaderSubGroupBallotTests && !formatTypeIsSupportedARB)
493 continue;
494
495 {
496 TestCaseGroup* testGroup = extShaderSubGroupBallotTests ? computeGroupARB.get() : computeGroup.get();
497 {
498 const CaseDefinition caseDef =
499 {
500 opType, // OpType opType;
501 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags shaderStage;
502 format, // VkFormat format;
503 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
504 extShaderSubGroupBallotTests, // deBool extShaderSubGroupBallotTests;
505 DE_FALSE, // deBool subgroupSizeControl;
506 0u // deUint32 requiredSubgroupSize;
507 };
508
509 addFunctionCaseWithPrograms(testGroup, name, "", supportedCheck, initPrograms, test, caseDef);
510 }
511
512 for (deUint32 subgroupSize = 1; subgroupSize <= subgroups::maxSupportedSubgroupSize(); subgroupSize *= 2)
513 {
514 const CaseDefinition caseDef =
515 {
516 opType, // OpType opType;
517 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags shaderStage;
518 format, // VkFormat format;
519 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
520 extShaderSubGroupBallotTests, // deBool extShaderSubGroupBallotTests;
521 DE_TRUE, // deBool subgroupSizeControl;
522 subgroupSize, // deUint32 requiredSubgroupSize;
523 };
524 const string testName = name + "_requiredsubgroupsize" + de::toString(subgroupSize);
525
526 addFunctionCaseWithPrograms(testGroup, testName, "", supportedCheck, initPrograms, test, caseDef);
527 }
528 }
529
530 #ifndef CTS_USES_VULKANSC
531 for (const auto& stage : meshStages)
532 {
533 const auto stageName = "_" + getShaderStageName(stage);
534
535 TestCaseGroup* testGroup = extShaderSubGroupBallotTests ? meshGroupARB.get() : meshGroup.get();
536 {
537 const CaseDefinition caseDef =
538 {
539 opType, // OpType opType;
540 stage, // VkShaderStageFlags shaderStage;
541 format, // VkFormat format;
542 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
543 extShaderSubGroupBallotTests, // deBool extShaderSubGroupBallotTests;
544 DE_FALSE, // deBool subgroupSizeControl;
545 0u // deUint32 requiredSubgroupSize;
546 };
547
548 addFunctionCaseWithPrograms(testGroup, name + stageName, "", supportedCheck, initPrograms, test, caseDef);
549 }
550
551 for (deUint32 subgroupSize = 1; subgroupSize <= subgroups::maxSupportedSubgroupSize(); subgroupSize *= 2)
552 {
553 const CaseDefinition caseDef =
554 {
555 opType, // OpType opType;
556 stage, // VkShaderStageFlags shaderStage;
557 format, // VkFormat format;
558 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
559 extShaderSubGroupBallotTests, // deBool extShaderSubGroupBallotTests;
560 DE_TRUE, // deBool subgroupSizeControl;
561 subgroupSize, // deUint32 requiredSubgroupSize;
562 };
563 const string testName = name + "_requiredsubgroupsize" + de::toString(subgroupSize) + stageName;
564
565 addFunctionCaseWithPrograms(testGroup, testName, "", supportedCheck, initPrograms, test, caseDef);
566 }
567 }
568 #endif // CTS_USES_VULKANSC
569
570 {
571 TestCaseGroup* testGroup = extShaderSubGroupBallotTests ? graphicGroupARB.get() : graphicGroup.get();
572 const CaseDefinition caseDef =
573 {
574 opType, // OpType opType;
575 VK_SHADER_STAGE_ALL_GRAPHICS, // VkShaderStageFlags shaderStage;
576 format, // VkFormat format;
577 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
578 extShaderSubGroupBallotTests, // deBool extShaderSubGroupBallotTests;
579 DE_FALSE, // deBool subgroupSizeControl;
580 0u // deUint32 requiredSubgroupSize;
581 };
582
583 addFunctionCaseWithPrograms(testGroup, name, "", supportedCheck, initPrograms, test, caseDef);
584 }
585
586 {
587 TestCaseGroup* testGroup = extShaderSubGroupBallotTests ? framebufferGroupARB.get() : framebufferGroup.get();
588
589 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(fbStages); ++stageIndex)
590 {
591 const CaseDefinition caseDef =
592 {
593 opType, // OpType opType;
594 fbStages[stageIndex], // VkShaderStageFlags shaderStage;
595 format, // VkFormat format;
596 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
597 extShaderSubGroupBallotTests, // deBool extShaderSubGroupBallotTests;
598 DE_FALSE, // deBool subgroupSizeControl;
599 0u // deUint32 requiredSubgroupSize;
600 };
601
602 addFunctionCaseWithPrograms(testGroup, name + getShaderStageName(caseDef.shaderStage), "", supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
603 }
604 }
605 }
606 }
607 }
608 }
609
610 #ifndef CTS_USES_VULKANSC
611 {
612 const vector<VkFormat> formats = subgroups::getAllRayTracingFormats();
613
614 for (size_t formatIndex = 0; formatIndex < formats.size(); ++formatIndex)
615 {
616 const VkFormat format = formats[formatIndex];
617 const string formatName = subgroups::getFormatNameForGLSL(format);
618
619 for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
620 {
621 const OpType opType = static_cast<OpType>(opTypeIndex);
622 const string name = getOpTypeCaseName(opType) + "_" + formatName;
623 const CaseDefinition caseDef =
624 {
625 opType, // OpType opType;
626 SHADER_STAGE_ALL_RAY_TRACING, // VkShaderStageFlags shaderStage;
627 format, // VkFormat format;
628 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
629 DE_FALSE, // deBool extShaderSubGroupBallotTests;
630 DE_FALSE, // deBool subgroupSizeControl;
631 0 // int requiredSubgroupSize;
632 };
633
634 addFunctionCaseWithPrograms(raytracingGroup.get(), name, "", supportedCheck, initPrograms, test, caseDef);
635 }
636 }
637 }
638 #endif // CTS_USES_VULKANSC
639
640 groupARB->addChild(graphicGroupARB.release());
641 groupARB->addChild(computeGroupARB.release());
642 groupARB->addChild(framebufferGroupARB.release());
643
644 group->addChild(graphicGroup.release());
645 group->addChild(computeGroup.release());
646 group->addChild(framebufferGroup.release());
647 #ifndef CTS_USES_VULKANSC
648 group->addChild(raytracingGroup.release());
649 group->addChild(meshGroup.release());
650 groupARB->addChild(meshGroupARB.release());
651 #endif // CTS_USES_VULKANSC
652 group->addChild(groupARB.release());
653
654 return group.release();
655 }
656 } // subgroups
657 } // vkt
658