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"
644 << " gl_PointSize = 1.0f;\n"
647 programCollection.glslSources.add("vert")
648 << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
650 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
652 programCollection.glslSources.add("vert")
653 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
655 std::ostringstream src;
657 src << "#version 450\n"
658 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
659 << "layout(points) in;\n"
660 << "layout(points, max_vertices = 1) out;\n"
661 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
663 << " uint result[];\n"
665 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
667 << " uint numSubgroupsExecuted;\n"
670 << "void main (void)\n"
672 << " if (subgroupElect())\n"
674 << " result[gl_PrimitiveIDIn] = " << ELECTED_VALUE << ";\n"
675 << " atomicAdd(numSubgroupsExecuted, 1);\n"
679 << " result[gl_PrimitiveIDIn] = " << UNELECTED_VALUE << ";\n"
683 programCollection.glslSources.add("geom")
684 << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
686 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
688 programCollection.glslSources.add("vert")
689 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
691 programCollection.glslSources.add("tese")
692 << glu::TessellationEvaluationSource("#version 450\nlayout(isolines) in;\nvoid main (void) {}\n");
694 std::ostringstream src;
696 src << "#version 450\n"
697 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
698 << "layout(vertices=1) out;\n"
699 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
701 << " uint result[];\n"
703 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
705 << " uint numSubgroupsExecuted;\n"
708 << "void main (void)\n"
710 << " if (subgroupElect())\n"
712 << " result[gl_PrimitiveID] = " << ELECTED_VALUE << ";\n"
713 << " atomicAdd(numSubgroupsExecuted, 1);\n"
717 << " result[gl_PrimitiveID] = " << UNELECTED_VALUE << ";\n"
721 programCollection.glslSources.add("tesc")
722 << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
724 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
726 programCollection.glslSources.add("vert")
727 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
729 programCollection.glslSources.add("tesc")
730 << glu::TessellationControlSource("#version 450\nlayout(vertices=1) out;\nvoid main (void) { for(uint i = 0; i < 4; i++) { gl_TessLevelOuter[i] = 1.0f; } }\n");
732 std::ostringstream src;
734 src << "#version 450\n"
735 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
736 << "layout(isolines) in;\n"
737 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
739 << " uint result[];\n"
741 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
743 << " uint numSubgroupsExecuted;\n"
746 << "void main (void)\n"
748 << " if (subgroupElect())\n"
750 << " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = " << ELECTED_VALUE << ";\n"
751 << " atomicAdd(numSubgroupsExecuted, 1);\n"
755 << " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = " << UNELECTED_VALUE << ";\n"
759 programCollection.glslSources.add("tese")
760 << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
764 DE_FATAL("Unsupported shader stage");
769 std::ostringstream bdy;
771 switch (caseDef.opType)
774 DE_FATAL("Unhandled op type!");
775 case OPTYPE_SUBGROUP_BARRIER:
776 case OPTYPE_SUBGROUP_MEMORY_BARRIER:
777 case OPTYPE_SUBGROUP_MEMORY_BARRIER_BUFFER:
778 bdy << " if (subgroupElect())\n"
780 << " tempBuffer[id] = value;\n"
782 << " " << getOpTypeName(caseDef.opType) << "();\n"
783 << " tempResult = tempBuffer[id];\n";
785 case OPTYPE_SUBGROUP_MEMORY_BARRIER_SHARED:
786 bdy << " if (subgroupElect())\n"
788 << " tempShared[localId] = value;\n"
790 << " subgroupMemoryBarrierShared();\n"
791 << " tempResult = tempShared[localId];\n";
793 case OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE:
794 bdy << " if (subgroupElect())\n"
796 << " imageStore(tempImage, ivec2(id, 0), ivec4(value));\n"
798 << " subgroupMemoryBarrierImage();\n"
799 << " tempResult = imageLoad(tempImage, ivec2(id, 0)).x;\n";
803 if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
805 std::ostringstream src;
807 src << "#version 450\n"
808 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
809 << "layout (local_size_x_id = 0, local_size_y_id = 1, "
810 "local_size_z_id = 2) in;\n"
811 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
813 << " uint result[];\n"
815 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
817 << " uint tempBuffer[];\n"
819 << "layout(set = 0, binding = 2, std430) buffer Buffer3\n"
823 << "layout(set = 0, binding = 3, r32ui) uniform uimage2D tempImage;\n"
824 << "shared uint tempShared[gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_WorkGroupSize.z];\n"
826 << "void main (void)\n"
828 << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
829 << " highp uint offset = globalSize.x * ((globalSize.y * "
830 "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
831 "gl_GlobalInvocationID.x;\n"
832 << " uint localId = gl_SubgroupID;\n"
833 << " uint id = globalSize.x * ((globalSize.y * "
834 "gl_WorkGroupID.z) + gl_WorkGroupID.y) + "
835 "gl_WorkGroupID.x + localId;\n"
836 << " uint tempResult = 0;\n"
838 << " result[offset] = tempResult;\n"
841 programCollection.glslSources.add("comp")
842 << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
844 else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
846 programCollection.glslSources.add("vert")
847 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
849 std::ostringstream frag;
851 frag << "#version 450\n"
852 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
853 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
854 << "layout(location = 0) out uint result;\n"
855 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
857 << " uint tempBuffer[];\n"
859 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
861 << " uint subgroupID;\n"
863 << "layout(set = 0, binding = 2, std430) buffer Buffer3\n"
867 << "layout(set = 0, binding = 3, r32ui) uniform uimage2D tempImage;\n"
868 << "void main (void)\n"
870 << " if (gl_HelperInvocation) return;\n"
872 << " if (subgroupElect())\n"
874 << " id = atomicAdd(subgroupID, 1);\n"
876 << " id = subgroupBroadcastFirst(id);\n"
877 << " uint localId = id;\n"
878 << " uint tempResult = 0;\n"
880 << " result = tempResult;\n"
883 programCollection.glslSources.add("frag")
884 << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
886 else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
888 std::ostringstream src;
890 src << "#version 450\n"
891 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
892 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
893 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
895 << " uint result[];\n"
897 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
899 << " uint tempBuffer[];\n"
901 << "layout(set = 0, binding = 2, std430) buffer Buffer3\n"
903 << " uint subgroupID;\n"
905 << "layout(set = 0, binding = 3, std430) buffer Buffer4\n"
909 << "layout(set = 0, binding = 4, r32ui) uniform uimage2D tempImage;\n"
910 << "void main (void)\n"
913 << " if (subgroupElect())\n"
915 << " id = atomicAdd(subgroupID, 1);\n"
917 << " id = subgroupBroadcastFirst(id);\n"
918 << " uint localId = id;\n"
919 << " uint tempResult = 0;\n"
921 << " result[gl_VertexIndex] = tempResult;\n"
922 << " gl_PointSize = 1.0f;\n"
925 programCollection.glslSources.add("vert")
926 << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
928 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
930 programCollection.glslSources.add("vert")
931 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
933 std::ostringstream src;
935 src << "#version 450\n"
936 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
937 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
938 << "layout(points) in;\n"
939 << "layout(points, max_vertices = 1) out;\n"
940 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
942 << " uint result[];\n"
944 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
946 << " uint tempBuffer[];\n"
948 << "layout(set = 0, binding = 2, std430) buffer Buffer3\n"
950 << " uint subgroupID;\n"
952 << "layout(set = 0, binding = 3, std430) buffer Buffer4\n"
956 << "layout(set = 0, binding = 4, r32ui) uniform uimage2D tempImage;\n"
957 << "void main (void)\n"
960 << " if (subgroupElect())\n"
962 << " id = atomicAdd(subgroupID, 1);\n"
964 << " id = subgroupBroadcastFirst(id);\n"
965 << " uint localId = id;\n"
966 << " uint tempResult = 0;\n"
968 << " result[gl_PrimitiveIDIn] = tempResult;\n"
971 programCollection.glslSources.add("geom")
972 << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
974 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
976 programCollection.glslSources.add("vert")
977 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
979 programCollection.glslSources.add("tese")
980 << glu::TessellationEvaluationSource("#version 450\nlayout(isolines) in;\nvoid main (void) {}\n");
982 std::ostringstream src;
984 src << "#version 450\n"
985 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
986 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
987 << "layout(vertices=1) out;\n"
988 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
990 << " uint result[];\n"
992 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
994 << " uint tempBuffer[];\n"
996 << "layout(set = 0, binding = 2, std430) buffer Buffer3\n"
998 << " uint subgroupID;\n"
1000 << "layout(set = 0, binding = 3, std430) buffer Buffer4\n"
1004 << "layout(set = 0, binding = 4, r32ui) uniform uimage2D tempImage;\n"
1005 << "void main (void)\n"
1007 << " uint id = 0;\n"
1008 << " if (subgroupElect())\n"
1010 << " id = atomicAdd(subgroupID, 1);\n"
1012 << " id = subgroupBroadcastFirst(id);\n"
1013 << " uint localId = id;\n"
1014 << " uint tempResult = 0;\n"
1016 << " result[gl_PrimitiveID] = tempResult;\n"
1019 programCollection.glslSources.add("tesc")
1020 << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
1022 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
1024 programCollection.glslSources.add("vert")
1025 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
1027 programCollection.glslSources.add("tesc")
1028 << glu::TessellationControlSource("#version 450\nlayout(vertices=1) out;\nvoid main (void) { for(uint i = 0; i < 4; i++) { gl_TessLevelOuter[i] = 1.0f; } }\n");
1030 std::ostringstream src;
1032 src << "#version 450\n"
1033 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1034 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
1035 << "layout(isolines) in;\n"
1036 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
1038 << " uint result[];\n"
1040 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
1042 << " uint tempBuffer[];\n"
1044 << "layout(set = 0, binding = 2, std430) buffer Buffer3\n"
1046 << " uint subgroupID;\n"
1048 << "layout(set = 0, binding = 3, std430) buffer Buffer4\n"
1052 << "layout(set = 0, binding = 4, r32ui) uniform uimage2D tempImage;\n"
1053 << "void main (void)\n"
1055 << " uint id = 0;\n"
1056 << " if (subgroupElect())\n"
1058 << " id = atomicAdd(subgroupID, 1);\n"
1060 << " id = subgroupBroadcastFirst(id);\n"
1061 << " uint localId = id;\n"
1062 << " uint tempResult = 0;\n"
1064 << " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempResult;\n"
1067 programCollection.glslSources.add("tese")
1068 << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
1072 DE_FATAL("Unsupported shader stage");
1077 tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
1079 if (!subgroups::isSubgroupSupported(context))
1080 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
1082 if (!subgroups::areSubgroupOperationsSupportedForStage(
1083 context, caseDef.shaderStage))
1085 if (subgroups::areSubgroupOperationsRequiredForStage(
1086 caseDef.shaderStage))
1088 return tcu::TestStatus::fail(
1090 subgroups::getShaderStageName(caseDef.shaderStage) +
1091 " is required to support subgroup operations!");
1095 TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
1099 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BASIC_BIT))
1101 return tcu::TestStatus::fail(
1102 "Subgroup feature " +
1103 subgroups::getSubgroupFeatureName(VK_SUBGROUP_FEATURE_BASIC_BIT) +
1104 " is a required capability!");
1107 if (OPTYPE_ELECT != caseDef.opType && VK_SHADER_STAGE_COMPUTE_BIT != caseDef.shaderStage)
1109 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BALLOT_BIT))
1111 TCU_THROW(NotSupportedError, "Subgroup basic operation non-compute stage test required that ballot operations are supported!");
1115 //Tests which don't use the SSBO
1118 if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
1120 if (OPTYPE_ELECT == caseDef.opType)
1122 return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32G32_SFLOAT,
1123 DE_NULL, 0u, checkVertexPipelineStagesSubgroupElectNoSSBO);
1127 const deUint32 inputDatasCount = OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? 3u : 2u;
1128 std::vector<subgroups::SSBOData> inputDatas (inputDatasCount);
1130 inputDatas[0].format = VK_FORMAT_R32_UINT;
1131 inputDatas[0].numElements = SHADER_BUFFER_SIZE/4ull;
1132 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1134 inputDatas[1].format = VK_FORMAT_R32_UINT;
1135 inputDatas[1].numElements = 1ull;
1136 inputDatas[1].initializeType = subgroups::SSBOData::InitializeNonZero;
1138 if(OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType )
1140 inputDatas[2].format = VK_FORMAT_R32_UINT;
1141 inputDatas[2].numElements = SHADER_BUFFER_SIZE;
1142 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNone;
1143 inputDatas[2].isImage = true;
1146 DE_ASSERT(SHADER_BUFFER_SIZE/4ull > subgroups::getSubgroupSize(context));
1147 return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32G32B32A32_SFLOAT,
1148 &inputDatas[0], inputDatasCount, checkVertexPipelineStagesSubgroupBarriersNoSSBO);
1152 if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
1154 const deUint32 inputDatasCount = OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? 3u : 2u;
1155 std::vector<subgroups::SSBOData> inputDatas (inputDatasCount);
1157 inputDatas[0].format = VK_FORMAT_R32_UINT;
1158 inputDatas[0].numElements = SHADER_BUFFER_SIZE/4ull;
1159 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1161 inputDatas[1].format = VK_FORMAT_R32_UINT;
1162 inputDatas[1].numElements = 1ull;
1163 inputDatas[1].initializeType = subgroups::SSBOData::InitializeNonZero;
1165 if(OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType )
1167 inputDatas[2].format = VK_FORMAT_R32_UINT;
1168 inputDatas[2].numElements = SHADER_BUFFER_SIZE;
1169 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNone;
1170 inputDatas[2].isImage = true;
1173 return subgroups::makeFragmentFrameBufferTest(context, VK_FORMAT_R32G32B32A32_SFLOAT,
1174 &inputDatas[0], inputDatasCount, checkFragmentSubgroupBarriersNoSSBO);
1178 if ((VK_SHADER_STAGE_FRAGMENT_BIT != caseDef.shaderStage) &&
1179 (VK_SHADER_STAGE_COMPUTE_BIT != caseDef.shaderStage))
1181 if (!subgroups::isVertexSSBOSupportedForDevice(context))
1183 TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
1187 if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
1189 if (!subgroups::isFragmentSSBOSupportedForDevice(context))
1191 TCU_THROW(NotSupportedError, "Subgroup basic operation require that the fragment stage be able to write to SSBOs!");
1194 if (OPTYPE_ELECT == caseDef.opType)
1196 subgroups::SSBOData inputData;
1197 inputData.format = VK_FORMAT_R32_UINT;
1198 inputData.numElements = 1;
1199 inputData.initializeType = subgroups::SSBOData::InitializeZero;
1201 return subgroups::makeFragmentTest(context, VK_FORMAT_R32_UINT,
1202 &inputData, 1, checkFragmentSubgroupElect);
1206 const deUint32 inputDatasCount = 4;
1207 subgroups::SSBOData inputDatas[inputDatasCount];
1208 inputDatas[0].format = VK_FORMAT_R32_UINT;
1209 inputDatas[0].numElements = SHADER_BUFFER_SIZE;
1210 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1212 inputDatas[1].format = VK_FORMAT_R32_UINT;
1213 inputDatas[1].numElements = 1;
1214 inputDatas[1].initializeType = subgroups::SSBOData::InitializeZero;
1216 inputDatas[2].format = VK_FORMAT_R32_UINT;
1217 inputDatas[2].numElements = 1;
1218 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNonZero;
1220 inputDatas[3].format = VK_FORMAT_R32_UINT;
1221 inputDatas[3].numElements = SHADER_BUFFER_SIZE;
1222 inputDatas[3].initializeType = subgroups::SSBOData::InitializeNone;
1223 inputDatas[3].isImage = true;
1225 return subgroups::makeFragmentTest(context, VK_FORMAT_R32_UINT,
1226 inputDatas, inputDatasCount, checkFragmentSubgroupBarriers);
1230 else if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
1232 if (OPTYPE_ELECT == caseDef.opType)
1234 return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT,
1235 DE_NULL, 0, checkComputeSubgroupElect);
1239 const deUint32 inputDatasCount = 3;
1240 subgroups::SSBOData inputDatas[inputDatasCount];
1241 inputDatas[0].format = VK_FORMAT_R32_UINT;
1242 inputDatas[0].numElements = SHADER_BUFFER_SIZE;
1243 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNone;
1245 inputDatas[1].format = VK_FORMAT_R32_UINT;
1246 inputDatas[1].numElements = 1;
1247 inputDatas[1].initializeType = subgroups::SSBOData::InitializeNonZero;
1249 inputDatas[2].format = VK_FORMAT_R32_UINT;
1250 inputDatas[2].numElements = SHADER_BUFFER_SIZE;
1251 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNone;
1252 inputDatas[2].isImage = true;
1254 return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT,
1255 inputDatas, inputDatasCount, checkComputeSubgroupBarriers);
1258 else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
1260 if (OPTYPE_ELECT == caseDef.opType)
1262 subgroups::SSBOData inputData;
1263 inputData.format = VK_FORMAT_R32_UINT;
1264 inputData.numElements = 1;
1265 inputData.initializeType = subgroups::SSBOData::InitializeZero;
1267 return subgroups::makeVertexTest(context, VK_FORMAT_R32_UINT,
1268 &inputData, 1, checkVertexPipelineStagesSubgroupElect);
1272 const deUint32 inputDatasCount = 4;
1273 subgroups::SSBOData inputDatas[inputDatasCount];
1274 inputDatas[0].format = VK_FORMAT_R32_UINT;
1275 inputDatas[0].numElements = SHADER_BUFFER_SIZE;
1276 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1278 inputDatas[1].format = VK_FORMAT_R32_UINT;
1279 inputDatas[1].numElements = 1;
1280 inputDatas[1].initializeType = subgroups::SSBOData::InitializeZero;
1282 inputDatas[2].format = VK_FORMAT_R32_UINT;
1283 inputDatas[2].numElements = 1;
1284 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNonZero;
1286 inputDatas[3].format = VK_FORMAT_R32_UINT;
1287 inputDatas[3].numElements = SHADER_BUFFER_SIZE;
1288 inputDatas[3].initializeType = subgroups::SSBOData::InitializeNone;
1289 inputDatas[3].isImage = true;
1291 return subgroups::makeVertexTest(context, VK_FORMAT_R32_UINT,
1292 inputDatas, inputDatasCount, checkVertexPipelineStagesSubgroupBarriers);
1295 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
1297 if (OPTYPE_ELECT == caseDef.opType)
1299 subgroups::SSBOData inputData;
1300 inputData.format = VK_FORMAT_R32_UINT;
1301 inputData.numElements = 1;
1302 inputData.initializeType = subgroups::SSBOData::InitializeZero;
1304 return subgroups::makeGeometryTest(context, VK_FORMAT_R32_UINT,
1305 &inputData, 1, checkVertexPipelineStagesSubgroupElect);
1309 const deUint32 inputDatasCount = 4;
1310 subgroups::SSBOData inputDatas[inputDatasCount];
1311 inputDatas[0].format = VK_FORMAT_R32_UINT;
1312 inputDatas[0].numElements = SHADER_BUFFER_SIZE;
1313 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1315 inputDatas[1].format = VK_FORMAT_R32_UINT;
1316 inputDatas[1].numElements = 1;
1317 inputDatas[1].initializeType = subgroups::SSBOData::InitializeZero;
1319 inputDatas[2].format = VK_FORMAT_R32_UINT;
1320 inputDatas[2].numElements = 1;
1321 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNonZero;
1323 inputDatas[3].format = VK_FORMAT_R32_UINT;
1324 inputDatas[3].numElements = SHADER_BUFFER_SIZE;
1325 inputDatas[3].initializeType = subgroups::SSBOData::InitializeNone;
1326 inputDatas[3].isImage = true;
1328 return subgroups::makeGeometryTest(context, VK_FORMAT_R32_UINT,
1329 inputDatas, inputDatasCount, checkVertexPipelineStagesSubgroupBarriers);
1332 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
1334 if (OPTYPE_ELECT == caseDef.opType)
1336 subgroups::SSBOData inputData;
1337 inputData.format = VK_FORMAT_R32_UINT;
1338 inputData.numElements = 1;
1339 inputData.initializeType = subgroups::SSBOData::InitializeZero;
1341 return subgroups::makeTessellationControlTest(context, VK_FORMAT_R32_UINT,
1342 &inputData, 1, checkVertexPipelineStagesSubgroupElect);
1346 const deUint32 inputDatasCount = 4;
1347 subgroups::SSBOData inputDatas[inputDatasCount];
1348 inputDatas[0].format = VK_FORMAT_R32_UINT;
1349 inputDatas[0].numElements = SHADER_BUFFER_SIZE;
1350 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1352 inputDatas[1].format = VK_FORMAT_R32_UINT;
1353 inputDatas[1].numElements = 1;
1354 inputDatas[1].initializeType = subgroups::SSBOData::InitializeZero;
1356 inputDatas[2].format = VK_FORMAT_R32_UINT;
1357 inputDatas[2].numElements = 1;
1358 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNonZero;
1360 inputDatas[3].format = VK_FORMAT_R32_UINT;
1361 inputDatas[3].numElements = SHADER_BUFFER_SIZE;
1362 inputDatas[3].initializeType = subgroups::SSBOData::InitializeNone;
1363 inputDatas[3].isImage = true;
1365 return subgroups::makeTessellationControlTest(context, VK_FORMAT_R32_UINT,
1366 inputDatas, inputDatasCount, checkVertexPipelineStagesSubgroupBarriers);
1369 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
1371 if (OPTYPE_ELECT == caseDef.opType)
1373 subgroups::SSBOData inputData;
1374 inputData.format = VK_FORMAT_R32_UINT;
1375 inputData.numElements = 1;
1376 inputData.initializeType = subgroups::SSBOData::InitializeZero;
1378 return subgroups::makeTessellationEvaluationTest(context, VK_FORMAT_R32_UINT,
1379 &inputData, 1, checkVertexPipelineStagesSubgroupElect);
1383 const deUint32 inputDatasCount = 4;
1384 subgroups::SSBOData inputDatas[inputDatasCount];
1385 inputDatas[0].format = VK_FORMAT_R32_UINT;
1386 inputDatas[0].numElements = SHADER_BUFFER_SIZE;
1387 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1389 inputDatas[1].format = VK_FORMAT_R32_UINT;
1390 inputDatas[1].numElements = 1;
1391 inputDatas[1].initializeType = subgroups::SSBOData::InitializeZero;
1393 inputDatas[2].format = VK_FORMAT_R32_UINT;
1394 inputDatas[2].numElements = 1;
1395 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNonZero;
1397 inputDatas[3].format = VK_FORMAT_R32_UINT;
1398 inputDatas[3].numElements = SHADER_BUFFER_SIZE;
1399 inputDatas[3].initializeType = subgroups::SSBOData::InitializeNone;
1400 inputDatas[3].isImage = true;
1402 return subgroups::makeTessellationEvaluationTest(context, VK_FORMAT_R32_UINT,
1403 inputDatas, inputDatasCount, checkVertexPipelineStagesSubgroupBarriers);
1408 TCU_THROW(InternalError, "Unhandled shader stage");
1417 tcu::TestCaseGroup* createSubgroupsBasicTests(tcu::TestContext& testCtx)
1419 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(
1420 testCtx, "basic", "Subgroup basic category tests"));
1422 const VkShaderStageFlags stages[] =
1424 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1425 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1426 VK_SHADER_STAGE_GEOMETRY_BIT,
1427 VK_SHADER_STAGE_VERTEX_BIT,
1428 VK_SHADER_STAGE_FRAGMENT_BIT,
1429 VK_SHADER_STAGE_COMPUTE_BIT
1432 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
1434 const VkShaderStageFlags stage = stages[stageIndex];
1436 for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
1438 if ((OPTYPE_SUBGROUP_MEMORY_BARRIER_SHARED == opTypeIndex) &&
1439 (VK_SHADER_STAGE_COMPUTE_BIT != stage))
1441 // Shared isn't available in non compute shaders.
1445 CaseDefinition caseDef = {opTypeIndex, stage, false};
1447 std::string op = getOpTypeName(opTypeIndex);
1449 addFunctionCaseWithPrograms(group.get(),
1451 "_" + getShaderStageName(stage), "",
1452 initPrograms, test, caseDef);
1454 if ((VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) & stage )
1456 if (OPTYPE_ELECT != caseDef.opType || VK_SHADER_STAGE_FRAGMENT_BIT != stage)
1458 caseDef.noSSBO = true;
1459 addFunctionCaseWithPrograms(group.get(),
1460 de::toLower(op) + "_" +
1461 getShaderStageName(stage)+"_framebuffer", "",
1462 initFrameBufferPrograms, test, caseDef);
1468 return group.release();