subgroups: Use common boilerplate for shader code
authorGraeme Leese <gleese@broadcom.com>
Mon, 30 Sep 2019 16:47:22 +0000 (17:47 +0100)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Tue, 12 Nov 2019 08:48:58 +0000 (03:48 -0500)
The code that set up the input values and wrote the output values to
appropriate locations was the same in all sets of subgroup tests and
duplicated into each of them, meaning any bugs had to be fixed multiple
times. Put all this common boilerplate into the TestUtils.

Components: Vulkan
Affects: dEQP-VK.subgroups.ballot_broadcast.*
         dEQP-VK.subgroups.arithmetic.*
         dEQP-VK.subgroups.clustered.*
         dEQP-VK.subgroups.quad.*

Change-Id: Ibde86869c33df4d057b9fd39705feeb9dff8c248

external/vulkancts/modules/vulkan/subgroups/vktSubgroupsArithmeticTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsBallotBroadcastTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsClusteredTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsQuadTests.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.cpp
external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.hpp

index dd581d0..207474d 100755 (executable)
@@ -464,17 +464,19 @@ struct CaseDefinition
        de::SharedPtr<bool>     geometryPointSizeSupported;
 };
 
-void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
+std::string getExtHeader(CaseDefinition caseDef)
+{
+       return  "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
+                       "#extension GL_KHR_shader_subgroup_ballot: enable\n" +
+                       subgroups::getAdditionalExtensionForFormat(caseDef.format);
+}
+
+void initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
        const vk::ShaderBuildOptions    buildOptions    (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
        std::string                                             indexVars;
        std::ostringstream                              bdy;
 
-       subgroups::setFragmentShaderFrameBuffer(programCollection);
-
-       if (VK_SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
-               subgroups::setVertexShaderFrameBuffer(programCollection);
-
        switch (caseDef.opType)
        {
                default:
@@ -500,10 +502,11 @@ void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefiniti
                        break;
        }
 
-       bdy << indexVars
+       bdy << "  uvec4 mask = subgroupBallot(true);\n"
+               << indexVars
                << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " ref = "
                << getIdentity(caseDef.opType, caseDef.format) << ";\n"
-               << "  uint tempResult = 0;\n"
+               << "  tempRes = 0;\n"
                << "  for (uint index = start; index < end; index++)\n"
                << "  {\n"
                << "    if (subgroupBallotBitExtract(mask, index))\n"
@@ -511,7 +514,7 @@ void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefiniti
                << "      ref = " << getOpTypeOperation(caseDef.opType, caseDef.format, "ref", "data[index]") << ";\n"
                << "    }\n"
                << "  }\n"
-               << "  tempResult = " << getCompare(caseDef.opType, caseDef.format, "ref",
+               << "  tempRes = " << getCompare(caseDef.opType, caseDef.format, "ref",
                                                                                        getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID])") << " ? 0x1 : 0;\n"
                << "  if (1 == (gl_SubgroupInvocationID % 2))\n"
                << "  {\n"
@@ -524,135 +527,21 @@ void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefiniti
                << "        ref = " << getOpTypeOperation(caseDef.opType, caseDef.format, "ref", "data[index]") << ";\n"
                << "      }\n"
                << "    }\n"
-               << "    tempResult |= " << getCompare(caseDef.opType, caseDef.format, "ref",
+               << "    tempRes |= " << getCompare(caseDef.opType, caseDef.format, "ref",
                                getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID])") << " ? 0x2 : 0;\n"
                << "  }\n"
                << "  else\n"
                << "  {\n"
-               << "    tempResult |= 0x2;\n"
+               << "    tempRes |= 0x2;\n"
                << "  }\n";
 
-       if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream vertexSrc;
-               vertexSrc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-                       << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                       << subgroups::getAdditionalExtensionForFormat(caseDef.format)
-                       << "layout(location = 0) in highp vec4 in_position;\n"
-                       << "layout(location = 0) out float out_color;\n"
-                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  uvec4 mask = subgroupBallot(true);\n"
-                       << bdy.str()
-                       << "  out_color = float(tempResult);\n"
-                       << "  gl_Position = in_position;\n"
-                       << "  gl_PointSize = 1.0f;\n"
-                       << "}\n";
-               programCollection.glslSources.add("vert")
-                       << glu::VertexSource(vertexSrc.str()) << buildOptions;
-       }
-       else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream geometry;
-
-               geometry << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-                       << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                       << subgroups::getAdditionalExtensionForFormat(caseDef.format)
-                       << "layout(points) in;\n"
-                       << "layout(points, max_vertices = 1) out;\n"
-                       << "layout(location = 0) out float out_color;\n"
-                       << "layout(set = 0, binding = 0) uniform Buffer\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  uvec4 mask = subgroupBallot(true);\n"
-                       << bdy.str()
-                       << "  out_color = float(tempResult);\n"
-                       << "  gl_Position = gl_in[0].gl_Position;\n"
-                       << (*caseDef.geometryPointSizeSupported ? "  gl_PointSize = gl_in[0].gl_PointSize;\n" : "")
-                       << "  EmitVertex();\n"
-                       << "  EndPrimitive();\n"
-                       << "}\n";
-
-               programCollection.glslSources.add("geometry")
-                               << glu::GeometrySource(geometry.str()) << buildOptions;
-       }
-       else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream controlSource;
-               controlSource  << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-                       << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                       << subgroups::getAdditionalExtensionForFormat(caseDef.format)
-                       << "layout(vertices = 2) out;\n"
-                       << "layout(location = 0) out float out_color[];\n"
-                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  if (gl_InvocationID == 0)\n"
-                       <<"  {\n"
-                       << "    gl_TessLevelOuter[0] = 1.0f;\n"
-                       << "    gl_TessLevelOuter[1] = 1.0f;\n"
-                       << "  }\n"
-                       << "  uvec4 mask = subgroupBallot(true);\n"
-                       << bdy.str()
-                       << "  out_color[gl_InvocationID] = float(tempResult);"
-                       << "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-                       << "}\n";
-
-
-               programCollection.glslSources.add("tesc")
-                       << glu::TessellationControlSource(controlSource.str()) << buildOptions;
-               subgroups::setTesEvalShaderFrameBuffer(programCollection);
-       }
-       else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-       {
-
-               std::ostringstream evaluationSource;
-               evaluationSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-                       << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                       << subgroups::getAdditionalExtensionForFormat(caseDef.format)
-                       << "layout(isolines, equal_spacing, ccw ) in;\n"
-                       << "layout(location = 0) out float out_color;\n"
-                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  uvec4 mask = subgroupBallot(true);\n"
-                       << bdy.str()
-                       << "  out_color = float(tempResult);\n"
-                       << "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
-                       << "}\n";
-
-               subgroups::setTesCtrlShaderFrameBuffer(programCollection);
-               programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(evaluationSource.str()) << buildOptions;
-       }
-       else
-       {
-               DE_FATAL("Unsupported shader stage");
-       }
+       subgroups::initStdFrameBufferPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, getExtHeader(caseDef), bdy.str(), "");
 }
 
 void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
+       const vk::ShaderBuildOptions    buildOptions    (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
+
        std::string indexVars;
        switch (caseDef.opType)
        {
@@ -679,11 +568,12 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                        break;
        }
 
-       const string bdy =
-               indexVars +
+       const string testSrc =
+               "  uvec4 mask = subgroupBallot(true);\n"
+               + indexVars +
                "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " ref = "
                + getIdentity(caseDef.opType, caseDef.format) + ";\n"
-               "  uint tempResult = 0;\n"
+               "  tempRes = 0;\n"
                "  for (uint index = start; index < end; index++)\n"
                "  {\n"
                "    if (subgroupBallotBitExtract(mask, index))\n"
@@ -691,7 +581,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                "      ref = " + getOpTypeOperation(caseDef.opType, caseDef.format, "ref", "data[index]") + ";\n"
                "    }\n"
                "  }\n"
-               "  tempResult = " + getCompare(caseDef.opType, caseDef.format, "ref", getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID])") + " ? 0x1 : 0;\n"
+               "  tempRes = " + getCompare(caseDef.opType, caseDef.format, "ref", getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID])") + " ? 0x1 : 0;\n"
                "  if (1 == (gl_SubgroupInvocationID % 2))\n"
                "  {\n"
                "    mask = subgroupBallot(true);\n"
@@ -703,189 +593,16 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
                "        ref = " + getOpTypeOperation(caseDef.opType, caseDef.format, "ref", "data[index]") + ";\n"
                "      }\n"
                "    }\n"
-               "    tempResult |= " + getCompare(caseDef.opType, caseDef.format, "ref", getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID])") + " ? 0x2 : 0;\n"
+               "    tempRes |= " + getCompare(caseDef.opType, caseDef.format, "ref", getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID])") + " ? 0x2 : 0;\n"
                "  }\n"
                "  else\n"
                "  {\n"
-               "    tempResult |= 0x2;\n"
+               "    tempRes |= 0x2;\n"
                "  }\n";
 
-       if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream src;
+       std::string extHeader = getExtHeader(caseDef);
 
