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 "vktSubgroupsBasicTests.hpp"
26 #include "vktSubgroupsTestsUtils.hpp"
38 static const deUint32 ELECTED_VALUE = 42u;
39 static const deUint32 UNELECTED_VALUE = 13u;
40 static const vk::VkDeviceSize SHADER_BUFFER_SIZE = 4096ull; // min(maxUniformBufferRange, maxImageDimension1D)
42 static bool checkFragmentSubgroupElect(std::vector<const void*> datas,
43 deUint32 width, deUint32 height, deUint32)
45 const deUint32* const resultData =
46 reinterpret_cast<const deUint32*>(datas[0]);
47 deUint32 poisonValuesFound = 0;
49 for (deUint32 x = 0; x < width; ++x)
51 for (deUint32 y = 0; y < height; ++y)
53 deUint32 val = resultData[y * width + x];
58 // some garbage value was found!
69 // we used an atomicly incremented counter to note how many subgroups we used for the fragment shader
70 const deUint32 numSubgroupsUsed =
71 *reinterpret_cast<const deUint32*>(datas[1]);
73 return numSubgroupsUsed == poisonValuesFound;
76 static bool checkFragmentSubgroupBarriers(std::vector<const void*> datas,
77 deUint32 width, deUint32 height, deUint32)
79 const deUint32* const resultData = reinterpret_cast<const deUint32*>(datas[0]);
81 // We used this SSBO to generate our unique value!
82 const deUint32 ref = *reinterpret_cast<const deUint32*>(datas[3]);
84 for (deUint32 x = 0; x < width; ++x)
86 for (deUint32 y = 0; y < height; ++y)
88 deUint32 val = resultData[x * height + y];
100 static bool checkFragmentSubgroupBarriersNoSSBO(std::vector<const void*> datas,
101 deUint32 width, deUint32 height, deUint32)
103 const float* const resultData = reinterpret_cast<const float*>(datas[0]);
105 for (deUint32 x = 0u; x < width; ++x)
107 for (deUint32 y = 0u; y < height; ++y)
109 const deUint32 ndx = (x * height + y) * 4u;
110 if (1.0f == resultData[ndx +2])
112 if(resultData[ndx] != resultData[ndx +1])
117 else if (resultData[ndx] != resultData[ndx +3])
127 static bool checkVertexPipelineStagesSubgroupElectNoSSBO(std::vector<const void*> datas,
128 deUint32 width, deUint32)
130 const float* const resultData = reinterpret_cast<const float*>(datas[0]);
131 float poisonValuesFound = 0.0f;
132 float numSubgroupsUsed = 0.0f;
134 for (deUint32 x = 0; x < width; ++x)
136 deUint32 val = static_cast<deUint32>(resultData[x * 2]);
137 numSubgroupsUsed += resultData[x * 2 + 1];
142 // some garbage value was found!
144 case UNELECTED_VALUE:
147 poisonValuesFound += 1.0f;
151 return numSubgroupsUsed == poisonValuesFound;
154 static bool checkVertexPipelineStagesSubgroupElect(std::vector<const void*> datas,
155 deUint32 width, deUint32)
157 const deUint32* const resultData =
158 reinterpret_cast<const deUint32*>(datas[0]);
159 deUint32 poisonValuesFound = 0;
161 for (deUint32 x = 0; x < width; ++x)
163 deUint32 val = resultData[x];
168 // some garbage value was found!
170 case UNELECTED_VALUE:
178 // we used an atomicly incremented counter to note how many subgroups we used for the vertex shader
179 const deUint32 numSubgroupsUsed =
180 *reinterpret_cast<const deUint32*>(datas[1]);
182 return numSubgroupsUsed == poisonValuesFound;
185 static bool checkVertexPipelineStagesSubgroupBarriers(std::vector<const void*> datas,
186 deUint32 width, deUint32)
188 const deUint32* const resultData = reinterpret_cast<const deUint32*>(datas[0]);
190 // We used this SSBO to generate our unique value!
191 const deUint32 ref = *reinterpret_cast<const deUint32*>(datas[3]);
193 for (deUint32 x = 0; x < width; ++x)
195 deUint32 val = resultData[x];
206 static bool checkVertexPipelineStagesSubgroupBarriersNoSSBO(std::vector<const void*> datas,
207 deUint32 width, deUint32)
209 const float* const resultData = reinterpret_cast<const float*>(datas[0]);
211 for (deUint32 x = 0u; x < width; ++x)
213 const deUint32 ndx = x*4u;
214 if (1.0f == resultData[ndx +2])
216 if(resultData[ndx] != resultData[ndx +1])
221 else if (resultData[ndx] != resultData[ndx +3])
231 static bool checkComputeSubgroupElect(std::vector<const void*> datas,
232 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
235 const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]);
237 for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
239 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
241 for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
243 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
245 for (deUint32 lY = 0; lY < localSize[1]; ++lY)
247 for (deUint32 lZ = 0; lZ < localSize[2];
250 const deUint32 globalInvocationX =
251 nX * localSize[0] + lX;
252 const deUint32 globalInvocationY =
253 nY * localSize[1] + lY;
254 const deUint32 globalInvocationZ =
255 nZ * localSize[2] + lZ;
257 const deUint32 globalSizeX =
258 numWorkgroups[0] * localSize[0];
259 const deUint32 globalSizeY =
260 numWorkgroups[1] * localSize[1];
262 const deUint32 offset =
268 if (1 != data[offset])
282 static bool checkComputeSubgroupBarriers(std::vector<const void*> datas,
283 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
286 const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]);
288 // We used this SSBO to generate our unique value!
289 const deUint32 ref = *reinterpret_cast<const deUint32*>(datas[2]);
291 for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
293 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
295 for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
297 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
299 for (deUint32 lY = 0; lY < localSize[1]; ++lY)
301 for (deUint32 lZ = 0; lZ < localSize[2];
304 const deUint32 globalInvocationX =
305 nX * localSize[0] + lX;
306 const deUint32 globalInvocationY =
307 nY * localSize[1] + lY;
308 const deUint32 globalInvocationZ =
309 nZ * localSize[2] + lZ;
311 const deUint32 globalSizeX =
312 numWorkgroups[0] * localSize[0];
313 const deUint32 globalSizeY =
314 numWorkgroups[1] * localSize[1];
316 const deUint32 offset =
323 if (ref != data[offset])
340 OPTYPE_SUBGROUP_BARRIER,
341 OPTYPE_SUBGROUP_MEMORY_BARRIER,
342 OPTYPE_SUBGROUP_MEMORY_BARRIER_BUFFER,
343 OPTYPE_SUBGROUP_MEMORY_BARRIER_SHARED,
344 OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE,
348 std::string getOpTypeName(int opType)
353 DE_FATAL("Unsupported op type");
355 return "subgroupElect";
356 case OPTYPE_SUBGROUP_BARRIER:
357 return "subgroupBarrier";
358 case OPTYPE_SUBGROUP_MEMORY_BARRIER:
359 return "subgroupMemoryBarrier";
360 case OPTYPE_SUBGROUP_MEMORY_BARRIER_BUFFER:
361 return "subgroupMemoryBarrierBuffer";
362 case OPTYPE_SUBGROUP_MEMORY_BARRIER_SHARED:
363 return "subgroupMemoryBarrierShared";
364 case OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE:
365 return "subgroupMemoryBarrierImage";
369 struct CaseDefinition
372 VkShaderStageFlags shaderStage;
376 void initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
378 std::ostringstream vertexSrc;
379 std::ostringstream fragmentSrc;
380 if(VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
382 fragmentSrc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
383 << "layout(location = 0) in vec4 in_color;\n"
384 << "layout(location = 0) out vec4 out_color;\n"
387 << " out_color = in_color;\n"
389 programCollection.glslSources.add("fragment") << glu::FragmentSource(fragmentSrc.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
391 else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
393 programCollection.glslSources.add("vert") << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
396 if (OPTYPE_ELECT == caseDef.opType)
398 if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
400 vertexSrc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
401 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
402 << "layout(location = 0) out vec4 out_color;\n"
403 << "layout(location = 0) in highp vec4 in_position;\n"
405 << "void main (void)\n"
407 << " if (subgroupElect())\n"
409 << " out_color.r = " << ELECTED_VALUE << ";\n"
410 << " out_color.g = 1.0f;\n"
414 << " out_color.r = " << UNELECTED_VALUE << ";\n"
415 << " out_color.g = 0.0f;\n"
417 << " gl_Position = in_position;\n"
418 << " gl_PointSize = 1.0f;\n"
420 programCollection.glslSources.add("vert")
421 << glu::VertexSource(vertexSrc.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
425 DE_FATAL("Unsupported shader stage");
430 std::ostringstream bdy;
431 switch (caseDef.opType)
434 DE_FATAL("Unhandled op type!");
435 case OPTYPE_SUBGROUP_BARRIER:
436 case OPTYPE_SUBGROUP_MEMORY_BARRIER:
437 case OPTYPE_SUBGROUP_MEMORY_BARRIER_BUFFER:
438 bdy << " tempResult2 = tempBuffer[id];\n"
439 << " if (subgroupElect())\n"
441 << " tempResult = value;\n"
442 << " out_color.b = 1.0f;\n"
446 << " tempResult = tempBuffer[id];\n"
448 << " " << getOpTypeName(caseDef.opType) << "();\n";
450 case OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE:
451 bdy <<"tempResult2 = imageLoad(tempImage, ivec2(id, 0)).x;\n"
452 << " if (subgroupElect())\n"
454 << " tempResult = value;\n"
455 << " out_color.b = 1.0f;\n"
459 << " tempResult = imageLoad(tempImage, ivec2(id, 0)).x;\n"
461 << " subgroupMemoryBarrierImage();\n";
466 if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
468 fragmentSrc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
469 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
470 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
471 << "layout(location = 0) out vec4 out_color;\n"
473 << "layout(set = 0, binding = 0) uniform Buffer1\n"
475 << " uint tempBuffer["<<SHADER_BUFFER_SIZE/4ull<<"];\n"
478 << "layout(set = 0, binding = 1) uniform Buffer2\n"
482 << (OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(set = 0, binding = 2, r32ui) readonly uniform highp uimage2D tempImage;\n" : "\n")
483 << "void main (void)\n"
485 << " if (gl_HelperInvocation) return;\n"
487 << " if (subgroupElect())\n"
489 << " id = uint(gl_FragCoord.x);\n"
491 << " id = subgroupBroadcastFirst(id);\n"
492 << " uint localId = id;\n"
493 << " uint tempResult = 0u;\n"
494 << " uint tempResult2 = 0u;\n"
495 << " out_color.b = 0.0f;\n"
497 << " out_color.r = float(tempResult);\n"
498 << " out_color.g = float(value);\n"
499 << " out_color.a = float(tempResult2);\n"
502 programCollection.glslSources.add("fragment") << glu::FragmentSource(fragmentSrc.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
504 else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
506 vertexSrc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
507 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
508 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
510 << "layout(location = 0) out vec4 out_color;\n"
511 << "layout(location = 0) in highp vec4 in_position;\n"
513 << "layout(set = 0, binding = 0) uniform Buffer1\n"
515 << " uint tempBuffer["<<SHADER_BUFFER_SIZE/4ull<<"];\n"
518 << "layout(set = 0, binding = 1) uniform Buffer2\n"
522 << (OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(set = 0, binding = 2, r32ui) readonly uniform highp uimage2D tempImage;\n" : "\n")
523 << "void main (void)\n"
526 << " if (subgroupElect())\n"
528 << " id = gl_VertexIndex;\n"
530 << " id = subgroupBroadcastFirst(id);\n"
531 << " uint tempResult = 0u;\n"
532 << " uint tempResult2 = 0u;\n"
533 << " out_color.b = 0.0f;\n"
535 << " out_color.r = float(tempResult);\n"
536 << " out_color.g = float(value);\n"
537 << " out_color.a = float(tempResult2);\n"
538 << " gl_Position = in_position;\n"
539 << " gl_PointSize = 1.0f;\n"
542 programCollection.glslSources.add("vert") << glu::VertexSource(vertexSrc.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
546 DE_FATAL("Unsupported shader stage");
551 void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
553 if (OPTYPE_ELECT == caseDef.opType)
555 if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
557 std::ostringstream src;
559 src << "#version 450\n"
560 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
561 << "layout (local_size_x_id = 0, local_size_y_id = 1, "
562 "local_size_z_id = 2) in;\n"
563 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
565 << " uint result[];\n"
568 << subgroups::getSharedMemoryBallotHelper()
569 << "void main (void)\n"
571 << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
572 << " highp uint offset = globalSize.x * ((globalSize.y * "
573 "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
574 "gl_GlobalInvocationID.x;\n"
575 << " uint value = " << UNELECTED_VALUE << ";\n"
576 << " if (subgroupElect())\n"
578 << " value = " << ELECTED_VALUE << ";\n"
580 << " uvec4 bits = bitCount(sharedMemoryBallot(value == " << ELECTED_VALUE << "));\n"
581 << " result[offset] = bits.x + bits.y + bits.z + bits.w;\n"
584 programCollection.glslSources.add("comp")
585 << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
587 else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
589 programCollection.glslSources.add("vert")
590 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
592 std::ostringstream frag;
594 frag << "#version 450\n"
595 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
596 << "layout(location = 0) out uint data;\n"
597 << "layout(set = 0, binding = 0, std430) buffer Buffer\n"
599 << " uint numSubgroupsExecuted;\n"
601 << "void main (void)\n"
603 << " if (gl_HelperInvocation) return;\n"
604 << " if (subgroupElect())\n"
606 << " data = " << ELECTED_VALUE << ";\n"
607 << " atomicAdd(numSubgroupsExecuted, 1);\n"
611 << " data = " << UNELECTED_VALUE << ";\n"
615 programCollection.glslSources.add("frag")
616 << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
618 else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
620 std::ostringstream src;
622 src << "#version 450\n"
623 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
624 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
626 << " uint result[];\n"
628 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
630 << " uint numSubgroupsExecuted;\n"
633 << "void main (void)\n"
635 << " if (subgroupElect())\n"
637 << " result[gl_VertexIndex] = " << ELECTED_VALUE << ";\n"
638 << " atomicAdd(numSubgroupsExecuted, 1);\n"
642 << " result[gl_VertexIndex] = " << UNELECTED_VALUE << ";\n"
646 programCollection.glslSources.add("vert")
647 << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
649 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
651 programCollection.glslSources.add("vert")
652 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
654 std::ostringstream src;
656 src << "#version 450\n"
657 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
658 << "layout(points) in;\n"
659 << "layout(points, max_vertices = 1) out;\n"
660 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
662 << " uint result[];\n"
664 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
666 << " uint numSubgroupsExecuted;\n"
669 << "void main (void)\n"
671 << " if (subgroupElect())\n"
673 << " result[gl_PrimitiveIDIn] = " << ELECTED_VALUE << ";\n"
674 << " atomicAdd(numSubgroupsExecuted, 1);\n"
678 << " result[gl_PrimitiveIDIn] = " << UNELECTED_VALUE << ";\n"
682 programCollection.glslSources.add("geom")
683 << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
685 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
687 programCollection.glslSources.add("vert")
688 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
690 programCollection.glslSources.add("tese")
691 << glu::TessellationEvaluationSource("#version 450\nlayout(isolines) in;\nvoid main (void) {}\n");
693 std::ostringstream src;
695 src << "#version 450\n"
696 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
697 << "layout(vertices=1) out;\n"
698 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
700 << " uint result[];\n"
702 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
704 << " uint numSubgroupsExecuted;\n"
707 << "void main (void)\n"
709 << " if (subgroupElect())\n"
711 << " result[gl_PrimitiveID] = " << ELECTED_VALUE << ";\n"
712 << " atomicAdd(numSubgroupsExecuted, 1);\n"
716 << " result[gl_PrimitiveID] = " << UNELECTED_VALUE << ";\n"
720 programCollection.glslSources.add("tesc")
721 << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
723 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
725 programCollection.glslSources.add("vert")
726 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
728 programCollection.glslSources.add("tesc")
729 << glu::TessellationControlSource("#version 450\nlayout(vertices=1) out;\nvoid main (void) { for(uint i = 0; i < 4; i++) { gl_TessLevelOuter[i] = 1.0f; } }\n");
731 std::ostringstream src;
733 src << "#version 450\n"
734 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
735 << "layout(isolines) in;\n"
736 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
738 << " uint result[];\n"
740 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
742 << " uint numSubgroupsExecuted;\n"
745 << "void main (void)\n"
747 << " if (subgroupElect())\n"
749 << " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = " << ELECTED_VALUE << ";\n"
750 << " atomicAdd(numSubgroupsExecuted, 1);\n"
754 << " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = " << UNELECTED_VALUE << ";\n"
758 programCollection.glslSources.add("tese")
759 << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
763 DE_FATAL("Unsupported shader stage");
768 std::ostringstream bdy;
770 switch (caseDef.opType)
773 DE_FATAL("Unhandled op type!");
774 case OPTYPE_SUBGROUP_BARRIER:
775 case OPTYPE_SUBGROUP_MEMORY_BARRIER:
776 case OPTYPE_SUBGROUP_MEMORY_BARRIER_BUFFER:
777 bdy << " if (subgroupElect())\n"
779 << " tempBuffer[id] = value;\n"
781 << " " << getOpTypeName(caseDef.opType) << "();\n"
782 << " tempResult = tempBuffer[id];\n";
784 case OPTYPE_SUBGROUP_MEMORY_BARRIER_SHARED:
785 bdy << " if (subgroupElect())\n"
787 << " tempShared[localId] = value;\n"
789 << " subgroupMemoryBarrierShared();\n"
790 << " tempResult = tempShared[localId];\n";
792 case OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE:
793 bdy << " if (subgroupElect())\n"
795 << " imageStore(tempImage, ivec2(id, 0), ivec4(value));\n"
797 << " subgroupMemoryBarrierImage();\n"
798 << " tempResult = imageLoad(tempImage, ivec2(id, 0)).x;\n";
802 if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
804 std::ostringstream src;
806 src << "#version 450\n"
807 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
808 << "layout (local_size_x_id = 0, local_size_y_id = 1, "
809 "local_size_z_id = 2) in;\n"
810 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
812 << " uint result[];\n"
814 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
816 << " uint tempBuffer[];\n"
818 << "layout(set = 0, binding = 2, std430) buffer Buffer3\n"
822 << "layout(set = 0, binding = 3, r32ui) uniform uimage2D tempImage;\n"
823 << "shared uint tempShared[gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_WorkGroupSize.z];\n"
825 << "void main (void)\n"
827 << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
828 << " highp uint offset = globalSize.x * ((globalSize.y * "
829 "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
830 "gl_GlobalInvocationID.x;\n"
831 << " uint localId = gl_SubgroupID;\n"
832 << " uint id = globalSize.x * ((globalSize.y * "
833 "gl_WorkGroupID.z) + gl_WorkGroupID.y) + "
834 "gl_WorkGroupID.x + localId;\n"
835 << " uint tempResult = 0;\n"
837 << " result[offset] = tempResult;\n"
840 programCollection.glslSources.add("comp")
841 << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
843 else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
845 programCollection.glslSources.add("vert")
846 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
848 std::ostringstream frag;
850 frag << "#version 450\n"
851 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
852 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
853 << "layout(location = 0) out uint result;\n"
854 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
856 << " uint tempBuffer[];\n"
858 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
860 << " uint subgroupID;\n"
862 << "layout(set = 0, binding = 2, std430) buffer Buffer3\n"
866 << "layout(set = 0, binding = 3, r32ui) uniform uimage2D tempImage;\n"
867 << "void main (void)\n"
869 << " if (gl_HelperInvocation) return;\n"
871 << " if (subgroupElect())\n"
873 << " id = atomicAdd(subgroupID, 1);\n"
875 << " id = subgroupBroadcastFirst(id);\n"
876 << " uint localId = id;\n"
877 << " uint tempResult = 0;\n"
879 << " result = tempResult;\n"
882 programCollection.glslSources.add("frag")
883 << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
885 else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
887 std::ostringstream src;
889 src << "#version 450\n"
890 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
891 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
892 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
894 << " uint result[];\n"
896 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
898 << " uint tempBuffer[];\n"
900 << "layout(set = 0, binding = 2, std430) buffer Buffer3\n"
902 << " uint subgroupID;\n"
904 << "layout(set = 0, binding = 3, std430) buffer Buffer4\n"
908 << "layout(set = 0, binding = 4, r32ui) uniform uimage2D tempImage;\n"
909 << "void main (void)\n"
912 << " if (subgroupElect())\n"
914 << " id = atomicAdd(subgroupID, 1);\n"
916 << " id = subgroupBroadcastFirst(id);\n"
917 << " uint localId = id;\n"
918 << " uint tempResult = 0;\n"
920 << " result[gl_VertexIndex] = tempResult;\n"
923 programCollection.glslSources.add("vert")
924 << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
926 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
928 programCollection.glslSources.add("vert")
929 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
931 std::ostringstream src;
933 src << "#version 450\n"
934 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
935 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
936 << "layout(points) in;\n"
937 << "layout(points, max_vertices = 1) out;\n"
938 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
940 << " uint result[];\n"
942 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
944 << " uint tempBuffer[];\n"
946 << "layout(set = 0, binding = 2, std430) buffer Buffer3\n"
948 << " uint subgroupID;\n"
950 << "layout(set = 0, binding = 3, std430) buffer Buffer4\n"
954 << "layout(set = 0, binding = 4, r32ui) uniform uimage2D tempImage;\n"
955 << "void main (void)\n"
958 << " if (subgroupElect())\n"
960 << " id = atomicAdd(subgroupID, 1);\n"
962 << " id = subgroupBroadcastFirst(id);\n"
963 << " uint localId = id;\n"
964 << " uint tempResult = 0;\n"
966 << " result[gl_PrimitiveIDIn] = tempResult;\n"
969 programCollection.glslSources.add("geom")
970 << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
972 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
974 programCollection.glslSources.add("vert")
975 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
977 programCollection.glslSources.add("tese")
978 << glu::TessellationEvaluationSource("#version 450\nlayout(isolines) in;\nvoid main (void) {}\n");
980 std::ostringstream src;
982 src << "#version 450\n"
983 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
984 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
985 << "layout(vertices=1) out;\n"
986 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
988 << " uint result[];\n"
990 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
992 << " uint tempBuffer[];\n"
994 << "layout(set = 0, binding = 2, std430) buffer Buffer3\n"
996 << " uint subgroupID;\n"
998 << "layout(set = 0, binding = 3, std430) buffer Buffer4\n"
1002 << "layout(set = 0, binding = 4, r32ui) uniform uimage2D tempImage;\n"
1003 << "void main (void)\n"
1005 << " uint id = 0;\n"
1006 << " if (subgroupElect())\n"
1008 << " id = atomicAdd(subgroupID, 1);\n"
1010 << " id = subgroupBroadcastFirst(id);\n"
1011 << " uint localId = id;\n"
1012 << " uint tempResult = 0;\n"
1014 << " result[gl_PrimitiveID] = tempResult;\n"
1017 programCollection.glslSources.add("tesc")
1018 << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
1020 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
1022 programCollection.glslSources.add("vert")
1023 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
1025 programCollection.glslSources.add("tesc")
1026 << glu::TessellationControlSource("#version 450\nlayout(vertices=1) out;\nvoid main (void) { for(uint i = 0; i < 4; i++) { gl_TessLevelOuter[i] = 1.0f; } }\n");
1028 std::ostringstream src;
1030 src << "#version 450\n"
1031 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1032 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
1033 << "layout(isolines) in;\n"
1034 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
1036 << " uint result[];\n"
1038 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
1040 << " uint tempBuffer[];\n"
1042 << "layout(set = 0, binding = 2, std430) buffer Buffer3\n"
1044 << " uint subgroupID;\n"
1046 << "layout(set = 0, binding = 3, std430) buffer Buffer4\n"
1050 << "layout(set = 0, binding = 4, r32ui) uniform uimage2D tempImage;\n"
1051 << "void main (void)\n"
1053 << " uint id = 0;\n"
1054 << " if (subgroupElect())\n"
1056 << " id = atomicAdd(subgroupID, 1);\n"
1058 << " id = subgroupBroadcastFirst(id);\n"
1059 << " uint localId = id;\n"
1060 << " uint tempResult = 0;\n"
1062 << " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempResult;\n"
1065 programCollection.glslSources.add("tese")
1066 << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
1070 DE_FATAL("Unsupported shader stage");
1075 tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
1077 if (!subgroups::isSubgroupSupported(context))
1078 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
1080 if (!subgroups::areSubgroupOperationsSupportedForStage(
1081 context, caseDef.shaderStage))
1083 if (subgroups::areSubgroupOperationsRequiredForStage(
1084 caseDef.shaderStage))
1086 return tcu::TestStatus::fail(
1088 subgroups::getShaderStageName(caseDef.shaderStage) +
1089 " is required to support subgroup operations!");
1093 TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
1097 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BASIC_BIT))
1099 return tcu::TestStatus::fail(
1100 "Subgroup feature " +
1101 subgroups::getSubgroupFeatureName(VK_SUBGROUP_FEATURE_BASIC_BIT) +
1102 " is a required capability!");
1105 if (OPTYPE_ELECT != caseDef.opType && VK_SHADER_STAGE_COMPUTE_BIT != caseDef.shaderStage)
1107 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BALLOT_BIT))
1109 TCU_THROW(NotSupportedError, "Subgroup basic operation non-compute stage test required that ballot operations are supported!");
1113 //Tests which don't use the SSBO
1116 if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
1118 if (OPTYPE_ELECT == caseDef.opType)
1120 return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32G32_SFLOAT,
1121 DE_NULL, 0u, checkVertexPipelineStagesSubgroupElectNoSSBO);
1125 const deUint32 inputDatasCount = OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? 3u : 2u;
1126 std::vector<subgroups::SSBOData> inputDatas (inputDatasCount);
1128 inputDatas[0].format = VK_FORMAT_R32_UINT;
1129 inputDatas[0].numElements = SHADER_BUFFER_SIZE/4ull;
1130 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1132 inputDatas[1].format = VK_FORMAT_R32_UINT;
1133 inputDatas[1].numElements = 1ull;
1134 inputDatas[1].initializeType = subgroups::SSBOData::InitializeNonZero;
1136 if(OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType )
1138 inputDatas[2].format = VK_FORMAT_R32_UINT;
1139 inputDatas[2].numElements = SHADER_BUFFER_SIZE;
1140 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNone;
1141 inputDatas[2].isImage = true;
1144 DE_ASSERT(SHADER_BUFFER_SIZE/4ull > subgroups::getSubgroupSize(context));
1145 return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32G32B32A32_SFLOAT,
1146 &inputDatas[0], inputDatasCount, checkVertexPipelineStagesSubgroupBarriersNoSSBO);
1150 if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
1152 const deUint32 inputDatasCount = OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? 3u : 2u;
1153 std::vector<subgroups::SSBOData> inputDatas (inputDatasCount);
1155 inputDatas[0].format = VK_FORMAT_R32_UINT;
1156 inputDatas[0].numElements = SHADER_BUFFER_SIZE/4ull;
1157 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1159 inputDatas[1].format = VK_FORMAT_R32_UINT;
1160 inputDatas[1].numElements = 1ull;
1161 inputDatas[1].initializeType = subgroups::SSBOData::InitializeNonZero;
1163 if(OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType )
1165 inputDatas[2].format = VK_FORMAT_R32_UINT;
1166 inputDatas[2].numElements = SHADER_BUFFER_SIZE;
1167 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNone;
1168 inputDatas[2].isImage = true;
1171 return subgroups::makeFragmentFrameBufferTest(context, VK_FORMAT_R32G32B32A32_SFLOAT,
1172 &inputDatas[0], inputDatasCount, checkFragmentSubgroupBarriersNoSSBO);
1176 if ((VK_SHADER_STAGE_FRAGMENT_BIT != caseDef.shaderStage) &&
1177 (VK_SHADER_STAGE_COMPUTE_BIT != caseDef.shaderStage))
1179 if (!subgroups::isVertexSSBOSupportedForDevice(context))
1181 TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
1185 if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
1187 if (!subgroups::isFragmentSSBOSupportedForDevice(context))
1189 TCU_THROW(NotSupportedError, "Subgroup basic operation require that the fragment stage be able to write to SSBOs!");
1192 if (OPTYPE_ELECT == caseDef.opType)
1194 subgroups::SSBOData inputData;
1195 inputData.format = VK_FORMAT_R32_UINT;
1196 inputData.numElements = 1;
1197 inputData.initializeType = subgroups::SSBOData::InitializeZero;
1199 return subgroups::makeFragmentTest(context, VK_FORMAT_R32_UINT,
1200 &inputData, 1, checkFragmentSubgroupElect);
1204 const deUint32 inputDatasCount = 4;
1205 subgroups::SSBOData inputDatas[inputDatasCount];
1206 inputDatas[0].format = VK_FORMAT_R32_UINT;
1207 inputDatas[0].numElements = SHADER_BUFFER_SIZE;
1208 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1210 inputDatas[1].format = VK_FORMAT_R32_UINT;
1211 inputDatas[1].numElements = 1;
1212 inputDatas[1].initializeType = subgroups::SSBOData::InitializeZero;
1214 inputDatas[2].format = VK_FORMAT_R32_UINT;
1215 inputDatas[2].numElements = 1;
1216 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNonZero;
1218 inputDatas[3].format = VK_FORMAT_R32_UINT;
1219 inputDatas[3].numElements = SHADER_BUFFER_SIZE;
1220 inputDatas[3].initializeType = subgroups::SSBOData::InitializeNone;
1221 inputDatas[3].isImage = true;
1223 return subgroups::makeFragmentTest(context, VK_FORMAT_R32_UINT,
1224 inputDatas, inputDatasCount, checkFragmentSubgroupBarriers);
1228 else if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
1230 if (OPTYPE_ELECT == caseDef.opType)
1232 return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT,
1233 DE_NULL, 0, checkComputeSubgroupElect);
1237 const deUint32 inputDatasCount = 3;
1238 subgroups::SSBOData inputDatas[inputDatasCount];
1239 inputDatas[0].format = VK_FORMAT_R32_UINT;
1240 inputDatas[0].numElements = SHADER_BUFFER_SIZE;
1241 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNone;
1243 inputDatas[1].format = VK_FORMAT_R32_UINT;
1244 inputDatas[1].numElements = 1;
1245 inputDatas[1].initializeType = subgroups::SSBOData::InitializeNonZero;
1247 inputDatas[2].format = VK_FORMAT_R32_UINT;
1248 inputDatas[2].numElements = SHADER_BUFFER_SIZE;
1249 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNone;
1250 inputDatas[2].isImage = true;
1252 return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT,
1253 inputDatas, inputDatasCount, checkComputeSubgroupBarriers);
1256 else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
1258 if (OPTYPE_ELECT == caseDef.opType)
1260 subgroups::SSBOData inputData;
1261 inputData.format = VK_FORMAT_R32_UINT;
1262 inputData.numElements = 1;
1263 inputData.initializeType = subgroups::SSBOData::InitializeZero;
1265 return subgroups::makeVertexTest(context, VK_FORMAT_R32_UINT,
1266 &inputData, 1, checkVertexPipelineStagesSubgroupElect);
1270 const deUint32 inputDatasCount = 4;
1271 subgroups::SSBOData inputDatas[inputDatasCount];
1272 inputDatas[0].format = VK_FORMAT_R32_UINT;
1273 inputDatas[0].numElements = SHADER_BUFFER_SIZE;
1274 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1276 inputDatas[1].format = VK_FORMAT_R32_UINT;
1277 inputDatas[1].numElements = 1;
1278 inputDatas[1].initializeType = subgroups::SSBOData::InitializeZero;
1280 inputDatas[2].format = VK_FORMAT_R32_UINT;
1281 inputDatas[2].numElements = 1;
1282 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNonZero;
1284 inputDatas[3].format = VK_FORMAT_R32_UINT;
1285 inputDatas[3].numElements = SHADER_BUFFER_SIZE;
1286 inputDatas[3].initializeType = subgroups::SSBOData::InitializeNone;
1287 inputDatas[3].isImage = true;
1289 return subgroups::makeVertexTest(context, VK_FORMAT_R32_UINT,
1290 inputDatas, inputDatasCount, checkVertexPipelineStagesSubgroupBarriers);
1293 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
1295 if (OPTYPE_ELECT == caseDef.opType)
1297 subgroups::SSBOData inputData;
1298 inputData.format = VK_FORMAT_R32_UINT;
1299 inputData.numElements = 1;
1300 inputData.initializeType = subgroups::SSBOData::InitializeZero;
1302 return subgroups::makeGeometryTest(context, VK_FORMAT_R32_UINT,
1303 &inputData, 1, checkVertexPipelineStagesSubgroupElect);
1307 const deUint32 inputDatasCount = 4;
1308 subgroups::SSBOData inputDatas[inputDatasCount];
1309 inputDatas[0].format = VK_FORMAT_R32_UINT;
1310 inputDatas[0].numElements = SHADER_BUFFER_SIZE;
1311 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1313 inputDatas[1].format = VK_FORMAT_R32_UINT;
1314 inputDatas[1].numElements = 1;
1315 inputDatas[1].initializeType = subgroups::SSBOData::InitializeZero;
1317 inputDatas[2].format = VK_FORMAT_R32_UINT;
1318 inputDatas[2].numElements = 1;
1319 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNonZero;
1321 inputDatas[3].format = VK_FORMAT_R32_UINT;
1322 inputDatas[3].numElements = SHADER_BUFFER_SIZE;
1323 inputDatas[3].initializeType = subgroups::SSBOData::InitializeNone;
1324 inputDatas[3].isImage = true;
1326 return subgroups::makeGeometryTest(context, VK_FORMAT_R32_UINT,
1327 inputDatas, inputDatasCount, checkVertexPipelineStagesSubgroupBarriers);
1330 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
1332 if (OPTYPE_ELECT == caseDef.opType)
1334 subgroups::SSBOData inputData;
1335 inputData.format = VK_FORMAT_R32_UINT;
1336 inputData.numElements = 1;
1337 inputData.initializeType = subgroups::SSBOData::InitializeZero;
1339 return subgroups::makeTessellationControlTest(context, VK_FORMAT_R32_UINT,
1340 &inputData, 1, checkVertexPipelineStagesSubgroupElect);
1344 const deUint32 inputDatasCount = 4;
1345 subgroups::SSBOData inputDatas[inputDatasCount];
1346 inputDatas[0].format = VK_FORMAT_R32_UINT;
1347 inputDatas[0].numElements = SHADER_BUFFER_SIZE;
1348 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1350 inputDatas[1].format = VK_FORMAT_R32_UINT;
1351 inputDatas[1].numElements = 1;
1352 inputDatas[1].initializeType = subgroups::SSBOData::InitializeZero;
1354 inputDatas[2].format = VK_FORMAT_R32_UINT;
1355 inputDatas[2].numElements = 1;
1356 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNonZero;
1358 inputDatas[3].format = VK_FORMAT_R32_UINT;
1359 inputDatas[3].numElements = SHADER_BUFFER_SIZE;
1360 inputDatas[3].initializeType = subgroups::SSBOData::InitializeNone;
1361 inputDatas[3].isImage = true;
1363 return subgroups::makeTessellationControlTest(context, VK_FORMAT_R32_UINT,
1364 inputDatas, inputDatasCount, checkVertexPipelineStagesSubgroupBarriers);
1367 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
1369 if (OPTYPE_ELECT == caseDef.opType)
1371 subgroups::SSBOData inputData;
1372 inputData.format = VK_FORMAT_R32_UINT;
1373 inputData.numElements = 1;
1374 inputData.initializeType = subgroups::SSBOData::InitializeZero;
1376 return subgroups::makeTessellationEvaluationTest(context, VK_FORMAT_R32_UINT,
1377 &inputData, 1, checkVertexPipelineStagesSubgroupElect);
1381 const deUint32 inputDatasCount = 4;
1382 subgroups::SSBOData inputDatas[inputDatasCount];
1383 inputDatas[0].format = VK_FORMAT_R32_UINT;
1384 inputDatas[0].numElements = SHADER_BUFFER_SIZE;
1385 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1387 inputDatas[1].format = VK_FORMAT_R32_UINT;
1388 inputDatas[1].numElements = 1;
1389 inputDatas[1].initializeType = subgroups::SSBOData::InitializeZero;
1391 inputDatas[2].format = VK_FORMAT_R32_UINT;
1392 inputDatas[2].numElements = 1;
1393 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNonZero;
1395 inputDatas[3].format = VK_FORMAT_R32_UINT;
1396 inputDatas[3].numElements = SHADER_BUFFER_SIZE;
1397 inputDatas[3].initializeType = subgroups::SSBOData::InitializeNone;
1398 inputDatas[3].isImage = true;
1400 return subgroups::makeTessellationEvaluationTest(context, VK_FORMAT_R32_UINT,
1401 inputDatas, inputDatasCount, checkVertexPipelineStagesSubgroupBarriers);
1406 TCU_THROW(InternalError, "Unhandled shader stage");
1415 tcu::TestCaseGroup* createSubgroupsBasicTests(tcu::TestContext& testCtx)
1417 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(
1418 testCtx, "basic", "Subgroup basic category tests"));
1420 const VkShaderStageFlags stages[] =
1422 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1423 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1424 VK_SHADER_STAGE_GEOMETRY_BIT,
1425 VK_SHADER_STAGE_VERTEX_BIT,
1426 VK_SHADER_STAGE_FRAGMENT_BIT,
1427 VK_SHADER_STAGE_COMPUTE_BIT
1430 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
1432 const VkShaderStageFlags stage = stages[stageIndex];
1434 for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
1436 if ((OPTYPE_SUBGROUP_MEMORY_BARRIER_SHARED == opTypeIndex) &&
1437 (VK_SHADER_STAGE_COMPUTE_BIT != stage))
1439 // Shared isn't available in non compute shaders.
1443 CaseDefinition caseDef = {opTypeIndex, stage, false};
1445 std::string op = getOpTypeName(opTypeIndex);
1447 addFunctionCaseWithPrograms(group.get(),
1449 "_" + getShaderStageName(stage), "",
1450 initPrograms, test, caseDef);
1452 if ((VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) & stage )
1454 if (OPTYPE_ELECT != caseDef.opType || VK_SHADER_STAGE_FRAGMENT_BIT != stage)
1456 caseDef.noSSBO = true;
1457 addFunctionCaseWithPrograms(group.get(),
1458 de::toLower(op) + "_" +
1459 getShaderStageName(stage)+"_framebuffer", "",
1460 initFrameBufferPrograms, test, caseDef);
1466 return group.release();