1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 The Khronos Group Inc.
6 * Copyright (c) 2017 Codeplay Software Ltd.
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 * \brief Subgroups Tests
23 */ /*--------------------------------------------------------------------*/
25 #include "vktSubgroupsBuiltinVarTests.hpp"
26 #include "vktSubgroupsTestsUtils.hpp"
40 bool checkVertexPipelineStagesSubgroupSize(std::vector<const void*> datas,
41 deUint32 width, deUint32 subgroupSize)
43 const deUint32* data =
44 reinterpret_cast<const deUint32*>(datas[0]);
45 for (deUint32 x = 0; x < width; ++x)
47 deUint32 val = data[x * 4];
49 if (subgroupSize != val)
58 bool checkVertexPipelineStagesSubgroupInvocationID(std::vector<const void*> datas,
59 deUint32 width, deUint32 subgroupSize)
61 const deUint32* data =
62 reinterpret_cast<const deUint32*>(datas[0]);
63 vector<deUint32> subgroupInvocationHits(subgroupSize, 0);
65 for (deUint32 x = 0; x < width; ++x)
67 deUint32 subgroupInvocationID = data[(x * 4) + 1];
69 if (subgroupInvocationID >= subgroupSize)
74 subgroupInvocationHits[subgroupInvocationID]++;
77 const deUint32 totalSize = width;
79 deUint32 totalInvocationsRun = 0;
80 for (deUint32 i = 0; i < subgroupSize; ++i)
82 totalInvocationsRun += subgroupInvocationHits[i];
85 if (totalInvocationsRun != totalSize)
93 static bool checkFragmentSubgroupSize(std::vector<const void*> datas,
94 deUint32 width, deUint32 height, deUint32 subgroupSize)
96 const deUint32* data =
97 reinterpret_cast<const deUint32*>(datas[0]);
98 for (deUint32 x = 0; x < width; ++x)
100 for (deUint32 y = 0; y < height; ++y)
102 deUint32 val = data[(x * height + y) * 4];
104 if (subgroupSize != val)
114 static bool checkFragmentSubgroupInvocationID(
115 std::vector<const void*> datas, deUint32 width, deUint32 height,
116 deUint32 subgroupSize)
118 const deUint32* data =
119 reinterpret_cast<const deUint32*>(datas[0]);
120 vector<deUint32> subgroupInvocationHits(subgroupSize, 0);
122 for (deUint32 x = 0; x < width; ++x)
124 for (deUint32 y = 0; y < height; ++y)
126 deUint32 subgroupInvocationID = data[((x * height + y) * 4) + 1];
128 if (subgroupInvocationID >= subgroupSize)
133 subgroupInvocationHits[subgroupInvocationID]++;
137 const deUint32 totalSize = width * height;
139 deUint32 totalInvocationsRun = 0;
140 for (deUint32 i = 0; i < subgroupSize; ++i)
142 totalInvocationsRun += subgroupInvocationHits[i];
145 if (totalInvocationsRun != totalSize)
153 static bool checkComputeSubgroupSize(std::vector<const void*> datas,
154 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
155 deUint32 subgroupSize)
157 const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]);
159 for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
161 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
163 for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
165 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
167 for (deUint32 lY = 0; lY < localSize[1]; ++lY)
169 for (deUint32 lZ = 0; lZ < localSize[2];
172 const deUint32 globalInvocationX =
173 nX * localSize[0] + lX;
174 const deUint32 globalInvocationY =
175 nY * localSize[1] + lY;
176 const deUint32 globalInvocationZ =
177 nZ * localSize[2] + lZ;
179 const deUint32 globalSizeX =
180 numWorkgroups[0] * localSize[0];
181 const deUint32 globalSizeY =
182 numWorkgroups[1] * localSize[1];
184 const deUint32 offset =
191 if (subgroupSize != data[offset * 4])
205 static bool checkComputeSubgroupInvocationID(std::vector<const void*> datas,
206 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
207 deUint32 subgroupSize)
209 const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]);
211 for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
213 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
215 for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
217 const deUint32 totalLocalSize =
218 localSize[0] * localSize[1] * localSize[2];
219 vector<deUint32> subgroupInvocationHits(subgroupSize, 0);
221 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
223 for (deUint32 lY = 0; lY < localSize[1]; ++lY)
225 for (deUint32 lZ = 0; lZ < localSize[2];
228 const deUint32 globalInvocationX =
229 nX * localSize[0] + lX;
230 const deUint32 globalInvocationY =
231 nY * localSize[1] + lY;
232 const deUint32 globalInvocationZ =
233 nZ * localSize[2] + lZ;
235 const deUint32 globalSizeX =
236 numWorkgroups[0] * localSize[0];
237 const deUint32 globalSizeY =
238 numWorkgroups[1] * localSize[1];
240 const deUint32 offset =
247 deUint32 subgroupInvocationID = data[(offset * 4) + 1];
249 if (subgroupInvocationID >= subgroupSize)
254 subgroupInvocationHits[subgroupInvocationID]++;
259 deUint32 totalInvocationsRun = 0;
260 for (deUint32 i = 0; i < subgroupSize; ++i)
262 totalInvocationsRun += subgroupInvocationHits[i];
265 if (totalInvocationsRun != totalLocalSize)
276 static bool checkComputeNumSubgroups(std::vector<const void*> datas,
277 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
280 const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]);
282 for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
284 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
286 for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
288 const deUint32 totalLocalSize =
289 localSize[0] * localSize[1] * localSize[2];
291 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
293 for (deUint32 lY = 0; lY < localSize[1]; ++lY)
295 for (deUint32 lZ = 0; lZ < localSize[2];
298 const deUint32 globalInvocationX =
299 nX * localSize[0] + lX;
300 const deUint32 globalInvocationY =
301 nY * localSize[1] + lY;
302 const deUint32 globalInvocationZ =
303 nZ * localSize[2] + lZ;
305 const deUint32 globalSizeX =
306 numWorkgroups[0] * localSize[0];
307 const deUint32 globalSizeY =
308 numWorkgroups[1] * localSize[1];
310 const deUint32 offset =
317 deUint32 numSubgroups = data[(offset * 4) + 2];
319 if (numSubgroups > totalLocalSize)
333 static bool checkComputeSubgroupID(std::vector<const void*> datas,
334 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
337 const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]);
339 for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
341 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
343 for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
345 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
347 for (deUint32 lY = 0; lY < localSize[1]; ++lY)
349 for (deUint32 lZ = 0; lZ < localSize[2];
352 const deUint32 globalInvocationX =
353 nX * localSize[0] + lX;
354 const deUint32 globalInvocationY =
355 nY * localSize[1] + lY;
356 const deUint32 globalInvocationZ =
357 nZ * localSize[2] + lZ;
359 const deUint32 globalSizeX =
360 numWorkgroups[0] * localSize[0];
361 const deUint32 globalSizeY =
362 numWorkgroups[1] * localSize[1];
364 const deUint32 offset =
371 deUint32 numSubgroups = data[(offset * 4) + 2];
372 deUint32 subgroupID = data[(offset * 4) + 3];
374 if (subgroupID >= numSubgroups)
390 struct CaseDefinition
393 VkShaderStageFlags shaderStage;
398 void initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
400 std::ostringstream src;
401 if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
403 src << "#version 450\n"
404 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
405 << "layout(location = 0) out vec4 out_color;\n"
406 << "layout(location = 0) in highp vec4 in_position;\n"
408 << "void main (void)\n"
410 << " out_color = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 1.0f, 1.0f);\n"
411 << " gl_Position = in_position;\n"
412 << " gl_PointSize = 1.0f;\n"
415 programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
417 std::ostringstream source;
418 source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
419 << "layout(location = 0) in vec4 in_color;\n"
420 << "layout(location = 0) out uvec4 out_color;\n"
423 << " out_color = uvec4(in_color);\n"
425 programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
429 DE_FATAL("Unsupported shader stage");
433 void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
435 if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
437 std::ostringstream src;
439 src << "#version 450\n"
440 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
441 << "layout (local_size_x_id = 0, local_size_y_id = 1, "
442 "local_size_z_id = 2) in;\n"
443 << "layout(set = 0, binding = 0, std430) buffer Output\n"
445 << " uvec4 result[];\n"
448 << "void main (void)\n"
450 << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
451 << " highp uint offset = globalSize.x * ((globalSize.y * "
452 "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
453 "gl_GlobalInvocationID.x;\n"
454 << " result[offset] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, gl_NumSubgroups, gl_SubgroupID);\n"
457 programCollection.glslSources.add("comp")
458 << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
460 else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
462 programCollection.glslSources.add("vert")
463 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
465 std::ostringstream frag;
467 frag << "#version 450\n"
468 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
469 << "layout(location = 0) out uvec4 data;\n"
470 << "void main (void)\n"
472 << " data = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
475 programCollection.glslSources.add("frag")
476 << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
478 else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
480 std::ostringstream src;
482 src << "#version 450\n"
483 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
484 << "layout(set = 0, binding = 0, std430) buffer Output\n"
486 << " uvec4 result[];\n"
489 << "void main (void)\n"
491 << " result[gl_VertexIndex] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
492 << " gl_PointSize = 1.0f;\n"
495 programCollection.glslSources.add("vert")
496 << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
498 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
500 programCollection.glslSources.add("vert")
501 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
503 std::ostringstream src;
505 src << "#version 450\n"
506 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
507 << "layout(points) in;\n"
508 << "layout(points, max_vertices = 1) out;\n"
509 << "layout(set = 0, binding = 0, std430) buffer Output\n"
511 << " uvec4 result[];\n"
514 << "void main (void)\n"
516 << " result[gl_PrimitiveIDIn] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
519 programCollection.glslSources.add("geom")
520 << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
522 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
524 programCollection.glslSources.add("vert")
525 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
527 programCollection.glslSources.add("tese")
528 << glu::TessellationEvaluationSource("#version 450\nlayout(isolines) in;\nvoid main (void) {}\n");
530 std::ostringstream src;
532 src << "#version 450\n"
533 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
534 << "layout(vertices=1) out;\n"
535 << "layout(set = 0, binding = 0, std430) buffer Output\n"
537 << " uvec4 result[];\n"
540 << "void main (void)\n"
542 << " result[gl_PrimitiveID] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
545 programCollection.glslSources.add("tesc")
546 << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
548 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
550 programCollection.glslSources.add("vert")
551 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
553 programCollection.glslSources.add("tesc")
554 << glu::TessellationControlSource("#version 450\nlayout(vertices=1) out;\nvoid main (void) { for(uint i = 0; i < 4; i++) { gl_TessLevelOuter[i] = 1.0f; } }\n");
556 std::ostringstream src;
558 src << "#version 450\n"
559 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
560 << "layout(isolines) in;\n"
561 << "layout(set = 0, binding = 0, std430) buffer Output\n"
563 << " uvec4 result[];\n"
566 << "void main (void)\n"
568 << " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
571 programCollection.glslSources.add("tese")
572 << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
576 DE_FATAL("Unsupported shader stage");
580 tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
582 if (!subgroups::isSubgroupSupported(context))
583 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
585 if (!areSubgroupOperationsSupportedForStage(
586 context, caseDef.shaderStage))
588 if (areSubgroupOperationsRequiredForStage(caseDef.shaderStage))
590 return tcu::TestStatus::fail(
591 "Shader stage " + getShaderStageName(caseDef.shaderStage) +
592 " is required to support subgroup operations!");
596 TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
600 //Tests which don't use the SSBO
601 if (caseDef.noSSBO && VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
603 if ("gl_SubgroupSize" == caseDef.varName)
605 return makeVertexFrameBufferTest(
606 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
608 else if ("gl_SubgroupInvocationID" == caseDef.varName)
610 return makeVertexFrameBufferTest(
611 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
615 if ((VK_SHADER_STAGE_FRAGMENT_BIT != caseDef.shaderStage) &&
616 (VK_SHADER_STAGE_COMPUTE_BIT != caseDef.shaderStage))
618 if (!subgroups::isVertexSSBOSupportedForDevice(context))
620 TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
624 if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
626 if ("gl_SubgroupSize" == caseDef.varName)
628 return makeComputeTest(
629 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeSubgroupSize);
631 else if ("gl_SubgroupInvocationID" == caseDef.varName)
633 return makeComputeTest(
634 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeSubgroupInvocationID);
636 else if ("gl_NumSubgroups" == caseDef.varName)
638 return makeComputeTest(
639 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeNumSubgroups);
641 else if ("gl_SubgroupID" == caseDef.varName)
643 return makeComputeTest(
644 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeSubgroupID);
648 return tcu::TestStatus::fail(
649 caseDef.varName + " failed (unhandled error checking case " +
650 caseDef.varName + ")!");
653 else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
655 if ("gl_SubgroupSize" == caseDef.varName)
657 return makeFragmentTest(
658 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkFragmentSubgroupSize);
660 else if ("gl_SubgroupInvocationID" == caseDef.varName)
662 return makeFragmentTest(
663 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkFragmentSubgroupInvocationID);
667 return tcu::TestStatus::fail(
668 caseDef.varName + " failed (unhandled error checking case " +
669 caseDef.varName + ")!");
672 else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
674 if ("gl_SubgroupSize" == caseDef.varName)
676 return makeVertexTest(
677 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
679 else if ("gl_SubgroupInvocationID" == caseDef.varName)
681 return makeVertexTest(
682 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
686 return tcu::TestStatus::fail(
687 caseDef.varName + " failed (unhandled error checking case " +
688 caseDef.varName + ")!");
691 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
693 if ("gl_SubgroupSize" == caseDef.varName)
695 return makeGeometryTest(
696 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
698 else if ("gl_SubgroupInvocationID" == caseDef.varName)
700 return makeGeometryTest(
701 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
705 return tcu::TestStatus::fail(
706 caseDef.varName + " failed (unhandled error checking case " +
707 caseDef.varName + ")!");
710 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
712 if ("gl_SubgroupSize" == caseDef.varName)
714 return makeTessellationControlTest(
715 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
717 else if ("gl_SubgroupInvocationID" == caseDef.varName)
719 return makeTessellationControlTest(
720 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
724 return tcu::TestStatus::fail(
725 caseDef.varName + " failed (unhandled error checking case " +
726 caseDef.varName + ")!");
729 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
731 if ("gl_SubgroupSize" == caseDef.varName)
733 return makeTessellationEvaluationTest(
734 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
736 else if ("gl_SubgroupInvocationID" == caseDef.varName)
738 return makeTessellationEvaluationTest(
739 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
743 return tcu::TestStatus::fail(
744 caseDef.varName + " failed (unhandled error checking case " +
745 caseDef.varName + ")!");
750 TCU_THROW(InternalError, "Unhandled shader stage");
754 tcu::TestCaseGroup* createSubgroupsBuiltinVarTests(tcu::TestContext& testCtx)
756 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(
757 testCtx, "builtin_var", "Subgroup builtin variable tests"));
759 const char* const all_stages_vars[] =
762 "SubgroupInvocationID"
765 const char* const compute_only_vars[] =
771 const VkShaderStageFlags stages[] =
773 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
774 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
775 VK_SHADER_STAGE_GEOMETRY_BIT,
776 VK_SHADER_STAGE_VERTEX_BIT,
777 VK_SHADER_STAGE_FRAGMENT_BIT,
778 VK_SHADER_STAGE_COMPUTE_BIT,
781 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
783 const VkShaderStageFlags stage = stages[stageIndex];
785 for (int a = 0; a < DE_LENGTH_OF_ARRAY(all_stages_vars); ++a)
787 const std::string var = all_stages_vars[a];
789 CaseDefinition caseDef = {"gl_" + var, stage, false};
791 addFunctionCaseWithPrograms(group.get(),
792 de::toLower(var) + "_" +
793 getShaderStageName(stage), "",
794 initPrograms, test, caseDef);
796 if (VK_SHADER_STAGE_VERTEX_BIT == stage)
798 caseDef.noSSBO = true;
799 addFunctionCaseWithPrograms(group.get(),
800 de::toLower(var) + "_" +
801 getShaderStageName(stage)+"_framebuffer", "",
802 initFrameBufferPrograms, test, caseDef);
807 for (int a = 0; a < DE_LENGTH_OF_ARRAY(compute_only_vars); ++a)
809 const VkShaderStageFlags stage = VK_SHADER_STAGE_COMPUTE_BIT;
810 const std::string var = compute_only_vars[a];
812 CaseDefinition caseDef = {"gl_" + var, stage, false};
814 addFunctionCaseWithPrograms(group.get(), de::toLower(var) +
815 "_" + getShaderStageName(stage), "",
816 initPrograms, test, caseDef);
819 return group.release();