-               src << "#version 450\n"
-                       << "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-                       << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                       << subgroups::getAdditionalExtensionForFormat(caseDef.format)
-                       << "layout (local_size_x_id = 0, local_size_y_id = 1, "
-                       "local_size_z_id = 2) in;\n"
-                       << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-                       << "{\n"
-                       << "  uint result[];\n"
-                       << "};\n"
-                       << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
-                       << "  highp uint offset = globalSize.x * ((globalSize.y * "
-                       "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
-                       "gl_GlobalInvocationID.x;\n"
-                       << "  uvec4 mask = subgroupBallot(true);\n"
-                       << bdy
-                       << "  result[offset] = tempResult;\n"
-                       << "}\n";
-
-               programCollection.glslSources.add("comp")
-                               << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-       }
-       else
-       {
-               {
-                       const std::string vertex =
-                               "#version 450\n"
-                               "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-                               "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                               + subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-                               "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-                               "{\n"
-                               "  uint result[];\n"
-                               "};\n"
-                               "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                               "{\n"
-                               "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                               "};\n"
-                               "\n"
-                               "void main (void)\n"
-                               "{\n"
-                               "  uvec4 mask = subgroupBallot(true);\n"
-                               + bdy+
-                               "  result[gl_VertexIndex] = tempResult;\n"
-                               "  float pixelSize = 2.0f/1024.0f;\n"
-                               "  float pixelPosition = pixelSize/2.0f - 1.0f;\n"
-                               "  gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
-                               "  gl_PointSize = 1.0f;\n"
-                               "}\n";
-                       programCollection.glslSources.add("vert")
-                                       << glu::VertexSource(vertex) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-               }
-
-               {
-                       const std::string tesc =
-                               "#version 450\n"
-                               "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-                               "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                               + subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-                               "layout(vertices=1) out;\n"
-                               "layout(set = 0, binding = 1, std430) buffer Buffer1\n"
-                               "{\n"
-                               "  uint result[];\n"
-                               "};\n"
-                               "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                               "{\n"
-                               "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                               "};\n"
-                               "\n"
-                               "void main (void)\n"
-                               "{\n"
-                               "  uvec4 mask = subgroupBallot(true);\n"
-                               + bdy +
-                               "  result[gl_PrimitiveID] = tempResult;\n"
-                               "  if (gl_InvocationID == 0)\n"
-                               "  {\n"
-                               "    gl_TessLevelOuter[0] = 1.0f;\n"
-                               "    gl_TessLevelOuter[1] = 1.0f;\n"
-                               "  }\n"
-                               "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-                               "}\n";
-                       programCollection.glslSources.add("tesc")
-                               << glu::TessellationControlSource(tesc) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-               }
-
-               {
-                       const std::string tese =
-                               "#version 450\n"
-                               "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-                               "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                               + subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-                               "layout(isolines) in;\n"
-                               "layout(set = 0, binding = 2, std430) buffer Buffer1\n"
-                               "{\n"
-                               "  uint result[];\n"
-                               "};\n"
-                               "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                               "{\n"
-                               "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                               "};\n"
-                               "\n"
-                               "void main (void)\n"
-                               "{\n"
-                               "  uvec4 mask = subgroupBallot(true);\n"
-                               + bdy +
-                               "  result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempResult;\n"
-                               "  float pixelSize = 2.0f/1024.0f;\n"
-                               "  gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
-                               "}\n";
-                       programCollection.glslSources.add("tese")
-                               << glu::TessellationEvaluationSource(tese) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-               }
-
-               {
-                       const std::string geometry =
-                               "#version 450\n"
-                               "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-                               "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                               + subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-                               "layout(${TOPOLOGY}) in;\n"
-                               "layout(points, max_vertices = 1) out;\n"
-                               "layout(set = 0, binding = 3, std430) buffer Buffer1\n"
-                               "{\n"
-                               "  uint result[];\n"
-                               "};\n"
-                               "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                               "{\n"
-                               "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                               "};\n"
-                               "\n"
-                               "void main (void)\n"
-                               "{\n"
-                               "  uvec4 mask = subgroupBallot(true);\n"
-                                + bdy +
-                               "  result[gl_PrimitiveIDIn] = tempResult;\n"
-                               "  gl_Position = gl_in[0].gl_Position;\n"
-                               "  EmitVertex();\n"
-                               "  EndPrimitive();\n"
-                               "}\n";
-                       subgroups::addGeometryShadersFromTemplate(geometry, vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u),
-                                                                                                         programCollection.glslSources);
-               }
-
-               {
-                       const std::string fragment =
-                               "#version 450\n"
-                               "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
-                               "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                               + subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-                               "layout(location = 0) out uint result;\n"
-                               "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                               "{\n"
-                               "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                               "};\n"
-                               "void main (void)\n"
-                               "{\n"
-                               "  uvec4 mask = subgroupBallot(true);\n"
-                               + bdy +
-                               "  result = tempResult;\n"
-                               "}\n";
-                       programCollection.glslSources.add("fragment")
-                               << glu::FragmentSource(fragment)<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-               }
-               subgroups::addNoSubgroupShader(programCollection);
-       }
+   subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, extHeader, testSrc, "");
 }
 
 void supportedCheck (Context& context, CaseDefinition caseDef)
@@ -894,9 +611,7 @@ void supportedCheck (Context& context, CaseDefinition caseDef)
                TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
 
        if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_ARITHMETIC_BIT))
-       {
                TCU_THROW(NotSupportedError, "Device does not support subgroup arithmetic operations");
-       }
 
        if (!subgroups::isFormatSupportedForDevice(context, caseDef.format))
                TCU_THROW(NotSupportedError, "Device does not support the specified format in subgroup operations");
@@ -936,7 +651,7 @@ tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
                return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-               return subgroups::makeTessellationEvaluationFrameBufferTest(context,  VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
+               return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
        else
                TCU_THROW(InternalError, "Unhandled shader stage");
 }
@@ -963,12 +678,12 @@ tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
 {
        if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
        {
-               if(!checkShaderStages(context,caseDef))
+               if (!checkShaderStages(context,caseDef))
                {
                        return tcu::TestStatus::fail(
-                                                       "Shader stage " +
-                                                       subgroups::getShaderStageName(caseDef.shaderStage) +
-                                                       " is required to support subgroup operations!");
+                                       "Shader stage " +
+                                       subgroups::getShaderStageName(caseDef.shaderStage) +
+                                       " is required to support subgroup operations!");
                }
                subgroups::SSBOData inputData;
                inputData.format = caseDef.format;
@@ -992,7 +707,7 @@ tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
 
                VkShaderStageFlagBits stages = (VkShaderStageFlagBits)(caseDef.shaderStage  & subgroupProperties.supportedStages);
 
-               if ( VK_SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context))
+               if (VK_SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context))
                {
                        if ( (stages & VK_SHADER_STAGE_FRAGMENT_BIT) == 0)
                                TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
@@ -1011,8 +726,7 @@ tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
                inputData.binding                       = 4u;
                inputData.stages                        = stages;
 
-               return subgroups::allStages(context, VK_FORMAT_R32_UINT, &inputData,
-                                                                                1, checkVertexPipelineStages, stages);
+               return subgroups::allStages(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, stages);
        }
 }
 }
index 9636ef2..0b1b4e3 100755 (executable)
@@ -79,7 +79,16 @@ struct CaseDefinition
        deBool                          extShaderSubGroupBallotTests;
 };
 
