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 "vktSubgroupsArithmeticTests.hpp"
27 #include "vktSubgroupsScanHelpers.hpp"
28 #include "vktSubgroupsTestsUtils.hpp"
29
30 #include <string>
31 #include <vector>
32
33 using namespace tcu;
34 using namespace std;
35 using namespace vk;
36 using namespace vkt;
37
38 namespace
39 {
40 enum OpType
41 {
42 OPTYPE_ADD = 0,
43 OPTYPE_MUL,
44 OPTYPE_MIN,
45 OPTYPE_MAX,
46 OPTYPE_AND,
47 OPTYPE_OR,
48 OPTYPE_XOR,
49 OPTYPE_INCLUSIVE_ADD,
50 OPTYPE_INCLUSIVE_MUL,
51 OPTYPE_INCLUSIVE_MIN,
52 OPTYPE_INCLUSIVE_MAX,
53 OPTYPE_INCLUSIVE_AND,
54 OPTYPE_INCLUSIVE_OR,
55 OPTYPE_INCLUSIVE_XOR,
56 OPTYPE_EXCLUSIVE_ADD,
57 OPTYPE_EXCLUSIVE_MUL,
58 OPTYPE_EXCLUSIVE_MIN,
59 OPTYPE_EXCLUSIVE_MAX,
60 OPTYPE_EXCLUSIVE_AND,
61 OPTYPE_EXCLUSIVE_OR,
62 OPTYPE_EXCLUSIVE_XOR,
63 OPTYPE_LAST
64 };
65
66 struct CaseDefinition
67 {
68 Operator op;
69 ScanType scanType;
70 VkShaderStageFlags shaderStage;
71 VkFormat format;
72 de::SharedPtr<bool> geometryPointSizeSupported;
73 deBool requiredSubgroupSize;
74 };
75
getOperator(OpType opType)76 static Operator getOperator (OpType opType)
77 {
78 switch (opType)
79 {
80 case OPTYPE_ADD:
81 case OPTYPE_INCLUSIVE_ADD:
82 case OPTYPE_EXCLUSIVE_ADD:
83 return OPERATOR_ADD;
84 case OPTYPE_MUL:
85 case OPTYPE_INCLUSIVE_MUL:
86 case OPTYPE_EXCLUSIVE_MUL:
87 return OPERATOR_MUL;
88 case OPTYPE_MIN:
89 case OPTYPE_INCLUSIVE_MIN:
90 case OPTYPE_EXCLUSIVE_MIN:
91 return OPERATOR_MIN;
92 case OPTYPE_MAX:
93 case OPTYPE_INCLUSIVE_MAX:
94 case OPTYPE_EXCLUSIVE_MAX:
95 return OPERATOR_MAX;
96 case OPTYPE_AND:
97 case OPTYPE_INCLUSIVE_AND:
98 case OPTYPE_EXCLUSIVE_AND:
99 return OPERATOR_AND;
100 case OPTYPE_OR:
101 case OPTYPE_INCLUSIVE_OR:
102 case OPTYPE_EXCLUSIVE_OR:
103 return OPERATOR_OR;
104 case OPTYPE_XOR:
105 case OPTYPE_INCLUSIVE_XOR:
106 case OPTYPE_EXCLUSIVE_XOR:
107 return OPERATOR_XOR;
108 default:
109 DE_FATAL("Unsupported op type");
110 return OPERATOR_ADD;
111 }
112 }
113
getScanType(OpType opType)114 static ScanType getScanType(OpType opType)
115 {
116 switch (opType)
117 {
118 case OPTYPE_ADD:
119 case OPTYPE_MUL:
120 case OPTYPE_MIN:
121 case OPTYPE_MAX:
122 case OPTYPE_AND:
123 case OPTYPE_OR:
124 case OPTYPE_XOR:
125 return SCAN_REDUCE;
126 case OPTYPE_INCLUSIVE_ADD:
127 case OPTYPE_INCLUSIVE_MUL:
128 case OPTYPE_INCLUSIVE_MIN:
129 case OPTYPE_INCLUSIVE_MAX:
130 case OPTYPE_INCLUSIVE_AND:
131 case OPTYPE_INCLUSIVE_OR:
132 case OPTYPE_INCLUSIVE_XOR:
133 return SCAN_INCLUSIVE;
134 case OPTYPE_EXCLUSIVE_ADD:
135 case OPTYPE_EXCLUSIVE_MUL:
136 case OPTYPE_EXCLUSIVE_MIN:
137 case OPTYPE_EXCLUSIVE_MAX:
138 case OPTYPE_EXCLUSIVE_AND:
139 case OPTYPE_EXCLUSIVE_OR:
140 case OPTYPE_EXCLUSIVE_XOR:
141 return SCAN_EXCLUSIVE;
142 default:
143 DE_FATAL("Unsupported op type");
144 return SCAN_REDUCE;
145 }
146 }
147
checkVertexPipelineStages(const void * internalData,vector<const void * > datas,deUint32 width,deUint32)148 static bool checkVertexPipelineStages (const void* internalData,
149 vector<const void*> datas,
150 deUint32 width,
151 deUint32)
152 {
153 DE_UNREF(internalData);
154
155 return subgroups::check(datas, width, 0x3);
156 }
157
checkCompute(const void * internalData,vector<const void * > datas,const deUint32 numWorkgroups[3],const deUint32 localSize[3],deUint32)158 static bool checkCompute (const void* internalData,
159 vector<const void*> datas,
160 const deUint32 numWorkgroups[3],
161 const deUint32 localSize[3],
162 deUint32)
163 {
164 DE_UNREF(internalData);
165
166 return subgroups::checkCompute(datas, numWorkgroups, localSize, 0x3);
167 }
168
getOpTypeName(Operator op,ScanType scanType)169 string getOpTypeName (Operator op, ScanType scanType)
170 {
171 return getScanOpName("subgroup", "", op, scanType);
172 }
173
getExtHeader(const CaseDefinition & caseDef)174 string getExtHeader (const CaseDefinition& caseDef)
175 {
176 return "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
177 "#extension GL_KHR_shader_subgroup_ballot: enable\n" +
178 subgroups::getAdditionalExtensionForFormat(caseDef.format);
179 }
180
getIndexVars(const CaseDefinition & caseDef)181 string getIndexVars (const CaseDefinition& caseDef)
182 {
183 switch (caseDef.scanType)
184 {
185 case SCAN_REDUCE: return " uint start = 0, end = gl_SubgroupSize;\n";
186 case SCAN_INCLUSIVE: return " uint start = 0, end = gl_SubgroupInvocationID + 1;\n";
187 case SCAN_EXCLUSIVE: return " uint start = 0, end = gl_SubgroupInvocationID;\n";
188 default: TCU_THROW(InternalError, "Unreachable");
189 }
190 }
191
getTestSrc(const CaseDefinition & caseDef)192 string getTestSrc (const CaseDefinition& caseDef)
193 {
194 const string indexVars = getIndexVars(caseDef);
195
196 return " uvec4 mask = subgroupBallot(true);\n"
197 + indexVars +
198 " " + subgroups::getFormatNameForGLSL(caseDef.format) + " ref = "
199 + getIdentity(caseDef.op, caseDef.format) + ";\n"
200 " tempRes = 0;\n"
201 " for (uint index = start; index < end; index++)\n"
202 " {\n"
203 " if (subgroupBallotBitExtract(mask, index))\n"
204 " {\n"
205 " ref = " + getOpOperation(caseDef.op, caseDef.format, "ref", "data[index]") + ";\n"
206 " }\n"
207 " }\n"
208 " tempRes = " + getCompare(caseDef.op, caseDef.format, "ref", getOpTypeName(caseDef.op, caseDef.scanType) + "(data[gl_SubgroupInvocationID])") + " ? 0x1 : 0;\n"
209 " if (1 == (gl_SubgroupInvocationID % 2))\n"
210 " {\n"
211 " mask = subgroupBallot(true);\n"
212 " ref = " + getIdentity(caseDef.op, caseDef.format) + ";\n"
213 " for (uint index = start; index < end; index++)\n"
214 " {\n"
215 " if (subgroupBallotBitExtract(mask, index))\n"
216 " {\n"
217 " ref = " + getOpOperation(caseDef.op, caseDef.format, "ref", "data[index]") + ";\n"
218 " }\n"
219 " }\n"
220 " tempRes |= " + getCompare(caseDef.op, caseDef.format, "ref", getOpTypeName(caseDef.op, caseDef.scanType) + "(data[gl_SubgroupInvocationID])") + " ? 0x2 : 0;\n"
221 " }\n"
222 " else\n"
223 " {\n"
224 " tempRes |= 0x2;\n"
225 " }\n";
226 }
227
initFrameBufferPrograms(SourceCollections & programCollection,CaseDefinition caseDef)228 void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
229 {
230 const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, SPIRV_VERSION_1_3, 0u);
231 const string extHeader = getExtHeader(caseDef);
232 const string testSrc = getTestSrc(caseDef);
233
234 subgroups::initStdFrameBufferPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, extHeader, testSrc, "");
235 }
236
initPrograms(SourceCollections & programCollection,CaseDefinition caseDef)237 void initPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
238 {
239 const bool spirv14required = isAllRayTracingStages(caseDef.shaderStage);
240 const SpirvVersion spirvVersion = spirv14required ? SPIRV_VERSION_1_4 : SPIRV_VERSION_1_3;
241 const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, spirvVersion, 0u);
242 const string extHeader = getExtHeader(caseDef);
243 const string testSrc = getTestSrc(caseDef);
244
245 subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, extHeader, testSrc, "");
246 }
247
supportedCheck(Context & context,CaseDefinition caseDef)248 void supportedCheck (Context& context, CaseDefinition caseDef)
249 {
250 if (!subgroups::isSubgroupSupported(context))
251 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
252
253 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_ARITHMETIC_BIT))
254 TCU_THROW(NotSupportedError, "Device does not support subgroup arithmetic operations");
255
256 if (!subgroups::isFormatSupportedForDevice(context, caseDef.format))
257 TCU_THROW(NotSupportedError, "Device does not support the specified format in subgroup operations");
258
259 if (caseDef.requiredSubgroupSize)
260 {
261 context.requireDeviceFunctionality("VK_EXT_subgroup_size_control");
262
263 const VkPhysicalDeviceSubgroupSizeControlFeaturesEXT& subgroupSizeControlFeatures = context.getSubgroupSizeControlFeaturesEXT();
264 const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& subgroupSizeControlProperties = context.getSubgroupSizeControlPropertiesEXT();
265
266 if (subgroupSizeControlFeatures.subgroupSizeControl == DE_FALSE)
267 TCU_THROW(NotSupportedError, "Device does not support varying subgroup sizes nor required subgroup size");
268
269 if (subgroupSizeControlFeatures.computeFullSubgroups == DE_FALSE)
270 TCU_THROW(NotSupportedError, "Device does not support full subgroups in compute shaders");
271
272 if ((subgroupSizeControlProperties.requiredSubgroupSizeStages & caseDef.shaderStage) != caseDef.shaderStage)
273 TCU_THROW(NotSupportedError, "Required subgroup size is not supported for shader stage");
274 }
275
276 *caseDef.geometryPointSizeSupported = subgroups::isTessellationAndGeometryPointSizeSupported(context);
277
278 if (isAllRayTracingStages(caseDef.shaderStage))
279 {
280 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
281 }
282
283 subgroups::supportedCheckShader(context, caseDef.shaderStage);
284 }
285
noSSBOtest(Context & context,const CaseDefinition caseDef)286 TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
287 {
288 const subgroups::SSBOData inputData =
289 {
290 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
291 subgroups::SSBOData::LayoutStd140, // InputDataLayoutType layout;
292 caseDef.format, // vk::VkFormat format;
293 subgroups::maxSupportedSubgroupSize(), // vk::VkDeviceSize numElements;
294 };
295
296 switch (caseDef.shaderStage)
297 {
298 case VK_SHADER_STAGE_VERTEX_BIT: return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages);
299 case VK_SHADER_STAGE_GEOMETRY_BIT: return subgroups::makeGeometryFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages);
300 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, caseDef.shaderStage);
301 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, caseDef.shaderStage);
302 default: TCU_THROW(InternalError, "Unhandled shader stage");
303 }
304 }
305
test(Context & context,const CaseDefinition caseDef)306 TestStatus test (Context& context, const CaseDefinition caseDef)
307 {
308 if (isAllComputeStages(caseDef.shaderStage))
309 {
310 const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& subgroupSizeControlProperties = context.getSubgroupSizeControlPropertiesEXT();
311 TestLog& log = context.getTestContext().getLog();
312 const subgroups::SSBOData inputData =
313 {
314 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
315 subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout;
316 caseDef.format, // vk::VkFormat format;
317 subgroups::maxSupportedSubgroupSize(), // vk::VkDeviceSize numElements;
318 };
319
320 if (caseDef.requiredSubgroupSize == DE_FALSE)
321 return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkCompute);
322
323 log << TestLog::Message << "Testing required subgroup size range [" << subgroupSizeControlProperties.minSubgroupSize << ", "
324 << subgroupSizeControlProperties.maxSubgroupSize << "]" << TestLog::EndMessage;
325
326 // According to the spec, requiredSubgroupSize must be a power-of-two integer.
327 for (deUint32 size = subgroupSizeControlProperties.minSubgroupSize; size <= subgroupSizeControlProperties.maxSubgroupSize; size *= 2)
328 {
329 TestStatus result = subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkCompute,
330 size, VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT);
331 if (result.getCode() != QP_TEST_RESULT_PASS)
332 {
333 log << TestLog::Message << "subgroupSize " << size << " failed" << TestLog::EndMessage;
334 return result;
335 }
336 }
337
338 return TestStatus::pass("OK");
339 }
340 else if (isAllGraphicsStages(caseDef.shaderStage))
341 {
342 const VkShaderStageFlags stages = subgroups::getPossibleGraphicsSubgroupStages(context, caseDef.shaderStage);
343 const subgroups::SSBOData inputData =
344 {
345 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
346 subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout;
347 caseDef.format, // vk::VkFormat format;
348 subgroups::maxSupportedSubgroupSize(), // vk::VkDeviceSize numElements;
349 false, // bool isImage;
350 4u, // deUint32 binding;
351 stages, // vk::VkShaderStageFlags stages;
352 };
353
354 return subgroups::allStages(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, stages);
355 }
356 else if (isAllRayTracingStages(caseDef.shaderStage))
357 {
358 const VkShaderStageFlags stages = subgroups::getPossibleRayTracingSubgroupStages(context, caseDef.shaderStage);
359 const subgroups::SSBOData inputData =
360 {
361 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
362 subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout;
363 caseDef.format, // vk::VkFormat format;
364 subgroups::maxSupportedSubgroupSize(), // vk::VkDeviceSize numElements;
365 false, // bool isImage;
366 6u, // deUint32 binding;
367 stages, // vk::VkShaderStageFlags stages;
368 };
369
370 return subgroups::allRayTracingStages(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, stages);
371 }
372 else
373 TCU_THROW(InternalError, "Unknown stage or invalid stage set");
374 }
375 }
376
377 namespace vkt
378 {
379 namespace subgroups
380 {
createSubgroupsArithmeticTests(TestContext & testCtx)381 TestCaseGroup* createSubgroupsArithmeticTests (TestContext& testCtx)
382 {
383 de::MovePtr<TestCaseGroup> group (new TestCaseGroup(testCtx, "arithmetic", "Subgroup arithmetic category tests"));
384 de::MovePtr<TestCaseGroup> graphicGroup (new TestCaseGroup(testCtx, "graphics", "Subgroup arithmetic category tests: graphics"));
385 de::MovePtr<TestCaseGroup> computeGroup (new TestCaseGroup(testCtx, "compute", "Subgroup arithmetic category tests: compute"));
386 de::MovePtr<TestCaseGroup> framebufferGroup (new TestCaseGroup(testCtx, "framebuffer", "Subgroup arithmetic category tests: framebuffer"));
387 de::MovePtr<TestCaseGroup> raytracingGroup (new TestCaseGroup(testCtx, "ray_tracing", "Subgroup arithmetic category tests: ray tracing"));
388 const VkShaderStageFlags stages[] =
389 {
390 VK_SHADER_STAGE_VERTEX_BIT,
391 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
392 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
393 VK_SHADER_STAGE_GEOMETRY_BIT,
394 };
395 const deBool boolValues[] =
396 {
397 DE_FALSE,
398 DE_TRUE
399 };
400
401 {
402 const vector<VkFormat> formats = subgroups::getAllFormats();
403
404 for (size_t formatIndex = 0; formatIndex < formats.size(); ++formatIndex)
405 {
406 const VkFormat format = formats[formatIndex];
407 const string formatName = subgroups::getFormatNameForGLSL(format);
408 const bool isBool = subgroups::isFormatBool(format);
409 const bool isFloat = subgroups::isFormatFloat(format);
410
411 for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
412 {
413 const OpType opType = static_cast<OpType>(opTypeIndex);
414 const Operator op = getOperator(opType);
415 const ScanType st = getScanType(opType);
416 const bool isBitwiseOp = (op == OPERATOR_AND || op == OPERATOR_OR || op == OPERATOR_XOR);
417
418 // Skip float with bitwise category.
419 if (isFloat && isBitwiseOp)
420 continue;
421
422 // Skip bool when its not the bitwise category.
423 if (isBool && !isBitwiseOp)
424 continue;
425
426 const string name = de::toLower(getOpTypeName(op, st)) + "_" + formatName;
427
428 for (size_t groupSizeNdx = 0; groupSizeNdx < DE_LENGTH_OF_ARRAY(boolValues); ++groupSizeNdx)
429 {
430 const deBool requiredSubgroupSize = boolValues[groupSizeNdx];
431 const string testName = name + (requiredSubgroupSize ? "_requiredsubgroupsize" : "");
432 const CaseDefinition caseDef =
433 {
434 op, // Operator op;
435 st, // ScanType scanType;
436 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags shaderStage;
437 format, // VkFormat format;
438 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
439 requiredSubgroupSize // deBool requiredSubgroupSize;
440 };
441
442 addFunctionCaseWithPrograms(computeGroup.get(), testName, "", supportedCheck, initPrograms, test, caseDef);
443 }
444
445 {
446 const CaseDefinition caseDef =
447 {
448 op, // Operator op;
449 st, // ScanType scanType;
450 VK_SHADER_STAGE_ALL_GRAPHICS, // VkShaderStageFlags shaderStage;
451 format, // VkFormat format;
452 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
453 DE_FALSE // deBool requiredSubgroupSize;
454 };
455
456 addFunctionCaseWithPrograms(graphicGroup.get(), name, "", supportedCheck, initPrograms, test, caseDef);
457 }
458
459 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
460 {
461 const CaseDefinition caseDef =
462 {
463 op, // Operator op;
464 st, // ScanType scanType;
465 stages[stageIndex], // VkShaderStageFlags shaderStage;
466 format, // VkFormat format;
467 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
468 DE_FALSE // deBool requiredSubgroupSize;
469 };
470 const string testName = name + "_" + getShaderStageName(caseDef.shaderStage);
471
472 addFunctionCaseWithPrograms(framebufferGroup.get(), testName, "", supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
473 }
474 }
475 }
476 }
477
478 {
479 const vector<VkFormat> formats = subgroups::getAllRayTracingFormats();
480
481 for (size_t formatIndex = 0; formatIndex < formats.size(); ++formatIndex)
482 {
483 const VkFormat format = formats[formatIndex];
484 const string formatName = subgroups::getFormatNameForGLSL(format);
485 const bool isBool = subgroups::isFormatBool(format);
486 const bool isFloat = subgroups::isFormatFloat(format);
487
488 for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
489 {
490 const OpType opType = static_cast<OpType>(opTypeIndex);
491 const Operator op = getOperator(opType);
492 const ScanType st = getScanType(opType);
493 const bool isBitwiseOp = (op == OPERATOR_AND || op == OPERATOR_OR || op == OPERATOR_XOR);
494
495 // Skip float with bitwise category.
496 if (isFloat && isBitwiseOp)
497 continue;
498
499 // Skip bool when its not the bitwise category.
500 if (isBool && !isBitwiseOp)
501 continue;
502
503 {
504 const CaseDefinition caseDef =
505 {
506 op, // Operator op;
507 st, // ScanType scanType;
508 SHADER_STAGE_ALL_RAY_TRACING, // VkShaderStageFlags shaderStage;
509 format, // VkFormat format;
510 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
511 DE_FALSE // deBool requiredSubgroupSize;
512 };
513 const string name = de::toLower(getOpTypeName(op, st)) + "_" + formatName;
514
515 addFunctionCaseWithPrograms(raytracingGroup.get(), name, "", supportedCheck, initPrograms, test, caseDef);
516 }
517 }
518 }
519 }
520
521 group->addChild(graphicGroup.release());
522 group->addChild(computeGroup.release());
523 group->addChild(framebufferGroup.release());
524 group->addChild(raytracingGroup.release());
525
526 return group.release();
527 }
528 } // subgroups
529 } // vkt
530