<< " uint sgInvocation = gl_SubgroupInvocationID;\n";
}
- if (OPTYPE_BROADCAST == caseDef.opType)
+ const std::string fmt = subgroups::getFormatNameForGLSL(caseDef.format);
+
+ if (caseDef.opType == OPTYPE_BROADCAST)
{
- bdy << " uint tempResult = 0x3;\n";
+ bdy << " tempRes = 0x3;\n";
for (int i = 0; i < max; i++)
{
bdy << " {\n"
<< " const uint id = "<< i << ";\n"
- << " " << fmt << " op = " << broadcast << "(data1[sgInvocation], id);\n"
- << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " op = "
- << broadcast << "(data[sgInvocation], id);\n"
++ << " " << fmt << " op = " << 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";
}
}
- const std::string validate = " if (subgroupBallotBitExtract(mask, id) && op != data1[id])\n"
+ else if (caseDef.opType == OPTYPE_BROADCAST_NONCONST)
+ {
- << " " << fmt << " op = " << broadcast << "(data1[sgInvocation], id);\n"
++ const std::string validate = " if (subgroupBallotBitExtract(mask, id) && op != data[id])\n"
+ " tempResult = 0;\n";
+
+ bdy << " uint tempResult = 0x3;\n"
+ << " for (uint id = 0; id < sgSize; id++)\n"
+ << " {\n"
- << " " << fmt << " op = " << broadcast << "(data1[sgInvocation], id);\n"
++ << " " << fmt << " op = " << broadcast << "(data[sgInvocation], id);\n"
+ << validate
+ << " }\n"
+ << " // Test lane id that is only uniform across active lanes\n"
+ << " if (sgInvocation >= sgSize / 2)\n"
+ << " {\n"
+ << " uint id = sgInvocation & ~((sgSize / 2) - 1);\n"
++ << " " << fmt << " op = " << broadcast << "(data[sgInvocation], id);\n"
+ << validate
+ << " }\n";
+ }
else
{
- bdy << " uint tempResult = 0;\n"
+ bdy << " tempRes = 0;\n"
<< " uint firstActive = 0;\n"
<< " for (uint i = 0; i < sgSize; i++)\n"
<< " {\n"
void initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
{
- const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
+ const vk::SpirvVersion spirvVersion = (caseDef.opType == OPTYPE_BROADCAST_NONCONST) ? vk::SPIRV_VERSION_1_5 : vk::SPIRV_VERSION_1_3;
+ const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, spirvVersion, 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);
+ const vk::SpirvVersion spirvVersion = (caseDef.opType == OPTYPE_BROADCAST_NONCONST) ? vk::SPIRV_VERSION_1_5 : vk::SPIRV_VERSION_1_3;
+ const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, spirvVersion, 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)
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");
- }
+ if ((caseDef.opType == OPTYPE_BROADCAST_NONCONST) && !subgroups::isSubgroupBroadcastDynamicIdSupported(context))
+ TCU_THROW(NotSupportedError, "Device does not support SubgroupBroadcastDynamicId");
+
*caseDef.geometryPointSizeSupported = subgroups::isTessellationAndGeometryPointSizeSupported(context);
}