-std::string getBodySource(CaseDefinition caseDef)
+std::string getExtHeader(CaseDefinition caseDef)
+{
+       return (caseDef.extShaderSubGroupBallotTests ?  "#extension GL_ARB_shader_ballot: enable\n"
+                                                                                                       "#extension GL_KHR_shader_subgroup_basic: enable\n"
+                                                                                                       "#extension GL_ARB_gpu_shader_int64: enable\n"
+                                                                                               :       "#extension GL_KHR_shader_subgroup_ballot: enable\n")
+                               + subgroups::getAdditionalExtensionForFormat(caseDef.format);
+}
+
+std::string getTestSrc(const CaseDefinition &caseDef)
 {
        std::ostringstream bdy;
 
@@ -113,18 +122,18 @@ std::string getBodySource(CaseDefinition caseDef)
 
        if (OPTYPE_BROADCAST == caseDef.opType)
        {
-               bdy     << "  uint tempResult = 0x3;\n";
+               bdy     << "  tempRes = 0x3;\n";
                for (int i = 0; i < max; i++)
                {
                        bdy << "  {\n"
                        << "    const uint id = "<< i << ";\n"
                        << "    " << subgroups::getFormatNameForGLSL(caseDef.format) << " op = "
-                               << broadcast << "(data1[sgInvocation], id);\n"
+                               << broadcast << "(data[sgInvocation], id);\n"
                        << "    if ((id < sgSize) && subgroupBallotBitExtract(mask, id))\n"
                        << "    {\n"
-                       << "      if (op != data1[id])\n"
+                       << "      if (op != data[id])\n"
                        << "      {\n"
-                       << "        tempResult = 0;\n"
+                       << "        tempRes = 0;\n"
                        << "      }\n"
                        << "    }\n"
                        << "  }\n";
@@ -132,7 +141,7 @@ std::string getBodySource(CaseDefinition caseDef)
        }
        else
        {
-               bdy << "  uint tempResult = 0;\n"
+               bdy << "  tempRes = 0;\n"
                        << "  uint firstActive = 0;\n"
                        << "  for (uint i = 0; i < sgSize; i++)\n"
                        << "  {\n"
@@ -142,7 +151,7 @@ std::string getBodySource(CaseDefinition caseDef)
                        << "      break;\n"
                        << "    }\n"
                        << "  }\n"
-                       << "  tempResult |= (" << broadcastFirst << "(data1[sgInvocation]) == data1[firstActive]) ? 0x1 : 0;\n"
+                       << "  tempRes |= (" << broadcastFirst << "(data[sgInvocation]) == data[firstActive]) ? 0x1 : 0;\n"
                        << "  // make the firstActive invocation inactive now\n"
                        << "  if (firstActive != sgInvocation)\n"
                        << "  {\n"
@@ -155,18 +164,18 @@ std::string getBodySource(CaseDefinition caseDef)
                        << "        break;\n"
                        << "      }\n"
                        << "    }\n"
-                       << "    tempResult |= (" << broadcastFirst << "(data1[sgInvocation]) == data1[firstActive]) ? 0x2 : 0;\n"
+                       << "    tempRes |= (" << broadcastFirst << "(data[sgInvocation]) == data[firstActive]) ? 0x2 : 0;\n"
                        << "  }\n"
                        << "  else\n"
                        << "  {\n"
                        << "    // the firstActive invocation didn't partake in the second result so set it to true\n"
-                       << "    tempResult |= 0x2;\n"
+                       << "    tempRes |= 0x2;\n"
                        << "  }\n";
        }
-   return bdy.str();
+       return bdy.str();
 }
 
-std::string getHelperFunctionARB(CaseDefinition caseDef)
+std::string getHelperFunctionARB(const CaseDefinition &caseDef)
 {
        std::ostringstream bdy;
 
@@ -188,294 +197,23 @@ std::string getHelperFunctionARB(CaseDefinition caseDef)
 void initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
        const vk::ShaderBuildOptions    buildOptions    (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-       const string extensionHeader =  (caseDef.extShaderSubGroupBallotTests ? "#extension GL_ARB_shader_ballot: enable\n"
-                                                                                                                                                       "#extension GL_KHR_shader_subgroup_basic: enable\n"
-                                                                                                                                                       "#extension GL_ARB_gpu_shader_int64: enable\n"
-                                                                                                                                               :       "#extension GL_KHR_shader_subgroup_ballot: enable\n")
-                                                                       + subgroups::getAdditionalExtensionForFormat(caseDef.format);
-
-       subgroups::setFragmentShaderFrameBuffer(programCollection);
-
-       if (VK_SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
-               subgroups::setVertexShaderFrameBuffer(programCollection);
 
-       std::string bdyStr = getBodySource(caseDef);
-       std::string helperStrARB = getHelperFunctionARB(caseDef);
+       std::string extHeader = getExtHeader(caseDef);
+       std::string testSrc = getTestSrc(caseDef);
+       std::string helperStr = getHelperFunctionARB(caseDef);
 
-       if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream                              vertex;
-               vertex << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << extensionHeader.c_str()
-                       << "layout(location = 0) in highp vec4 in_position;\n"
-                       << "layout(location = 0) out float out_color;\n"
-                       << "layout(set = 0, binding = 0) uniform  Buffer1\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data1[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << helperStrARB.c_str()
-                       << "void main (void)\n"
-                       << "{\n"
-                       << bdyStr
-                       << "  out_color = float(tempResult);\n"
-                       << "  gl_Position = in_position;\n"
-                       << "  gl_PointSize = 1.0f;\n"
-                       << "}\n";
-               programCollection.glslSources.add("vert")
-                       << glu::VertexSource(vertex.str()) << buildOptions;
-       }
-       else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream geometry;
-
-               geometry << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << extensionHeader.c_str()
-                       << "layout(points) in;\n"
-                       << "layout(points, max_vertices = 1) out;\n"
-                       << "layout(location = 0) out float out_color;\n"
-                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data1[" <<subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << helperStrARB.c_str()
-                       << "void main (void)\n"
-                       << "{\n"
-                       << bdyStr
-                       << "  out_color = float(tempResult);\n"
-                       << "  gl_Position = gl_in[0].gl_Position;\n"
-                       << (*caseDef.geometryPointSizeSupported ? "  gl_PointSize = gl_in[0].gl_PointSize;\n" : "")
-                       << "  EmitVertex();\n"
-                       << "  EndPrimitive();\n"
-                       << "}\n";
-
-               programCollection.glslSources.add("geometry")
-                       << glu::GeometrySource(geometry.str()) << buildOptions;
-       }
-       else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream controlSource;
-
-               controlSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << extensionHeader.c_str()
-                       << "layout(vertices = 2) out;\n"
-                       << "layout(location = 0) out float out_color[];\n"
-                       << "layout(set = 0, binding = 0) uniform Buffer2\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data1[" <<subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << helperStrARB.c_str()
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  if (gl_InvocationID == 0)\n"
-                       << "  {\n"
-                       << "    gl_TessLevelOuter[0] = 1.0f;\n"
-                       << "    gl_TessLevelOuter[1] = 1.0f;\n"
-                       << "  }\n"
-                       << bdyStr
-                       << "  out_color[gl_InvocationID ] = float(tempResult);\n"
-                       << "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-                       << "}\n";
-
-               programCollection.glslSources.add("tesc")
-                       << glu::TessellationControlSource(controlSource.str()) << buildOptions;
-               subgroups::setTesEvalShaderFrameBuffer(programCollection);
-       }
-       else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream evaluationSource;
-               evaluationSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << extensionHeader.c_str()
-                       << "layout(isolines, equal_spacing, ccw ) in;\n"
-                       << "layout(location = 0) out float out_color;\n"
-                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data1[" <<subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << helperStrARB.c_str()
-                       << "void main (void)\n"
-                       << "{\n"
-                       << bdyStr
-                       << "  out_color  = float(tempResult);\n"
-                       << "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
-                       << "}\n";
-
-               subgroups::setTesCtrlShaderFrameBuffer(programCollection);
-               programCollection.glslSources.add("tese")
-                       << glu::TessellationEvaluationSource(evaluationSource.str()) << buildOptions;
-       }
-       else
-       {
-               DE_FATAL("Unsupported shader stage");
-       }
+   subgroups::initStdFrameBufferPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, extHeader, testSrc, helperStr);
 }
 
 void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
        const vk::ShaderBuildOptions    buildOptions    (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
 
-       std::string bdyStr = getBodySource(caseDef);
-       std::string helperStrARB = getHelperFunctionARB(caseDef);
-
-       const string extensionHeader =  (caseDef.extShaderSubGroupBallotTests ? "#extension GL_ARB_shader_ballot: enable\n"
-                                                                                                                                                       "#extension GL_KHR_shader_subgroup_basic: enable\n"
-                                                                                                                                                       "#extension GL_ARB_gpu_shader_int64: enable\n"
-                                                                                                                                               :       "#extension GL_KHR_shader_subgroup_ballot: enable\n")
-                                                                       + subgroups::getAdditionalExtensionForFormat(caseDef.format);
+       std::string extHeader = getExtHeader(caseDef);
+       std::string testSrc = getTestSrc(caseDef);
+       std::string helperStr = getHelperFunctionARB(caseDef);
 
-       if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream src;
-
-               src << "#version 450\n"
-                       << extensionHeader.c_str()
-                       << "layout (local_size_x_id = 0, local_size_y_id = 1, "
-                       "local_size_z_id = 2) in;\n"
-                       << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-                       << "{\n"
-                       << "  uint result[];\n"
-                       << "};\n"
-                       << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data1[];\n"
-                       << "};\n"
-                       << "\n"
-                       << helperStrARB.c_str()
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
-                       << "  highp uint offset = globalSize.x * ((globalSize.y * "
-                       "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
-                       "gl_GlobalInvocationID.x;\n"
-                       << bdyStr
-                       << "  result[offset] = tempResult;\n"
-                       << "}\n";
-
-               programCollection.glslSources.add("comp") << glu::ComputeSource(src.str()) << buildOptions;
-       }
-       else
-       {
-               const string vertex =
-                       "#version 450\n"
-                       + extensionHeader +
-                       "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-                       "{\n"
-                       "  uint result[];\n"
-                       "};\n"
-                       "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                       "{\n"
-                       "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data1[];\n"
-                       "};\n"
-                       "\n"
-                       + helperStrARB +
-                       "void main (void)\n"
-                       "{\n"
-                       + bdyStr +
-                       "  result[gl_VertexIndex] = tempResult;\n"
-                       "  float pixelSize = 2.0f/1024.0f;\n"
-                       "  float pixelPosition = pixelSize/2.0f - 1.0f;\n"
-                       "  gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
-                       "  gl_PointSize = 1.0f;\n"
-                       "}\n";
-
-               const string tesc =
-                       "#version 450\n"
-                       + extensionHeader +
-                       "layout(vertices=1) out;\n"
-                       "layout(set = 0, binding = 1, std430) buffer Buffer1\n"
-                       "{\n"
-                       "  uint result[];\n"
-                       "};\n"
-                       "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                       "{\n"
-                       "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data1[];\n"
-                       "};\n"
-                       "\n"
-                       + helperStrARB +
-                       "void main (void)\n"
-                       "{\n"
-                       + bdyStr +
-                       "  result[gl_PrimitiveID] = tempResult;\n"
-                       "  if (gl_InvocationID == 0)\n"
-                       "  {\n"
-                       "    gl_TessLevelOuter[0] = 1.0f;\n"
-                       "    gl_TessLevelOuter[1] = 1.0f;\n"
-                       "  }\n"
-                       "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-                       "}\n";
-
-               const string tese =
-                       "#version 450\n"
-                       + extensionHeader +
-                       "layout(isolines) in;\n"
-                       "layout(set = 0, binding = 2, std430) buffer Buffer1\n"
-                       "{\n"
-                       "  uint result[];\n"
-                       "};\n"
-                       "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                       "{\n"
-                       "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data1[];\n"
-                       "};\n"
-                       "\n"
-                       + helperStrARB +
-                       "void main (void)\n"
-                       "{\n"
-                       + bdyStr +
-                       "  result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempResult;\n"
-                       "  float pixelSize = 2.0f/1024.0f;\n"
-                       "  gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
-                       "}\n";
-
-               const string geometry =
-                       "#version 450\n"
-                       + extensionHeader +
-                       "layout(${TOPOLOGY}) in;\n"
-                       "layout(points, max_vertices = 1) out;\n"
-                       "layout(set = 0, binding = 3, std430) buffer Buffer1\n"
-                       "{\n"
-                       "  uint result[];\n"
-                       "};\n"
-                       "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                       "{\n"
-                       "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data1[];\n"
-                       "};\n"
-                       "\n"
-                       + helperStrARB +
-                       "void main (void)\n"
-                       "{\n"
-                       + bdyStr +
-                       "  result[gl_PrimitiveIDIn] = tempResult;\n"
-                       "  gl_Position = gl_in[0].gl_Position;\n"
-                       "  EmitVertex();\n"
-                       "  EndPrimitive();\n"
-                       "}\n";
-
-               const string fragment =
-                       "#version 450\n"
-                       + extensionHeader +
-                       "layout(location = 0) out uint result;\n"
-                       "layout(set = 0, binding = 4, std430) readonly buffer Buffer1\n"
-                       "{\n"
-                       "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data1[];\n"
-                       "};\n"
-                       + helperStrARB +
-                       "void main (void)\n"
-                       "{\n"
-                       + bdyStr +
-                       "  result = tempResult;\n"
-                       "}\n";
-
-               subgroups::addNoSubgroupShader(programCollection);
-
-               programCollection.glslSources.add("vert") << glu::VertexSource(vertex) << buildOptions;
-               programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc) << buildOptions;
-               programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese) << buildOptions;
-               subgroups::addGeometryShadersFromTemplate(geometry, buildOptions, programCollection.glslSources);
-               programCollection.glslSources.add("fragment") << glu::FragmentSource(fragment)<< buildOptions;
-       }
+       subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, extHeader, testSrc, helperStr);
 }
 
 void supportedCheck (Context& context, CaseDefinition caseDef)
