1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------ 2e5c31af7Sopenharmony_ci * OpenGL Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2017-2019 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * Copyright (c) 2017 Codeplay Software Ltd. 7e5c31af7Sopenharmony_ci * Copyright (c) 2019 NVIDIA Corporation. 8e5c31af7Sopenharmony_ci * 9e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 10e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 11e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 14e5c31af7Sopenharmony_ci * 15e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 16e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 17e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 19e5c31af7Sopenharmony_ci * limitations under the License. 20e5c31af7Sopenharmony_ci * 21e5c31af7Sopenharmony_ci */ /*! 22e5c31af7Sopenharmony_ci * \file 23e5c31af7Sopenharmony_ci * \brief Subgroups Tests 24e5c31af7Sopenharmony_ci */ /*--------------------------------------------------------------------*/ 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "glcSubgroupsBallotTests.hpp" 27e5c31af7Sopenharmony_ci#include "glcSubgroupsTestsUtils.hpp" 28e5c31af7Sopenharmony_ci 29e5c31af7Sopenharmony_ci#include <string> 30e5c31af7Sopenharmony_ci#include <vector> 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ciusing namespace tcu; 33e5c31af7Sopenharmony_ciusing namespace std; 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_cinamespace glc 36e5c31af7Sopenharmony_ci{ 37e5c31af7Sopenharmony_cinamespace subgroups 38e5c31af7Sopenharmony_ci{ 39e5c31af7Sopenharmony_cinamespace 40e5c31af7Sopenharmony_ci{ 41e5c31af7Sopenharmony_cistatic bool checkVertexPipelineStages(std::vector<const void*> datas, 42e5c31af7Sopenharmony_ci deUint32 width, deUint32) 43e5c31af7Sopenharmony_ci{ 44e5c31af7Sopenharmony_ci return glc::subgroups::check(datas, width, 0x7); 45e5c31af7Sopenharmony_ci} 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_cistatic bool checkComputeStage(std::vector<const void*> datas, 48e5c31af7Sopenharmony_ci const deUint32 numWorkgroups[3], const deUint32 localSize[3], 49e5c31af7Sopenharmony_ci deUint32) 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_ci return glc::subgroups::checkCompute(datas, numWorkgroups, localSize, 0x7); 52e5c31af7Sopenharmony_ci} 53e5c31af7Sopenharmony_ci 54e5c31af7Sopenharmony_cistruct CaseDefinition 55e5c31af7Sopenharmony_ci{ 56e5c31af7Sopenharmony_ci glc::subgroups::ShaderStageFlags shaderStage; 57e5c31af7Sopenharmony_ci}; 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_civoid initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef) 60e5c31af7Sopenharmony_ci{ 61e5c31af7Sopenharmony_ci std::ostringstream subgroupSizeStr; 62e5c31af7Sopenharmony_ci subgroupSizeStr << subgroups::maxSupportedSubgroupSize(); 63e5c31af7Sopenharmony_ci 64e5c31af7Sopenharmony_ci subgroups::setFragmentShaderFrameBuffer(programCollection); 65e5c31af7Sopenharmony_ci 66e5c31af7Sopenharmony_ci if (SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage) 67e5c31af7Sopenharmony_ci subgroups::setVertexShaderFrameBuffer(programCollection); 68e5c31af7Sopenharmony_ci 69e5c31af7Sopenharmony_ci if (SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage) 70e5c31af7Sopenharmony_ci { 71e5c31af7Sopenharmony_ci const string vertexGLSL = 72e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 73e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 74e5c31af7Sopenharmony_ci "layout(location = 0) in highp vec4 in_position;\n" 75e5c31af7Sopenharmony_ci "layout(location = 0) out float out_color;\n" 76e5c31af7Sopenharmony_ci "layout(binding = 0, std140) uniform Buffer1\n" 77e5c31af7Sopenharmony_ci "{\n" 78e5c31af7Sopenharmony_ci " uint data[" + subgroupSizeStr.str() + "];\n" 79e5c31af7Sopenharmony_ci "};\n" 80e5c31af7Sopenharmony_ci "\n" 81e5c31af7Sopenharmony_ci "void main (void)\n" 82e5c31af7Sopenharmony_ci "{\n" 83e5c31af7Sopenharmony_ci " uint tempResult = 0u;\n" 84e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(true)) ? 0x1u : 0u;\n" 85e5c31af7Sopenharmony_ci " bool bData = data[gl_SubgroupInvocationID] != 0u;\n" 86e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(bData)) ? 0x2u : 0u;\n" 87e5c31af7Sopenharmony_ci " tempResult |= uvec4(0) == subgroupBallot(false) ? 0x4u : 0u;\n" 88e5c31af7Sopenharmony_ci " out_color = float(tempResult);\n" 89e5c31af7Sopenharmony_ci " gl_Position = in_position;\n" 90e5c31af7Sopenharmony_ci " gl_PointSize = 1.0f;\n" 91e5c31af7Sopenharmony_ci "}\n"; 92e5c31af7Sopenharmony_ci programCollection.add("vert") << glu::VertexSource(vertexGLSL); 93e5c31af7Sopenharmony_ci } 94e5c31af7Sopenharmony_ci else if (SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage) 95e5c31af7Sopenharmony_ci { 96e5c31af7Sopenharmony_ci const string geometryGLSL = 97e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 98e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 99e5c31af7Sopenharmony_ci "layout(points) in;\n" 100e5c31af7Sopenharmony_ci "layout(points, max_vertices = 1) out;\n" 101e5c31af7Sopenharmony_ci "layout(location = 0) out float out_color;\n" 102e5c31af7Sopenharmony_ci "layout(binding = 0, std140) uniform Buffer1\n" 103e5c31af7Sopenharmony_ci "{\n" 104e5c31af7Sopenharmony_ci " uint data[" + subgroupSizeStr.str() + "];\n" 105e5c31af7Sopenharmony_ci "};\n" 106e5c31af7Sopenharmony_ci "\n" 107e5c31af7Sopenharmony_ci "void main (void)\n" 108e5c31af7Sopenharmony_ci "{\n" 109e5c31af7Sopenharmony_ci " uint tempResult = 0u;\n" 110e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(true)) ? 0x1u : 0u;\n" 111e5c31af7Sopenharmony_ci " bool bData = data[gl_SubgroupInvocationID] != 0u;\n" 112e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(bData)) ? 0x2u : 0u;\n" 113e5c31af7Sopenharmony_ci " tempResult |= uvec4(0) == subgroupBallot(false) ? 0x4u : 0u;\n" 114e5c31af7Sopenharmony_ci " out_color = float(tempResult);\n" 115e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 116e5c31af7Sopenharmony_ci " EmitVertex();\n" 117e5c31af7Sopenharmony_ci " EndPrimitive();\n" 118e5c31af7Sopenharmony_ci "}\n"; 119e5c31af7Sopenharmony_ci programCollection.add("geometry") << glu::GeometrySource(geometryGLSL); 120e5c31af7Sopenharmony_ci } 121e5c31af7Sopenharmony_ci else if (SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage) 122e5c31af7Sopenharmony_ci { 123e5c31af7Sopenharmony_ci const string controlSourceGLSL = 124e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 125e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 126e5c31af7Sopenharmony_ci "layout(vertices = 2) out;\n" 127e5c31af7Sopenharmony_ci "layout(location = 0) out float out_color[];\n" 128e5c31af7Sopenharmony_ci "layout(binding = 0, std140) uniform Buffer1\n" 129e5c31af7Sopenharmony_ci "{\n" 130e5c31af7Sopenharmony_ci " uint data[" + subgroupSizeStr.str() + "];\n" 131e5c31af7Sopenharmony_ci "};\n" 132e5c31af7Sopenharmony_ci "\n" 133e5c31af7Sopenharmony_ci "void main (void)\n" 134e5c31af7Sopenharmony_ci "{\n" 135e5c31af7Sopenharmony_ci " if (gl_InvocationID == 0)\n" 136e5c31af7Sopenharmony_ci " {\n" 137e5c31af7Sopenharmony_ci " gl_TessLevelOuter[0] = 1.0f;\n" 138e5c31af7Sopenharmony_ci " gl_TessLevelOuter[1] = 1.0f;\n" 139e5c31af7Sopenharmony_ci " }\n" 140e5c31af7Sopenharmony_ci " uint tempResult = 0u;\n" 141e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(true)) ? 0x1u : 0u;\n" 142e5c31af7Sopenharmony_ci " bool bData = data[gl_SubgroupInvocationID] != 0u;\n" 143e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(bData)) ? 0x2u : 0u;\n" 144e5c31af7Sopenharmony_ci " tempResult |= uvec4(0) == subgroupBallot(false) ? 0x4u : 0u;\n" 145e5c31af7Sopenharmony_ci " out_color[gl_InvocationID] = float(tempResult);\n" 146e5c31af7Sopenharmony_ci " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 147e5c31af7Sopenharmony_ci "}\n"; 148e5c31af7Sopenharmony_ci programCollection.add("tesc") << glu::TessellationControlSource(controlSourceGLSL); 149e5c31af7Sopenharmony_ci subgroups::setTesEvalShaderFrameBuffer(programCollection); 150e5c31af7Sopenharmony_ci 151e5c31af7Sopenharmony_ci } 152e5c31af7Sopenharmony_ci else if (SHADER_STAGE_TESS_EVALUATION_BIT == caseDef.shaderStage) 153e5c31af7Sopenharmony_ci { 154e5c31af7Sopenharmony_ci const string evaluationSourceGLSL = 155e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 156e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 157e5c31af7Sopenharmony_ci "layout(isolines, equal_spacing, ccw ) in;\n" 158e5c31af7Sopenharmony_ci "layout(location = 0) out float out_color;\n" 159e5c31af7Sopenharmony_ci "layout(binding = 0, std140) uniform Buffer1\n" 160e5c31af7Sopenharmony_ci "{\n" 161e5c31af7Sopenharmony_ci " uint data[" + subgroupSizeStr.str() + "];\n" 162e5c31af7Sopenharmony_ci "};\n" 163e5c31af7Sopenharmony_ci "\n" 164e5c31af7Sopenharmony_ci "void main (void)\n" 165e5c31af7Sopenharmony_ci "{\n" 166e5c31af7Sopenharmony_ci " uint tempResult = 0u;\n" 167e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(true)) ? 0x1u : 0u;\n" 168e5c31af7Sopenharmony_ci " bool bData = data[gl_SubgroupInvocationID] != 0u;\n" 169e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(bData)) ? 0x2u : 0u;\n" 170e5c31af7Sopenharmony_ci " tempResult |= uvec4(0) == subgroupBallot(false) ? 0x4u : 0u;\n" 171e5c31af7Sopenharmony_ci " out_color = float(tempResult);\n" 172e5c31af7Sopenharmony_ci " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n" 173e5c31af7Sopenharmony_ci "}\n"; 174e5c31af7Sopenharmony_ci programCollection.add("tese") << glu::TessellationEvaluationSource(evaluationSourceGLSL); 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_ci subgroups::setTesCtrlShaderFrameBuffer(programCollection); 177e5c31af7Sopenharmony_ci } 178e5c31af7Sopenharmony_ci else 179e5c31af7Sopenharmony_ci { 180e5c31af7Sopenharmony_ci DE_FATAL("Unsupported shader stage"); 181e5c31af7Sopenharmony_ci } 182e5c31af7Sopenharmony_ci} 183e5c31af7Sopenharmony_ci 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_civoid initPrograms(SourceCollections& programCollection, CaseDefinition caseDef) 186e5c31af7Sopenharmony_ci{ 187e5c31af7Sopenharmony_ci if (SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage) 188e5c31af7Sopenharmony_ci { 189e5c31af7Sopenharmony_ci std::ostringstream src; 190e5c31af7Sopenharmony_ci 191e5c31af7Sopenharmony_ci src << "${VERSION_DECL}\n" 192e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_ballot: enable\n" 193e5c31af7Sopenharmony_ci << "layout (${LOCAL_SIZE_X}, ${LOCAL_SIZE_Y}, ${LOCAL_SIZE_Z}) in;\n" 194e5c31af7Sopenharmony_ci << "layout(binding = 0, std430) buffer Buffer1\n" 195e5c31af7Sopenharmony_ci << "{\n" 196e5c31af7Sopenharmony_ci << " uint result[];\n" 197e5c31af7Sopenharmony_ci << "};\n" 198e5c31af7Sopenharmony_ci << "layout(binding = 1, std430) buffer Buffer2\n" 199e5c31af7Sopenharmony_ci << "{\n" 200e5c31af7Sopenharmony_ci << " uint data[];\n" 201e5c31af7Sopenharmony_ci << "};\n" 202e5c31af7Sopenharmony_ci << "\n" 203e5c31af7Sopenharmony_ci << subgroups::getSharedMemoryBallotHelper() 204e5c31af7Sopenharmony_ci << "void main (void)\n" 205e5c31af7Sopenharmony_ci << "{\n" 206e5c31af7Sopenharmony_ci << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n" 207e5c31af7Sopenharmony_ci << " highp uint offset = globalSize.x * ((globalSize.y * " 208e5c31af7Sopenharmony_ci "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + " 209e5c31af7Sopenharmony_ci "gl_GlobalInvocationID.x;\n" 210e5c31af7Sopenharmony_ci << " uint tempResult = 0u;\n" 211e5c31af7Sopenharmony_ci << " tempResult |= sharedMemoryBallot(true) == subgroupBallot(true) ? 0x1u : 0u;\n" 212e5c31af7Sopenharmony_ci << " bool bData = data[gl_SubgroupInvocationID] != 0u;\n" 213e5c31af7Sopenharmony_ci << " tempResult |= sharedMemoryBallot(bData) == subgroupBallot(bData) ? 0x2u : 0u;\n" 214e5c31af7Sopenharmony_ci << " tempResult |= uvec4(0) == subgroupBallot(false) ? 0x4u : 0u;\n" 215e5c31af7Sopenharmony_ci << " result[offset] = tempResult;\n" 216e5c31af7Sopenharmony_ci << "}\n"; 217e5c31af7Sopenharmony_ci 218e5c31af7Sopenharmony_ci programCollection.add("comp") << glu::ComputeSource(src.str()); 219e5c31af7Sopenharmony_ci } 220e5c31af7Sopenharmony_ci else 221e5c31af7Sopenharmony_ci { 222e5c31af7Sopenharmony_ci const string vertex = 223e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 224e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 225e5c31af7Sopenharmony_ci "layout(binding = 0, std430) buffer Buffer0\n" 226e5c31af7Sopenharmony_ci "{\n" 227e5c31af7Sopenharmony_ci " uint result[];\n" 228e5c31af7Sopenharmony_ci "} b0;\n" 229e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 230e5c31af7Sopenharmony_ci "{\n" 231e5c31af7Sopenharmony_ci " uint data[];\n" 232e5c31af7Sopenharmony_ci "};\n" 233e5c31af7Sopenharmony_ci "\n" 234e5c31af7Sopenharmony_ci "void main (void)\n" 235e5c31af7Sopenharmony_ci "{\n" 236e5c31af7Sopenharmony_ci " uint tempResult = 0u;\n" 237e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(true)) ? 0x1u : 0u;\n" 238e5c31af7Sopenharmony_ci " bool bData = data[gl_SubgroupInvocationID] != 0u;\n" 239e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(bData)) ? 0x2u : 0u;\n" 240e5c31af7Sopenharmony_ci " tempResult |= uvec4(0) == subgroupBallot(false) ? 0x4u : 0u;\n" 241e5c31af7Sopenharmony_ci " b0.result[gl_VertexID] = tempResult;\n" 242e5c31af7Sopenharmony_ci " float pixelSize = 2.0f/1024.0f;\n" 243e5c31af7Sopenharmony_ci " float pixelPosition = pixelSize/2.0f - 1.0f;\n" 244e5c31af7Sopenharmony_ci " gl_Position = vec4(float(gl_VertexID) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n" 245e5c31af7Sopenharmony_ci " gl_PointSize = 1.0f;\n" 246e5c31af7Sopenharmony_ci "}\n"; 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_ci const string tesc = 249e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 250e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 251e5c31af7Sopenharmony_ci "layout(vertices=1) out;\n" 252e5c31af7Sopenharmony_ci "layout(binding = 1, std430) buffer Buffer1\n" 253e5c31af7Sopenharmony_ci "{\n" 254e5c31af7Sopenharmony_ci " uint result[];\n" 255e5c31af7Sopenharmony_ci "} b1;\n" 256e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 257e5c31af7Sopenharmony_ci "{\n" 258e5c31af7Sopenharmony_ci " uint data[];\n" 259e5c31af7Sopenharmony_ci "};\n" 260e5c31af7Sopenharmony_ci "\n" 261e5c31af7Sopenharmony_ci "void main (void)\n" 262e5c31af7Sopenharmony_ci "{\n" 263e5c31af7Sopenharmony_ci " uint tempResult = 0u;\n" 264e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(true)) ? 0x1u : 0u;\n" 265e5c31af7Sopenharmony_ci " bool bData = data[gl_SubgroupInvocationID] != 0u;\n" 266e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(bData)) ? 0x2u : 0u;\n" 267e5c31af7Sopenharmony_ci " tempResult |= uvec4(0) == subgroupBallot(false) ? 0x4u : 0u;\n" 268e5c31af7Sopenharmony_ci " b1.result[gl_PrimitiveID] = tempResult;\n" 269e5c31af7Sopenharmony_ci " if (gl_InvocationID == 0)\n" 270e5c31af7Sopenharmony_ci " {\n" 271e5c31af7Sopenharmony_ci " gl_TessLevelOuter[0] = 1.0f;\n" 272e5c31af7Sopenharmony_ci " gl_TessLevelOuter[1] = 1.0f;\n" 273e5c31af7Sopenharmony_ci " }\n" 274e5c31af7Sopenharmony_ci " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 275e5c31af7Sopenharmony_ci "}\n"; 276e5c31af7Sopenharmony_ci 277e5c31af7Sopenharmony_ci const string tese = 278e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 279e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 280e5c31af7Sopenharmony_ci "layout(isolines) in;\n" 281e5c31af7Sopenharmony_ci "layout(binding = 2, std430) buffer Buffer2\n" 282e5c31af7Sopenharmony_ci "{\n" 283e5c31af7Sopenharmony_ci " uint result[];\n" 284e5c31af7Sopenharmony_ci "} b2;\n" 285e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 286e5c31af7Sopenharmony_ci "{\n" 287e5c31af7Sopenharmony_ci " uint data[];\n" 288e5c31af7Sopenharmony_ci "};\n" 289e5c31af7Sopenharmony_ci "\n" 290e5c31af7Sopenharmony_ci "void main (void)\n" 291e5c31af7Sopenharmony_ci "{\n" 292e5c31af7Sopenharmony_ci " uint tempResult = 0u;\n" 293e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(true)) ? 0x1u : 0u;\n" 294e5c31af7Sopenharmony_ci " bool bData = data[gl_SubgroupInvocationID] != 0u;\n" 295e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(bData)) ? 0x2u : 0u;\n" 296e5c31af7Sopenharmony_ci " tempResult |= uvec4(0) == subgroupBallot(false) ? 0x4u : 0u;\n" 297e5c31af7Sopenharmony_ci " b2.result[gl_PrimitiveID * 2 + int(gl_TessCoord.x + 0.5)] = tempResult;\n" 298e5c31af7Sopenharmony_ci " float pixelSize = 2.0f/1024.0f;\n" 299e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n" 300e5c31af7Sopenharmony_ci "}\n"; 301e5c31af7Sopenharmony_ci 302e5c31af7Sopenharmony_ci const string geometry = 303e5c31af7Sopenharmony_ci // version string added by addGeometryShadersFromTemplate 304e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 305e5c31af7Sopenharmony_ci "layout(${TOPOLOGY}) in;\n" 306e5c31af7Sopenharmony_ci "layout(points, max_vertices = 1) out;\n" 307e5c31af7Sopenharmony_ci "layout(binding = 3, std430) buffer Buffer3\n" 308e5c31af7Sopenharmony_ci "{\n" 309e5c31af7Sopenharmony_ci " uint result[];\n" 310e5c31af7Sopenharmony_ci "} b3;\n" 311e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 312e5c31af7Sopenharmony_ci "{\n" 313e5c31af7Sopenharmony_ci " uint data[];\n" 314e5c31af7Sopenharmony_ci "};\n" 315e5c31af7Sopenharmony_ci "\n" 316e5c31af7Sopenharmony_ci "void main (void)\n" 317e5c31af7Sopenharmony_ci "{\n" 318e5c31af7Sopenharmony_ci " uint tempResult = 0u;\n" 319e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(true)) ? 0x1u : 0u;\n" 320e5c31af7Sopenharmony_ci " bool bData = data[gl_SubgroupInvocationID] != 0u;\n" 321e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(bData)) ? 0x2u : 0u;\n" 322e5c31af7Sopenharmony_ci " tempResult |= uvec4(0) == subgroupBallot(false) ? 0x4u : 0u;\n" 323e5c31af7Sopenharmony_ci " b3.result[gl_PrimitiveIDIn] = tempResult;\n" 324e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 325e5c31af7Sopenharmony_ci " EmitVertex();\n" 326e5c31af7Sopenharmony_ci " EndPrimitive();\n" 327e5c31af7Sopenharmony_ci "}\n"; 328e5c31af7Sopenharmony_ci 329e5c31af7Sopenharmony_ci const string fragment = 330e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 331e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 332e5c31af7Sopenharmony_ci "precision highp int;\n" 333e5c31af7Sopenharmony_ci "layout(location = 0) out uint result;\n" 334e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 335e5c31af7Sopenharmony_ci "{\n" 336e5c31af7Sopenharmony_ci " uint data[];\n" 337e5c31af7Sopenharmony_ci "};\n" 338e5c31af7Sopenharmony_ci "void main (void)\n" 339e5c31af7Sopenharmony_ci "{\n" 340e5c31af7Sopenharmony_ci " uint tempResult = 0u;\n" 341e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(true)) ? 0x1u : 0u;\n" 342e5c31af7Sopenharmony_ci " bool bData = data[gl_SubgroupInvocationID] != 0u;\n" 343e5c31af7Sopenharmony_ci " tempResult |= !bool(uvec4(0) == subgroupBallot(bData)) ? 0x2u : 0u;\n" 344e5c31af7Sopenharmony_ci " tempResult |= uvec4(0) == subgroupBallot(false) ? 0x4u : 0u;\n" 345e5c31af7Sopenharmony_ci " result = tempResult;\n" 346e5c31af7Sopenharmony_ci "}\n"; 347e5c31af7Sopenharmony_ci 348e5c31af7Sopenharmony_ci subgroups::addNoSubgroupShader(programCollection); 349e5c31af7Sopenharmony_ci 350e5c31af7Sopenharmony_ci programCollection.add("vert") << glu::VertexSource(vertex); 351e5c31af7Sopenharmony_ci programCollection.add("tesc") << glu::TessellationControlSource(tesc); 352e5c31af7Sopenharmony_ci programCollection.add("tese") << glu::TessellationEvaluationSource(tese); 353e5c31af7Sopenharmony_ci subgroups::addGeometryShadersFromTemplate(geometry, programCollection); 354e5c31af7Sopenharmony_ci programCollection.add("fragment") << glu::FragmentSource(fragment); 355e5c31af7Sopenharmony_ci } 356e5c31af7Sopenharmony_ci} 357e5c31af7Sopenharmony_ci 358e5c31af7Sopenharmony_civoid supportedCheck (Context& context, CaseDefinition caseDef) 359e5c31af7Sopenharmony_ci{ 360e5c31af7Sopenharmony_ci DE_UNREF(caseDef); 361e5c31af7Sopenharmony_ci if (!subgroups::isSubgroupSupported(context)) 362e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Subgroup operations are not supported"); 363e5c31af7Sopenharmony_ci 364e5c31af7Sopenharmony_ci if (!subgroups::isSubgroupFeatureSupportedForDevice(context, SUBGROUP_FEATURE_BALLOT_BIT)) 365e5c31af7Sopenharmony_ci { 366e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support subgroup ballot operations"); 367e5c31af7Sopenharmony_ci } 368e5c31af7Sopenharmony_ci} 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_citcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef) 371e5c31af7Sopenharmony_ci{ 372e5c31af7Sopenharmony_ci if (!subgroups::areSubgroupOperationsSupportedForStage( 373e5c31af7Sopenharmony_ci context, caseDef.shaderStage)) 374e5c31af7Sopenharmony_ci { 375e5c31af7Sopenharmony_ci if (subgroups::areSubgroupOperationsRequiredForStage(caseDef.shaderStage)) 376e5c31af7Sopenharmony_ci { 377e5c31af7Sopenharmony_ci return tcu::TestStatus::fail( 378e5c31af7Sopenharmony_ci "Shader stage " + 379e5c31af7Sopenharmony_ci subgroups::getShaderStageName(caseDef.shaderStage) + 380e5c31af7Sopenharmony_ci " is required to support subgroup operations!"); 381e5c31af7Sopenharmony_ci } 382e5c31af7Sopenharmony_ci else 383e5c31af7Sopenharmony_ci { 384e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage"); 385e5c31af7Sopenharmony_ci } 386e5c31af7Sopenharmony_ci } 387e5c31af7Sopenharmony_ci 388e5c31af7Sopenharmony_ci subgroups::SSBOData inputData[1]; 389e5c31af7Sopenharmony_ci inputData[0].format = FORMAT_R32_UINT; 390e5c31af7Sopenharmony_ci inputData[0].layout = subgroups::SSBOData::LayoutStd140; 391e5c31af7Sopenharmony_ci inputData[0].numElements = subgroups::maxSupportedSubgroupSize(); 392e5c31af7Sopenharmony_ci inputData[0].initializeType = subgroups::SSBOData::InitializeNonZero; 393e5c31af7Sopenharmony_ci inputData[0].binding = 0u; 394e5c31af7Sopenharmony_ci 395e5c31af7Sopenharmony_ci if (SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage) 396e5c31af7Sopenharmony_ci return subgroups::makeVertexFrameBufferTest(context, FORMAT_R32_UINT, inputData, 1, checkVertexPipelineStages); 397e5c31af7Sopenharmony_ci else if (SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage) 398e5c31af7Sopenharmony_ci return subgroups::makeGeometryFrameBufferTest(context, FORMAT_R32_UINT, inputData, 1, checkVertexPipelineStages); 399e5c31af7Sopenharmony_ci else if (SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage) 400e5c31af7Sopenharmony_ci return subgroups::makeTessellationEvaluationFrameBufferTest(context, FORMAT_R32_UINT, inputData, 1, checkVertexPipelineStages, SHADER_STAGE_TESS_CONTROL_BIT); 401e5c31af7Sopenharmony_ci else if (SHADER_STAGE_TESS_EVALUATION_BIT == caseDef.shaderStage) 402e5c31af7Sopenharmony_ci return subgroups::makeTessellationEvaluationFrameBufferTest(context, FORMAT_R32_UINT, inputData, 1, checkVertexPipelineStages, SHADER_STAGE_TESS_EVALUATION_BIT); 403e5c31af7Sopenharmony_ci else 404e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Unhandled shader stage"); 405e5c31af7Sopenharmony_ci} 406e5c31af7Sopenharmony_ci 407e5c31af7Sopenharmony_citcu::TestStatus test(Context& context, const CaseDefinition caseDef) 408e5c31af7Sopenharmony_ci{ 409e5c31af7Sopenharmony_ci if (SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage) 410e5c31af7Sopenharmony_ci { 411e5c31af7Sopenharmony_ci if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage)) 412e5c31af7Sopenharmony_ci { 413e5c31af7Sopenharmony_ci return tcu::TestStatus::fail( 414e5c31af7Sopenharmony_ci "Shader stage " + 415e5c31af7Sopenharmony_ci subgroups::getShaderStageName(caseDef.shaderStage) + 416e5c31af7Sopenharmony_ci " is required to support subgroup operations!"); 417e5c31af7Sopenharmony_ci } 418e5c31af7Sopenharmony_ci subgroups::SSBOData inputData[1]; 419e5c31af7Sopenharmony_ci inputData[0].format = FORMAT_R32_UINT; 420e5c31af7Sopenharmony_ci inputData[0].layout = subgroups::SSBOData::LayoutStd430; 421e5c31af7Sopenharmony_ci inputData[0].numElements = subgroups::maxSupportedSubgroupSize(); 422e5c31af7Sopenharmony_ci inputData[0].initializeType = subgroups::SSBOData::InitializeNonZero; 423e5c31af7Sopenharmony_ci inputData[0].binding = 1u; 424e5c31af7Sopenharmony_ci 425e5c31af7Sopenharmony_ci return subgroups::makeComputeTest(context, FORMAT_R32_UINT, inputData, 1, checkComputeStage); 426e5c31af7Sopenharmony_ci } 427e5c31af7Sopenharmony_ci else 428e5c31af7Sopenharmony_ci { 429e5c31af7Sopenharmony_ci int supportedStages = context.getDeqpContext().getContextInfo().getInt(GL_SUBGROUP_SUPPORTED_STAGES_KHR); 430e5c31af7Sopenharmony_ci 431e5c31af7Sopenharmony_ci ShaderStageFlags stages = (ShaderStageFlags)(caseDef.shaderStage & supportedStages); 432e5c31af7Sopenharmony_ci 433e5c31af7Sopenharmony_ci if ( SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context)) 434e5c31af7Sopenharmony_ci { 435e5c31af7Sopenharmony_ci if ( (stages & SHADER_STAGE_FRAGMENT_BIT) == 0) 436e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes"); 437e5c31af7Sopenharmony_ci else 438e5c31af7Sopenharmony_ci stages = SHADER_STAGE_FRAGMENT_BIT; 439e5c31af7Sopenharmony_ci } 440e5c31af7Sopenharmony_ci 441e5c31af7Sopenharmony_ci if ((ShaderStageFlags)0u == stages) 442e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Subgroup operations are not supported for any graphic shader"); 443e5c31af7Sopenharmony_ci 444e5c31af7Sopenharmony_ci subgroups::SSBOData inputData; 445e5c31af7Sopenharmony_ci inputData.format = FORMAT_R32_UINT; 446e5c31af7Sopenharmony_ci inputData.layout = subgroups::SSBOData::LayoutStd430; 447e5c31af7Sopenharmony_ci inputData.numElements = subgroups::maxSupportedSubgroupSize(); 448e5c31af7Sopenharmony_ci inputData.initializeType = subgroups::SSBOData::InitializeNonZero; 449e5c31af7Sopenharmony_ci inputData.binding = 4u; 450e5c31af7Sopenharmony_ci inputData.stages = stages; 451e5c31af7Sopenharmony_ci 452e5c31af7Sopenharmony_ci return subgroups::allStages(context, FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, stages); 453e5c31af7Sopenharmony_ci } 454e5c31af7Sopenharmony_ci} 455e5c31af7Sopenharmony_ci} 456e5c31af7Sopenharmony_ci 457e5c31af7Sopenharmony_cideqp::TestCaseGroup* createSubgroupsBallotTests(deqp::Context& testCtx) 458e5c31af7Sopenharmony_ci{ 459e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> graphicGroup(new deqp::TestCaseGroup( 460e5c31af7Sopenharmony_ci testCtx, "graphics", "Subgroup ballot category tests: graphics")); 461e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> computeGroup(new deqp::TestCaseGroup( 462e5c31af7Sopenharmony_ci testCtx, "compute", "Subgroup ballot category tests: compute")); 463e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> framebufferGroup(new deqp::TestCaseGroup( 464e5c31af7Sopenharmony_ci testCtx, "framebuffer", "Subgroup ballot category tests: framebuffer")); 465e5c31af7Sopenharmony_ci 466e5c31af7Sopenharmony_ci const ShaderStageFlags stages[] = 467e5c31af7Sopenharmony_ci { 468e5c31af7Sopenharmony_ci SHADER_STAGE_TESS_EVALUATION_BIT, 469e5c31af7Sopenharmony_ci SHADER_STAGE_TESS_CONTROL_BIT, 470e5c31af7Sopenharmony_ci SHADER_STAGE_GEOMETRY_BIT, 471e5c31af7Sopenharmony_ci SHADER_STAGE_VERTEX_BIT 472e5c31af7Sopenharmony_ci }; 473e5c31af7Sopenharmony_ci 474e5c31af7Sopenharmony_ci { 475e5c31af7Sopenharmony_ci const CaseDefinition caseDef = {SHADER_STAGE_COMPUTE_BIT}; 476e5c31af7Sopenharmony_ci SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(computeGroup.get(), 477e5c31af7Sopenharmony_ci getShaderStageName(caseDef.shaderStage), "", 478e5c31af7Sopenharmony_ci supportedCheck, initPrograms, test, caseDef); 479e5c31af7Sopenharmony_ci } 480e5c31af7Sopenharmony_ci 481e5c31af7Sopenharmony_ci { 482e5c31af7Sopenharmony_ci const CaseDefinition caseDef = {SHADER_STAGE_ALL_GRAPHICS}; 483e5c31af7Sopenharmony_ci SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(graphicGroup.get(), "graphic", "", supportedCheck, initPrograms, test, caseDef); 484e5c31af7Sopenharmony_ci } 485e5c31af7Sopenharmony_ci 486e5c31af7Sopenharmony_ci for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex) 487e5c31af7Sopenharmony_ci { 488e5c31af7Sopenharmony_ci const CaseDefinition caseDef = {stages[stageIndex]}; 489e5c31af7Sopenharmony_ci SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(framebufferGroup.get(), getShaderStageName(caseDef.shaderStage), "", 490e5c31af7Sopenharmony_ci supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef); 491e5c31af7Sopenharmony_ci } 492e5c31af7Sopenharmony_ci 493e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> group(new deqp::TestCaseGroup( 494e5c31af7Sopenharmony_ci testCtx, "ballot", "Subgroup ballot category tests")); 495e5c31af7Sopenharmony_ci 496e5c31af7Sopenharmony_ci group->addChild(graphicGroup.release()); 497e5c31af7Sopenharmony_ci group->addChild(computeGroup.release()); 498e5c31af7Sopenharmony_ci group->addChild(framebufferGroup.release()); 499e5c31af7Sopenharmony_ci 500e5c31af7Sopenharmony_ci return group.release(); 501e5c31af7Sopenharmony_ci} 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_ci} // subgroups 504e5c31af7Sopenharmony_ci} // glc 505