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"
494 programCollection.glslSources.add("vert")
495 << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
497 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
499 programCollection.glslSources.add("vert")
500 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
502 std::ostringstream src;
504 src << "#version 450\n"
505 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
506 << "layout(points) in;\n"
507 << "layout(points, max_vertices = 1) out;\n"
508 << "layout(set = 0, binding = 0, std430) buffer Output\n"
510 << " uvec4 result[];\n"
513 << "void main (void)\n"
515 << " result[gl_PrimitiveIDIn] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
518 programCollection.glslSources.add("geom")
519 << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
521 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
523 programCollection.glslSources.add("vert")
524 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
526 programCollection.glslSources.add("tese")
527 << glu::TessellationEvaluationSource("#version 450\nlayout(isolines) in;\nvoid main (void) {}\n");
529 std::ostringstream src;
531 src << "#version 450\n"
532 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
533 << "layout(vertices=1) out;\n"
534 << "layout(set = 0, binding = 0, std430) buffer Output\n"
536 << " uvec4 result[];\n"
539 << "void main (void)\n"
541 << " result[gl_PrimitiveID] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
544 programCollection.glslSources.add("tesc")
545 << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
547 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
549 programCollection.glslSources.add("vert")
550 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
552 programCollection.glslSources.add("tesc")
553 << glu::TessellationControlSource("#version 450\nlayout(vertices=1) out;\nvoid main (void) { for(uint i = 0; i < 4; i++) { gl_TessLevelOuter[i] = 1.0f; } }\n");
555 std::ostringstream src;
557 src << "#version 450\n"
558 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
559 << "layout(isolines) in;\n"
560 << "layout(set = 0, binding = 0, std430) buffer Output\n"
562 << " uvec4 result[];\n"
565 << "void main (void)\n"
567 << " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
570 programCollection.glslSources.add("tese")
571 << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
575 DE_FATAL("Unsupported shader stage");
579 tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
581 if (!subgroups::isSubgroupSupported(context))
582 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
584 if (!areSubgroupOperationsSupportedForStage(
585 context, caseDef.shaderStage))
587 if (areSubgroupOperationsRequiredForStage(caseDef.shaderStage))
589 return tcu::TestStatus::fail(
590 "Shader stage " + getShaderStageName(caseDef.shaderStage) +
591 " is required to support subgroup operations!");
595 TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
599 //Tests which don't use the SSBO
600 if (caseDef.noSSBO && VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
602 if ("gl_SubgroupSize" == caseDef.varName)
604 return makeVertexFrameBufferTest(
605 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
607 else if ("gl_SubgroupInvocationID" == caseDef.varName)
609 return makeVertexFrameBufferTest(
610 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
614 if ((VK_SHADER_STAGE_FRAGMENT_BIT != caseDef.shaderStage) &&
615 (VK_SHADER_STAGE_COMPUTE_BIT != caseDef.shaderStage))
617 if (!subgroups::isVertexSSBOSupportedForDevice(context))
619 TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
623 if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
625 if ("gl_SubgroupSize" == caseDef.varName)
627 return makeComputeTest(
628 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeSubgroupSize);
630 else if ("gl_SubgroupInvocationID" == caseDef.varName)
632 return makeComputeTest(
633 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeSubgroupInvocationID);
635 else if ("gl_NumSubgroups" == caseDef.varName)
637 return makeComputeTest(
638 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeNumSubgroups);
640 else if ("gl_SubgroupID" == caseDef.varName)
642 return makeComputeTest(
643 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeSubgroupID);
647 return tcu::TestStatus::fail(
648 caseDef.varName + " failed (unhandled error checking case " +
649 caseDef.varName + ")!");
652 else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
654 if ("gl_SubgroupSize" == caseDef.varName)
656 return makeFragmentTest(
657 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkFragmentSubgroupSize);
659 else if ("gl_SubgroupInvocationID" == caseDef.varName)
661 return makeFragmentTest(
662 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkFragmentSubgroupInvocationID);
666 return tcu::TestStatus::fail(
667 caseDef.varName + " failed (unhandled error checking case " +
668 caseDef.varName + ")!");
671 else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
673 if ("gl_SubgroupSize" == caseDef.varName)
675 return makeVertexTest(
676 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
678 else if ("gl_SubgroupInvocationID" == caseDef.varName)
680 return makeVertexTest(
681 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
685 return tcu::TestStatus::fail(
686 caseDef.varName + " failed (unhandled error checking case " +
687 caseDef.varName + ")!");
690 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
692 if ("gl_SubgroupSize" == caseDef.varName)
694 return makeGeometryTest(
695 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
697 else if ("gl_SubgroupInvocationID" == caseDef.varName)
699 return makeGeometryTest(
700 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
704 return tcu::TestStatus::fail(
705 caseDef.varName + " failed (unhandled error checking case " +
706 caseDef.varName + ")!");
709 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
711 if ("gl_SubgroupSize" == caseDef.varName)
713 return makeTessellationControlTest(
714 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
716 else if ("gl_SubgroupInvocationID" == caseDef.varName)
718 return makeTessellationControlTest(
719 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
723 return tcu::TestStatus::fail(
724 caseDef.varName + " failed (unhandled error checking case " +
725 caseDef.varName + ")!");
728 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
730 if ("gl_SubgroupSize" == caseDef.varName)
732 return makeTessellationEvaluationTest(
733 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
735 else if ("gl_SubgroupInvocationID" == caseDef.varName)
737 return makeTessellationEvaluationTest(
738 context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
742 return tcu::TestStatus::fail(
743 caseDef.varName + " failed (unhandled error checking case " +
744 caseDef.varName + ")!");
749 TCU_THROW(InternalError, "Unhandled shader stage");
753 tcu::TestCaseGroup* createSubgroupsBuiltinVarTests(tcu::TestContext& testCtx)
755 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(
756 testCtx, "builtin_var", "Subgroup builtin variable tests"));
758 const char* const all_stages_vars[] =
761 "SubgroupInvocationID"
764 const char* const compute_only_vars[] =
770 const VkShaderStageFlags stages[] =
772 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
773 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
774 VK_SHADER_STAGE_GEOMETRY_BIT,
775 VK_SHADER_STAGE_VERTEX_BIT,
776 VK_SHADER_STAGE_FRAGMENT_BIT,
777 VK_SHADER_STAGE_COMPUTE_BIT,
780 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
782 const VkShaderStageFlags stage = stages[stageIndex];
784 for (int a = 0; a < DE_LENGTH_OF_ARRAY(all_stages_vars); ++a)
786 const std::string var = all_stages_vars[a];
788 CaseDefinition caseDef = {"gl_" + var, stage, false};
790 addFunctionCaseWithPrograms(group.get(),
791 de::toLower(var) + "_" +
792 getShaderStageName(stage), "",
793 initPrograms, test, caseDef);
795 if (VK_SHADER_STAGE_VERTEX_BIT == stage)
797 caseDef.noSSBO = true;
798 addFunctionCaseWithPrograms(group.get(),
799 de::toLower(var) + "_" +
800 getShaderStageName(stage)+"_framebuffer", "",
801 initFrameBufferPrograms, test, caseDef);
806 for (int a = 0; a < DE_LENGTH_OF_ARRAY(compute_only_vars); ++a)
808 const VkShaderStageFlags stage = VK_SHADER_STAGE_COMPUTE_BIT;
809 const std::string var = compute_only_vars[a];
811 CaseDefinition caseDef = {"gl_" + var, stage, false};
813 addFunctionCaseWithPrograms(group.get(), de::toLower(var) +
814 "_" + getShaderStageName(stage), "",
815 initPrograms, test, caseDef);
818 return group.release();