@@ -484,30 +222,23 @@ void supportedCheck (Context& context, CaseDefinition caseDef)
                TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
 
        if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BALLOT_BIT))
-       {
                TCU_THROW(NotSupportedError, "Device does not support subgroup ballot operations");
-       }
 
        if (!subgroups::isFormatSupportedForDevice(context, caseDef.format))
                TCU_THROW(NotSupportedError, "Device does not support the specified format in subgroup operations");
 
        if (caseDef.extShaderSubGroupBallotTests && !context.requireDeviceFunctionality("VK_EXT_shader_subgroup_ballot"))
-       {
                TCU_THROW(NotSupportedError, "Device does not support VK_EXT_shader_subgroup_ballot extension");
-       }
 
        if (caseDef.extShaderSubGroupBallotTests && !subgroups::isInt64SupportedForDevice(context))
-       {
                TCU_THROW(NotSupportedError, "Device does not support int64 data types");
-       }
 
        *caseDef.geometryPointSizeSupported = subgroups::isTessellationAndGeometryPointSizeSupported(context);
 }
 
 tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
 {
-       if (!subgroups::areSubgroupOperationsSupportedForStage(
-                       context, caseDef.shaderStage))
+       if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
        {
                if (subgroups::areSubgroupOperationsRequiredForStage(caseDef.shaderStage))
                {
@@ -522,20 +253,20 @@ tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
                }
        }
 
-       subgroups::SSBOData inputData[1];
-       inputData[0].format = caseDef.format;
-       inputData[0].layout = subgroups::SSBOData::LayoutStd140;
-       inputData[0].numElements = caseDef.extShaderSubGroupBallotTests ? 64u : subgroups::maxSupportedSubgroupSize();
-       inputData[0].initializeType = subgroups::SSBOData::InitializeNonZero;
+       subgroups::SSBOData inputData;
+       inputData.format = caseDef.format;
+       inputData.layout = subgroups::SSBOData::LayoutStd140;
+       inputData.numElements = caseDef.extShaderSubGroupBallotTests ? 64u : subgroups::maxSupportedSubgroupSize();
+       inputData.initializeType = subgroups::SSBOData::InitializeNonZero;
 
        if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
-               return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT, inputData, 1, checkVertexPipelineStages);
+               return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages);
        else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
-               return subgroups::makeGeometryFrameBufferTest(context, VK_FORMAT_R32_UINT, inputData, 1, checkVertexPipelineStages);
+               return subgroups::makeGeometryFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages);
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
-               return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
+               return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-               return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
+               return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
        else
                TCU_THROW(InternalError, "Unhandled shader stage");
 }
@@ -547,25 +278,18 @@ tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
        {
                if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
                {
-                       if (subgroups::areSubgroupOperationsRequiredForStage(caseDef.shaderStage))
-                       {
-                               return tcu::TestStatus::fail(
-                                                  "Shader stage " +
-                                                  subgroups::getShaderStageName(caseDef.shaderStage) +
-                                                  " is required to support subgroup operations!");
-                       }
-                       else
-                       {
-                               TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
-                       }
+                       return tcu::TestStatus::fail(
+                                       "Shader stage " +
+                                       subgroups::getShaderStageName(caseDef.shaderStage) +
+                                       " is required to support subgroup operations!");
                }
-               subgroups::SSBOData inputData[1];
-               inputData[0].format = caseDef.format;
-               inputData[0].layout = subgroups::SSBOData::LayoutStd430;
-               inputData[0].numElements = caseDef.extShaderSubGroupBallotTests ? 64u : subgroups::maxSupportedSubgroupSize();
-               inputData[0].initializeType = subgroups::SSBOData::InitializeNonZero;
+               subgroups::SSBOData inputData;
+               inputData.format = caseDef.format;
+               inputData.layout = subgroups::SSBOData::LayoutStd430;
+               inputData.numElements = caseDef.extShaderSubGroupBallotTests ? 64u : subgroups::maxSupportedSubgroupSize();
+               inputData.initializeType = subgroups::SSBOData::InitializeNonZero;
 
-               return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, inputData, 1, checkCompute);
+               return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkCompute);
        }
        else
        {
@@ -581,7 +305,7 @@ tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
 
                VkShaderStageFlagBits stages = (VkShaderStageFlagBits)(caseDef.shaderStage  & subgroupProperties.supportedStages);
 
-               if ( VK_SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context))
+               if (VK_SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context))
                {
                        if ( (stages & VK_SHADER_STAGE_FRAGMENT_BIT) == 0)
                                TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
@@ -695,6 +419,5 @@ tcu::TestCaseGroup* createSubgroupsBallotBroadcastTests(tcu::TestContext& testCt
 
        return group.release();
 }
-
 } // subgroups
 } // vkt
index 1acbd85..efd30d1 100755 (executable)
@@ -375,10 +375,18 @@ struct CaseDefinition
        de::SharedPtr<bool>     geometryPointSizeSupported;
 };
 
+std::string getExtHeader(CaseDefinition caseDef)
+{
+       return  "#extension GL_KHR_shader_subgroup_clustered: enable\n"
+                       "#extension GL_KHR_shader_subgroup_ballot: enable\n"
+                       + subgroups::getAdditionalExtensionForFormat(caseDef.format);
+}
+
 std::string getBodySource(CaseDefinition caseDef)
 {
        std::ostringstream bdy;
-       bdy << "  bool tempResult = true;\n";
+       bdy << "  bool tempResult = true;\n"
+               << "  uvec4 mask = subgroupBallot(true);\n";
 
        for (deUint32 i = 1; i <= subgroups::maxSupportedSubgroupSize(); i *= 2)
        {
@@ -408,324 +416,27 @@ std::string getBodySource(CaseDefinition caseDef)
                        << "        }\n"
                        << "      }\n"
                        << "    }\n"
-                       << "  }\n";
+                       << "  }\n"
+                       << "  tempRes = tempResult ? 1 : 0;\n";
        }
        return bdy.str();
 }
 
-void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
+void initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
        const vk::ShaderBuildOptions    buildOptions    (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
 
-       subgroups::setFragmentShaderFrameBuffer(programCollection);
-
-       if (VK_SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
-               subgroups::setVertexShaderFrameBuffer(programCollection);
-
-       std::string bdy = getBodySource(caseDef);
-
-       if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream                              vertexSrc;
-               vertexSrc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450 )<< "\n"
-                       << "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-                       << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                       << subgroups::getAdditionalExtensionForFormat(caseDef.format)
-                       << "layout(location = 0) in highp vec4 in_position;\n"
-                       << "layout(location = 0) out float out_color;\n"
-                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  uvec4 mask = subgroupBallot(true);\n"
-                       << bdy
-                       << "  out_color = float(tempResult ? 1 : 0);\n"
-                       << "  gl_Position = in_position;\n"
-                       << "  gl_PointSize = 1.0f;\n"
-                       << "}\n";
-               programCollection.glslSources.add("vert")
-                       << glu::VertexSource(vertexSrc.str()) <<buildOptions;
-       }
-       else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream geometry;
-
-               geometry  << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-                       << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                       << subgroups::getAdditionalExtensionForFormat(caseDef.format)
-                       << "layout(points) in;\n"
-                       << "layout(points, max_vertices = 1) out;\n"
-                       << "layout(location = 0) out float out_color;\n"
-                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  uvec4 mask = subgroupBallot(true);\n"
-                       << bdy
-                       << "  out_color = tempResult ? 1.0 : 0.0;\n"
-                       << "  gl_Position = gl_in[0].gl_Position;\n"
-                       << (*caseDef.geometryPointSizeSupported ? "  gl_PointSize = gl_in[0].gl_PointSize;\n" : "")
-                       << "  EmitVertex();\n"
-                       << "  EndPrimitive();\n"
-                       << "}\n";
-
-               programCollection.glslSources.add("geometry")
-                       << glu::GeometrySource(geometry.str()) << buildOptions;
-       }
-       else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream controlSource;
-
-               controlSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-                       << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                       << subgroups::getAdditionalExtensionForFormat(caseDef.format)
-                       << "layout(vertices = 2) out;\n"
-                       << "layout(location = 0) out float out_color[];\n"
-                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  if (gl_InvocationID == 0)\n"
-                       <<"  {\n"
-                       << "    gl_TessLevelOuter[0] = 1.0f;\n"
-                       << "    gl_TessLevelOuter[1] = 1.0f;\n"
-                       << "  }\n"
-                       << "  uvec4 mask = subgroupBallot(true);\n"
-                       << bdy
-                       << "  out_color[gl_InvocationID] = tempResult ? 1.0 : 0.0;\n"
-                       << "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-                       << "}\n";
-
-               programCollection.glslSources.add("tesc")
-                       << glu::TessellationControlSource(controlSource.str()) << buildOptions;
-               subgroups::setTesEvalShaderFrameBuffer(programCollection);
-       }
-       else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream evaluationSource;
-
-               evaluationSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-                       << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                       << subgroups::getAdditionalExtensionForFormat(caseDef.format)
-                       << "layout(isolines, equal_spacing, ccw ) in;\n"
-                       << "layout(location = 0) out float out_color;\n"
-                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  uvec4 mask = subgroupBallot(true);\n"
-                       << bdy
-                       << "  out_color = tempResult ? 1.0 : 0.0;\n"
-                       << "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
-                       << "}\n";
-
-               subgroups::setTesCtrlShaderFrameBuffer(programCollection);
-               programCollection.glslSources.add("tese")
-                       << glu::TessellationEvaluationSource(evaluationSource.str()) << buildOptions;
-       }
-       else
-       {
-               DE_FATAL("Unsupported shader stage");
-       }
+       subgroups::initStdFrameBufferPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, getExtHeader(caseDef), getBodySource(caseDef), "");
 }
 
 void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
-       std::string bdy = getBodySource(caseDef);
-
-       if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream src;
-
-               src << "#version 450\n"
-                       << "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-                       << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                       << subgroups::getAdditionalExtensionForFormat(caseDef.format)
-                       << "layout (local_size_x_id = 0, local_size_y_id = 1, "
-                       "local_size_z_id = 2) in;\n"
-                       << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-                       << "{\n"
-                       << "  uint result[];\n"
-                       << "};\n"
-                       << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
-                       << "  highp uint offset = globalSize.x * ((globalSize.y * "
-                       "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
-                       "gl_GlobalInvocationID.x;\n"
-                       << "  uvec4 mask = subgroupBallot(true);\n"
-                       << bdy
-                       << "  result[offset] = tempResult ? 1 : 0;\n"
-                       << "}\n";
-
-               programCollection.glslSources.add("comp")
-                               << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-       }
-       else
-       {
-               {
-                       const string vertex =
-                               "#version 450\n"
-                               "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-                               "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                               + subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-                               "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-                               "{\n"
-                               "  uint result[];\n"
-                               "};\n"
-                               "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                               "{\n"
-                               "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                               "};\n"
-                               "\n"
-                               "void main (void)\n"
-                               "{\n"
-                               "  uvec4 mask = subgroupBallot(true);\n"
-                               + bdy +
-                               "  result[gl_VertexIndex] = tempResult ? 1 : 0;\n"
-                               "  float pixelSize = 2.0f/1024.0f;\n"
-                               "  float pixelPosition = pixelSize/2.0f - 1.0f;\n"
-                               "  gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
-                               "  gl_PointSize = 1.0f;\n"
-                               "}\n";
-
-                       programCollection.glslSources.add("vert")
-                               << glu::VertexSource(vertex) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-               }
-
-               {
-                       const string tesc =
-                       "#version 450\n"
-                       "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-                       "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                       + subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-                       "layout(vertices=1) out;\n"
-                       "layout(set = 0, binding = 1, std430) buffer Buffer1\n"
-                       "{\n"
-                       "  uint result[];\n"
-                       "};\n"
-                       "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                       "{\n"
-                       "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                       "};\n"
-                       "\n"
-                       "void main (void)\n"
-                       "{\n"
-                       "  uvec4 mask = subgroupBallot(true);\n"
-                       + bdy +
-                       "  result[gl_PrimitiveID] = tempResult ? 1 : 0;\n"
-                       "  if (gl_InvocationID == 0)\n"
-                       "  {\n"
-                       "    gl_TessLevelOuter[0] = 1.0f;\n"
-                       "    gl_TessLevelOuter[1] = 1.0f;\n"
-                       "  }\n"
-                       "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-                       "}\n";
-
-                       programCollection.glslSources.add("tesc")
-                                       << glu::TessellationControlSource(tesc) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-               }
-
-               {
-                       const string tese =
-                               "#version 450\n"
-                               "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-                               "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                               + subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-                               "layout(isolines) in;\n"
-                               "layout(set = 0, binding = 2, std430) buffer Buffer1\n"
-                               "{\n"
-                               "  uint result[];\n"
-                               "};\n"
-                               "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                               "{\n"
-                               "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                               "};\n"
-                               "\n"
-                               "void main (void)\n"
-                               "{\n"
-                               "  uvec4 mask = subgroupBallot(true);\n"
-                               + bdy +
-                               "  result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempResult ? 1 : 0;\n"
-                               "  float pixelSize = 2.0f/1024.0f;\n"
-                               "  gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
-                               "}\n";
-                       programCollection.glslSources.add("tese")
-                                       << glu::TessellationEvaluationSource(tese) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-               }
-
-               {
-                       const string geometry =
-                               "#version 450\n"
-                               "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-                               "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                               + subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-                               "layout(${TOPOLOGY}) in;\n"
-                               "layout(points, max_vertices = 1) out;\n"
-                               "layout(set = 0, binding = 3, std430) buffer Buffer1\n"
-                               "{\n"
-                               "  uint result[];\n"
-                               "};\n"
-                               "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                               "{\n"
-                               "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                               "};\n"
-                               "\n"
-                               "void main (void)\n"
-                               "{\n"
-                               "  uvec4 mask = subgroupBallot(true);\n"
-                               + bdy +
-                               "  result[gl_PrimitiveIDIn] = tempResult ? 1 : 0;\n"
-                               "  gl_Position = gl_in[0].gl_Position;\n"
-                               "  EmitVertex();\n"
-                               "  EndPrimitive();\n"
-                               "}\n";
-                       subgroups::addGeometryShadersFromTemplate(geometry, vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u), programCollection.glslSources);
-               }
+       const vk::ShaderBuildOptions    buildOptions    (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
 
-               {
-                       const string fragment =
-                               "#version 450\n"
-                               "#extension GL_KHR_shader_subgroup_clustered: enable\n"
-                               "#extension GL_KHR_shader_subgroup_ballot: enable\n"
-                               + subgroups::getAdditionalExtensionForFormat(caseDef.format) +
-                               "layout(location = 0) out uint result;\n"
-                               "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                               "{\n"
-                               "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                               "};\n"
-                               "void main (void)\n"
-                               "{\n"
-                               "  uvec4 mask = subgroupBallot(true);\n"
-                               + bdy +
-                               "  result = tempResult ? 1 : 0;\n"
-                               "}\n";
-                       programCollection.glslSources.add("fragment")
-                               << glu::FragmentSource(fragment)<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
-               }
+       std::string extHeader = getExtHeader(caseDef);
+       std::string testSrc = getBodySource(caseDef);
 
-               subgroups::addNoSubgroupShader(programCollection);
-       }
+   subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, extHeader, testSrc, "");
 }
 
 void supportedCheck (Context& context, CaseDefinition caseDef)
@@ -744,11 +455,9 @@ void supportedCheck (Context& context, CaseDefinition caseDef)
 
 tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
 {
-       if (!subgroups::areSubgroupOperationsSupportedForStage(
-                               context, caseDef.shaderStage))
+       if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
        {
-               if (subgroups::areSubgroupOperationsRequiredForStage(
-                                       caseDef.shaderStage))
+               if (subgroups::areSubgroupOperationsRequiredForStage(caseDef.shaderStage))
                {
                        return tcu::TestStatus::fail(
                                           "Shader stage " +
@@ -774,21 +483,22 @@ tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
                return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-               return subgroups::makeTessellationEvaluationFrameBufferTest(context,  VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
+               return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
        else
                TCU_THROW(InternalError, "Unhandled shader stage");
 }
 
+
 tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
 {
        if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
        {
                if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
                {
-                               return tcu::TestStatus::fail(
-                                                  "Shader stage " +
-                                                  subgroups::getShaderStageName(caseDef.shaderStage) +
-                                                  " is required to support subgroup operations!");
+                       return tcu::TestStatus::fail(
+                                       "Shader stage " +
+                                       subgroups::getShaderStageName(caseDef.shaderStage) +
+                                       " is required to support subgroup operations!");
                }
                subgroups::SSBOData inputData;
                inputData.format = caseDef.format;
@@ -854,7 +564,7 @@ tcu::TestCaseGroup* createSubgroupsClusteredTests(tcu::TestContext& testCtx)
                VK_SHADER_STAGE_VERTEX_BIT,
                VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
                VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
-               VK_SHADER_STAGE_GEOMETRY_BIT
+               VK_SHADER_STAGE_GEOMETRY_BIT,
        };
 
        const std::vector<VkFormat> formats = subgroups::getAllFormats();
@@ -937,7 +647,7 @@ tcu::TestCaseGroup* createSubgroupsClusteredTests(tcu::TestContext& testCtx)
                        {
                                const CaseDefinition caseDef = {opTypeIndex, stages[stageIndex], format, de::SharedPtr<bool>(new bool)};
                                addFunctionCaseWithPrograms(framebufferGroup.get(), name +"_" + getShaderStageName(caseDef.shaderStage), "",
-                                                                                       supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
+                                                       supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
                        }
                }
        }
@@ -950,6 +660,5 @@ tcu::TestCaseGroup* createSubgroupsClusteredTests(tcu::TestContext& testCtx)
 
        return group.release();
 }
-
 } // subgroups
 } // vkt
index 15f76f5..609a723 100755 (executable)
@@ -84,14 +84,14 @@ struct CaseDefinition
        de::SharedPtr<bool>     geometryPointSizeSupported;
 };
 
-std::string GetExtHeader(VkFormat format)
+std::string getExtHeader(VkFormat format)
 {
        return  "#extension GL_KHR_shader_subgroup_quad: enable\n"
                        "#extension GL_KHR_shader_subgroup_ballot: enable\n" +
                        subgroups::getAdditionalExtensionForFormat(format);
 }
 
-std::string GetTestSrc(const CaseDefinition &caseDef)
+std::string getTestSrc(const CaseDefinition &caseDef)
 {
        const std::string swapTable[OPTYPE_LAST] = {
                "",
@@ -133,295 +133,21 @@ std::string GetTestSrc(const CaseDefinition &caseDef)
        return testSrc.str();
 }
 
-void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
+void initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
        const vk::ShaderBuildOptions    buildOptions    (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
 
-       subgroups::setFragmentShaderFrameBuffer(programCollection);
-
-       if (VK_SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
-               subgroups::setVertexShaderFrameBuffer(programCollection);
-
-       std::string extHeader = GetExtHeader(caseDef.format);
-       std::string testSrc = GetTestSrc(caseDef);
-
-       if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream      vertexSrc;
-               vertexSrc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << extHeader.c_str()
-                       << "layout(location = 0) in highp vec4 in_position;\n"
-                       << "layout(location = 0) out float result;\n"
-                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  uint tempRes;\n"
-                       << testSrc
-                       << "  result = float(tempRes);\n"
-                       << "  gl_Position = in_position;\n"
-                       << "  gl_PointSize = 1.0f;\n"
-                       << "}\n";
-               programCollection.glslSources.add("vert")
-                       << glu::VertexSource(vertexSrc.str()) << buildOptions;
-       }
-       else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream geometry;
-
-               geometry << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << extHeader.c_str()
-                       << "layout(points) in;\n"
-                       << "layout(points, max_vertices = 1) out;\n"
-                       << "layout(location = 0) out float out_color;\n"
-
-                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  uint tempRes;\n"
-                       << testSrc
-                       << "  out_color = float(tempRes);\n"
-                       << "  gl_Position = gl_in[0].gl_Position;\n"
-                       << (*caseDef.geometryPointSizeSupported ? "  gl_PointSize = gl_in[0].gl_PointSize;\n" : "")
-                       << "  EmitVertex();\n"
-                       << "  EndPrimitive();\n"
-                       << "}\n";
-
-               programCollection.glslSources.add("geometry")
-                       << glu::GeometrySource(geometry.str()) << buildOptions;
-       }
-       else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream controlSource;
-
-               controlSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << extHeader.c_str()
-                       << "layout(vertices = 2) out;\n"
-                       << "layout(location = 0) out float out_color[];\n"
-                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  if (gl_InvocationID == 0)\n"
-                       <<"  {\n"
-                       << "    gl_TessLevelOuter[0] = 1.0f;\n"
-                       << "    gl_TessLevelOuter[1] = 1.0f;\n"
-                       << "  }\n"
-                       << "  uint tempRes;\n"
-                       << testSrc
-                       << "  out_color[gl_InvocationID] = float(tempRes);\n"
-                       << "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-                       << "}\n";
-
-               programCollection.glslSources.add("tesc")
-                       << glu::TessellationControlSource(controlSource.str()) << buildOptions;
-               subgroups::setTesEvalShaderFrameBuffer(programCollection);
-       }
-       else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-       {
-               ostringstream evaluationSource;
-               evaluationSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
-                       << extHeader.c_str()
-                       << "layout(isolines, equal_spacing, ccw ) in;\n"
-                       << "layout(location = 0) out float out_color;\n"
-                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  uint tempRes;\n"
-                       << testSrc
-                       << "  out_color = float(tempRes);\n"
-                       << "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
-                       << "}\n";
-
-               subgroups::setTesCtrlShaderFrameBuffer(programCollection);
-               programCollection.glslSources.add("tese")
-                               << glu::TessellationEvaluationSource(evaluationSource.str()) << buildOptions;
-       }
-       else
-       {
-               DE_FATAL("Unsupported shader stage");
-       }
+   subgroups::initStdFrameBufferPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, getExtHeader(caseDef.format), getTestSrc(caseDef), "");
 }
 
 void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
 {
        const vk::ShaderBuildOptions    buildOptions    (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
 
-       std::string extHeader = GetExtHeader(caseDef.format);
-       std::string sourceType = GetTestSrc(caseDef);
-
-       if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
-       {
-               std::ostringstream src;
-
-               src << "#version 450\n"
-                       << extHeader.c_str()
-                       << "layout (local_size_x_id = 0, local_size_y_id = 1, "
-                       "local_size_z_id = 2) in;\n"
-                       << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-                       << "{\n"
-                       << "  uint result[];\n"
-                       << "};\n"
-                       << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
-                       << "{\n"
-                       << "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[];\n"
-                       << "};\n"
-                       << "\n"
-                       << "void main (void)\n"
-                       << "{\n"
-                       << "  uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
-                       << "  highp uint offset = globalSize.x * ((globalSize.y * "
-                       "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
-                       "gl_GlobalInvocationID.x;\n"
-                       << "  uint tempRes;\n"
-                       << sourceType
-                       << "  result[offset] = tempRes;\n"
-                       << "}\n";
-
-               programCollection.glslSources.add("comp") << glu::ComputeSource(src.str()) << buildOptions;
-       }
-       else
-       {
-               {
-                       const string vertex =
-                               "#version 450\n"
-                               + extHeader +
-                               "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
-                               "{\n"
-                               "  uint result[];\n"
-                               "};\n"
-                               "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                               "{\n"
-                               "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                               "};\n"
-                               "\n"
-                               "void main (void)\n"
-                               "{\n"
-                               "  uint tempRes;\n"
-                               + sourceType +
-                               "  result[gl_VertexIndex] = tempRes;\n"
-                               "  float pixelSize = 2.0f/1024.0f;\n"
-                               "  float pixelPosition = pixelSize/2.0f - 1.0f;\n"
-                               "  gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
-                               "  gl_PointSize = 1.0f;\n"
-                               "}\n";
-                       programCollection.glslSources.add("vert") << glu::VertexSource(vertex) << buildOptions;
-               }
-
-               {
-                       const string tesc =
-                               "#version 450\n"
-                               + extHeader +
-                               "layout(vertices=1) out;\n"
-                               "layout(set = 0, binding = 1, std430) buffer Buffer1\n"
-                               "{\n"
-                               "  uint result[];\n"
-                               "};\n"
-                               "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                               "{\n"
-                               "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                               "};\n"
-                               "\n"
-                               "void main (void)\n"
-                               "{\n"
-                               "  uint tempRes;\n"
-                               + sourceType +
-                               "  result[gl_PrimitiveID] = tempRes;\n"
-                               "  if (gl_InvocationID == 0)\n"
-                               "  {\n"
-                               "    gl_TessLevelOuter[0] = 1.0f;\n"
-                               "    gl_TessLevelOuter[1] = 1.0f;\n"
-                               "  }\n"
-                               "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
-                               "}\n";
-                       programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc) << buildOptions;
-               }
-
-               {
-                       const string tese =
-                               "#version 450\n"
-                               + extHeader +
-                               "layout(isolines) in;\n"
-                               "layout(set = 0, binding = 2, std430)  buffer Buffer1\n"
-                               "{\n"
-                               "  uint result[];\n"
-                               "};\n"
-                               "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                               "{\n"
-                               "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                               "};\n"
-                               "\n"
-                               "void main (void)\n"
-                               "{\n"
-                               "  uint tempRes;\n"
-                               + sourceType +
-                               "  result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempRes;\n"
-                               "  float pixelSize = 2.0f/1024.0f;\n"
-                               "  gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
-                               "}\n";
-                       programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese) << buildOptions;
-               }
+       std::string extHeader = getExtHeader(caseDef.format);
+       std::string testSrc = getTestSrc(caseDef);
 
-               {
-                       const string geometry =
-                               "#version 450\n"
-                               + extHeader +
-                               "layout(${TOPOLOGY}) in;\n"
-                               "layout(points, max_vertices = 1) out;\n"
-                               "layout(set = 0, binding = 3, std430) buffer Buffer1\n"
-                               "{\n"
-                               "  uint result[];\n"
-                               "};\n"
-                               "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                               "{\n"
-                               "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                               "};\n"
-                               "\n"
-                               "void main (void)\n"
-                               "{\n"
-                               "  uint tempRes;\n"
-                               + sourceType +
-                               "  result[gl_PrimitiveIDIn] = tempRes;\n"
-                               "  gl_Position = gl_in[0].gl_Position;\n"
-                               "  EmitVertex();\n"
-                               "  EndPrimitive();\n"
-                               "}\n";
-                       subgroups::addGeometryShadersFromTemplate(geometry, buildOptions, programCollection.glslSources);
-               }
-
-               {
-                       const string fragment =
-                               "#version 450\n"
-                               + extHeader +
-                               "layout(location = 0) out uint result;\n"
-                               "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
-                               "{\n"
-                               "  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
-                               "};\n"
-                               "void main (void)\n"
-                               "{\n"
-                               "  uint tempRes;\n"
-                               + sourceType +
-                               "  result = tempRes;\n"
-                               "}\n";
-                       programCollection.glslSources.add("fragment") << glu::FragmentSource(fragment)<< buildOptions;
-               }
-               subgroups::addNoSubgroupShader(programCollection);
-       }
+       subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, extHeader, testSrc, "");
 }
 
 void supportedCheck (Context& context, CaseDefinition caseDef)
@@ -440,11 +166,9 @@ void supportedCheck (Context& context, CaseDefinition caseDef)
 
 tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
 {
-       if (!subgroups::areSubgroupOperationsSupportedForStage(
-                               context, caseDef.shaderStage))
+       if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
        {
-               if (subgroups::areSubgroupOperationsRequiredForStage(
-                                       caseDef.shaderStage))
+               if (subgroups::areSubgroupOperationsRequiredForStage(caseDef.shaderStage))
                {
                        return tcu::TestStatus::fail(
                                           "Shader stage " +
@@ -461,7 +185,7 @@ tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
        inputData.format = caseDef.format;
        inputData.layout = subgroups::SSBOData::LayoutStd140;
        inputData.numElements = subgroups::maxSupportedSubgroupSize();
-       inputData.initializeType = subgroups::SSBOData::InitializeNonZero;;
+       inputData.initializeType = subgroups::SSBOData::InitializeNonZero;
 
        if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
                return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages);
@@ -470,7 +194,7 @@ tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
        else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
                return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
        else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
-               return subgroups::makeTessellationEvaluationFrameBufferTest(context,  VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
+               return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
        else
                TCU_THROW(InternalError, "Unhandled shader stage");
 }
@@ -483,9 +207,9 @@ tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
                if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
                {
                        return tcu::TestStatus::fail(
-                                          "Shader stage " +
-                                          subgroups::getShaderStageName(caseDef.shaderStage) +
-                                          " is required to support subgroup operations!");
+                                       "Shader stage " +
+                                       subgroups::getShaderStageName(caseDef.shaderStage) +
+                                       " is required to support subgroup operations!");
                }
                subgroups::SSBOData inputData;
                inputData.format = caseDef.format;
@@ -589,7 +313,6 @@ tcu::TestCaseGroup* createSubgroupsQuadTests(tcu::TestContext& testCtx)
                                addFunctionCaseWithPrograms(framebufferGroup.get(), name.str()+"_"+ getShaderStageName(caseDef.shaderStage), "",
                                                                                        supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
                        }
-
                }
        }
 
index 3775221..ab4752f 100644 (file)
@@ -962,6 +962,299 @@ std::string vkt::subgroups::getVertShaderForStage(vk::VkShaderStageFlags stage)
        }
 }
 
+void vkt::subgroups::initStdFrameBufferPrograms(       SourceCollections&                              programCollection,
+                                                                                                       const vk::ShaderBuildOptions&   buildOptions,
+                                                                                                       VkShaderStageFlags                              shaderStage,
+                                                                                                       VkFormat                                                format,
+                                                                                                       bool                                                    gsPointSize,
+                                                                                                       std::string                                             extHeader,
+                                                                                                       std::string                                             testSrc,
+                                                                                                       std::string                                             helperStr)
+{
+       subgroups::setFragmentShaderFrameBuffer(programCollection);
+
+       if (shaderStage != VK_SHADER_STAGE_VERTEX_BIT)
+               subgroups::setVertexShaderFrameBuffer(programCollection);
+
+       if (shaderStage == VK_SHADER_STAGE_VERTEX_BIT)
+       {
+               std::ostringstream vertex;
+               vertex << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
+                       << extHeader.c_str()
+                       << "layout(location = 0) in highp vec4 in_position;\n"
+                       << "layout(location = 0) out float result;\n"
+                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
+                       << "{\n"
+                       << "  " << subgroups::getFormatNameForGLSL(format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
+                       << "};\n"
+                       << "\n"
+                       << helperStr.c_str()
+                       << "void main (void)\n"
+                       << "{\n"
+                       << "  uint tempRes;\n"
+                       << testSrc
+                       << "  result = float(tempRes);\n"
+                       << "  gl_Position = in_position;\n"
+                       << "  gl_PointSize = 1.0f;\n"
+                       << "}\n";
+               programCollection.glslSources.add("vert")
+                       << glu::VertexSource(vertex.str()) << buildOptions;
+       }
+       else if (shaderStage == VK_SHADER_STAGE_GEOMETRY_BIT)
+       {
+               std::ostringstream geometry;
+
+               geometry << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
+                       << extHeader.c_str()
+                       << "layout(points) in;\n"
+                       << "layout(points, max_vertices = 1) out;\n"
+                       << "layout(location = 0) out float out_color;\n"
+                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
+                       << "{\n"
+                       << "  " << subgroups::getFormatNameForGLSL(format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
+                       << "};\n"
+                       << "\n"
+                       << helperStr.c_str()
+                       << "void main (void)\n"
+                       << "{\n"
+                       << "  uint tempRes;\n"
+                       << testSrc
+                       << "  out_color = float(tempRes);\n"
+                       << "  gl_Position = gl_in[0].gl_Position;\n"
+                       << (gsPointSize ? "  gl_PointSize = gl_in[0].gl_PointSize;\n" : "")
+                       << "  EmitVertex();\n"
+                       << "  EndPrimitive();\n"
+                       << "}\n";
+
+               programCollection.glslSources.add("geometry")
+                       << glu::GeometrySource(geometry.str()) << buildOptions;
+       }
+       else if (shaderStage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
+       {
+               std::ostringstream controlSource;
+               controlSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
+                       << extHeader.c_str()
+                       << "layout(vertices = 2) out;\n"
+                       << "layout(location = 0) out float out_color[];\n"
+                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
+                       << "{\n"
+                       << "  " << subgroups::getFormatNameForGLSL(format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
+                       << "};\n"
+                       << "\n"
+                       << helperStr.c_str()
+                       << "void main (void)\n"
+                       << "{\n"
+                       << "  if (gl_InvocationID == 0)\n"
+                       << "  {\n"
+                       << "    gl_TessLevelOuter[0] = 1.0f;\n"
+                       << "    gl_TessLevelOuter[1] = 1.0f;\n"
+                       << "  }\n"
+                       << "  uint tempRes;\n"
+                       << testSrc
+                       << "  out_color[gl_InvocationID] = float(tempRes);\n"
+                       << "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+                       << "}\n";
+
+               programCollection.glslSources.add("tesc")
+                       << glu::TessellationControlSource(controlSource.str()) << buildOptions;
+               subgroups::setTesEvalShaderFrameBuffer(programCollection);
+       }
+       else if (shaderStage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
+       {
+               ostringstream evaluationSource;
+               evaluationSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
+                       << extHeader.c_str()
+                       << "layout(isolines, equal_spacing, ccw ) in;\n"
+                       << "layout(location = 0) out float out_color;\n"
+                       << "layout(set = 0, binding = 0) uniform Buffer1\n"
+                       << "{\n"
+                       << "  " << subgroups::getFormatNameForGLSL(format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
+                       << "};\n"
+                       << "\n"
+                       << helperStr.c_str()
+                       << "void main (void)\n"
+                       << "{\n"
+                       << "  uint tempRes;\n"
+                       << testSrc
+                       << "  out_color = float(tempRes);\n"
+                       << "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
+                       << "}\n";
+
+               subgroups::setTesCtrlShaderFrameBuffer(programCollection);
+               programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(evaluationSource.str()) << buildOptions;
+       }
+       else
+       {
+               DE_FATAL("Unsupported shader stage");
+       }
+}
+
+void vkt::subgroups::initStdPrograms(  vk::SourceCollections&                  programCollection,
+                                                                               const vk::ShaderBuildOptions&   buildOptions,
+                                                                               vk::VkShaderStageFlags                  shaderStage,
+                                                                               vk::VkFormat                                    format,
+                                                                               std::string                                             extHeader,
+                                                                               std::string                                             testSrc,
+                                                                               std::string                                             helperStr)
+{
+       if (shaderStage == VK_SHADER_STAGE_COMPUTE_BIT)
+       {
+               std::ostringstream src;
+
+               src << "#version 450\n"
+                       << extHeader.c_str()
+                       << "layout (local_size_x_id = 0, local_size_y_id = 1, "
+                       "local_size_z_id = 2) in;\n"
+                       << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
+                       << "{\n"
+                       << "  uint result[];\n"
+                       << "};\n"
+                       << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
+                       << "{\n"
+                       << "  " << subgroups::getFormatNameForGLSL(format) << " data[];\n"
+                       << "};\n"
+                       << "\n"
+                       << helperStr.c_str()
+                       << "void main (void)\n"
+                       << "{\n"
+                       << "  uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
+                       << "  highp uint offset = globalSize.x * ((globalSize.y * "
+                       "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
+                       "gl_GlobalInvocationID.x;\n"
+                       << "  uint tempRes;\n"
+                       << testSrc
+                       << "  result[offset] = tempRes;\n"
+                       << "}\n";
+
+               programCollection.glslSources.add("comp") << glu::ComputeSource(src.str()) << buildOptions;
+       }
+       else
+       {
+               const string vertex =
+                       "#version 450\n"
+                       + extHeader +
+                       "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
+                       "{\n"
+                       "  uint result[];\n"
+                       "};\n"
+                       "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
+                       "{\n"
+                       "  " + subgroups::getFormatNameForGLSL(format) + " data[];\n"
+                       "};\n"
+                       "\n"
+                       + helperStr +
+                       "void main (void)\n"
+                       "{\n"
+                       "  uint tempRes;\n"
+                       + testSrc +
+                       "  result[gl_VertexIndex] = tempRes;\n"
+                       "  float pixelSize = 2.0f/1024.0f;\n"
+                       "  float pixelPosition = pixelSize/2.0f - 1.0f;\n"
+                       "  gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
+                       "  gl_PointSize = 1.0f;\n"
+                       "}\n";
+
+               const string tesc =
+                       "#version 450\n"
+                       + extHeader +
+                       "layout(vertices=1) out;\n"
+                       "layout(set = 0, binding = 1, std430) buffer Buffer1\n"
+                       "{\n"
+                       "  uint result[];\n"
+                       "};\n"
+                       "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
+                       "{\n"
+                       "  " + subgroups::getFormatNameForGLSL(format) + " data[];\n"
+                       "};\n"
+                       "\n"
+                       + helperStr +
+                       "void main (void)\n"
+                       "{\n"
+                       "  uint tempRes;\n"
+                       + testSrc +
+                       "  result[gl_PrimitiveID] = tempRes;\n"
+                       "  if (gl_InvocationID == 0)\n"
+                       "  {\n"
+                       "    gl_TessLevelOuter[0] = 1.0f;\n"
+                       "    gl_TessLevelOuter[1] = 1.0f;\n"
+                       "  }\n"
+                       "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+                       "}\n";
+
+               const string tese =
+                       "#version 450\n"
+                       + extHeader +
+                       "layout(isolines) in;\n"
+                       "layout(set = 0, binding = 2, std430) buffer Buffer1\n"
+                       "{\n"
+                       "  uint result[];\n"
+                       "};\n"
+                       "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
+                       "{\n"
+                       "  " + subgroups::getFormatNameForGLSL(format) + " data[];\n"
+                       "};\n"
+                       "\n"
+                       + helperStr +
+                       "void main (void)\n"
+                       "{\n"
+                       "  uint tempRes;\n"
+                       + testSrc +
+                       "  result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempRes;\n"
+                       "  float pixelSize = 2.0f/1024.0f;\n"
+                       "  gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
+                       "}\n";
+
+               const string geometry =
+                       "#version 450\n"
+                       + extHeader +
+                       "layout(${TOPOLOGY}) in;\n"
+                       "layout(points, max_vertices = 1) out;\n"
+                       "layout(set = 0, binding = 3, std430) buffer Buffer1\n"
+                       "{\n"
+                       "  uint result[];\n"
+                       "};\n"
+                       "layout(set = 0, binding = 4, std430) readonly buffer Buffer2\n"
+                       "{\n"
+                       "  " + subgroups::getFormatNameForGLSL(format) + " data[];\n"
+                       "};\n"
+                       "\n"
+                       + helperStr +
+                       "void main (void)\n"
+                       "{\n"
+                       "  uint tempRes;\n"
+                       + testSrc +
+                       "  result[gl_PrimitiveIDIn] = tempRes;\n"
+                       "  gl_Position = gl_in[0].gl_Position;\n"
+                       "  EmitVertex();\n"
+                       "  EndPrimitive();\n"
+                       "}\n";
+
+               const string fragment =
+                       "#version 450\n"
+                       + extHeader +
+                       "layout(location = 0) out uint result;\n"
+                       "layout(set = 0, binding = 4, std430) readonly buffer Buffer1\n"
+                       "{\n"
+                       "  " + subgroups::getFormatNameForGLSL(format) + " data[];\n"
+                       "};\n"
+                       + helperStr +
+                       "void main (void)\n"
+                       "{\n"
+                       "  uint tempRes;\n"
+                       + testSrc +
+                       "  result = tempRes;\n"
+                       "}\n";
+
+               subgroups::addNoSubgroupShader(programCollection);
+
+               programCollection.glslSources.add("vert") << glu::VertexSource(vertex) << buildOptions;
+               programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc) << buildOptions;
+               programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese) << buildOptions;
+               subgroups::addGeometryShadersFromTemplate(geometry, buildOptions, programCollection.glslSources);
+               programCollection.glslSources.add("fragment") << glu::FragmentSource(fragment)<< buildOptions;
+       }
+}
+
 bool vkt::subgroups::isSubgroupSupported(Context& context)
 {
        return context.contextSupports(vk::ApiVersion(1, 1, 0));
index 67e2256..4fe6d57 100644 (file)
@@ -104,6 +104,23 @@ void addNoSubgroupShader (vk::SourceCollections& programCollection);
 
 std::string getVertShaderForStage(vk::VkShaderStageFlags stage);//TODO
 
+void initStdFrameBufferPrograms(       vk::SourceCollections&                  programCollection,
+                                                                       const vk::ShaderBuildOptions&   buildOptions,
+                                                                       vk::VkShaderStageFlags                  shaderStage,
+                                                                       vk::VkFormat                                    format,
+                                                                       bool                                                    gsPointSize,
+                                                                       std::string                                             extHeader,
+                                                                       std::string                                             testSrc,
+                                                                       std::string                                             helperStr);
+
+void initStdPrograms(  vk::SourceCollections&                  programCollection,
+                                                               const vk::ShaderBuildOptions&   buildOptions,
+                                                               vk::VkShaderStageFlags                  shaderStage,
+                                                               vk::VkFormat                                    format,
+                                                               std::string                                             extHeader,
+                                                               std::string                                             testSrc,
+                                                               std::string                                             helperStr);
+
 bool isSubgroupSupported(Context& context);
 
 bool areSubgroupOperationsSupportedForStage(