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 "glcSubgroupsVoteTests.hpp" 27e5c31af7Sopenharmony_ci#include "glcSubgroupsTestsUtils.hpp" 28e5c31af7Sopenharmony_ci 29e5c31af7Sopenharmony_ci#include <string> 30e5c31af7Sopenharmony_ci#include <vector> 31e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 32e5c31af7Sopenharmony_ci 33e5c31af7Sopenharmony_ciusing namespace tcu; 34e5c31af7Sopenharmony_ciusing namespace std; 35e5c31af7Sopenharmony_ci 36e5c31af7Sopenharmony_cinamespace glc 37e5c31af7Sopenharmony_ci{ 38e5c31af7Sopenharmony_cinamespace subgroups 39e5c31af7Sopenharmony_ci{ 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_cinamespace 42e5c31af7Sopenharmony_ci{ 43e5c31af7Sopenharmony_ci 44e5c31af7Sopenharmony_cienum OpType 45e5c31af7Sopenharmony_ci{ 46e5c31af7Sopenharmony_ci OPTYPE_ALL = 0, 47e5c31af7Sopenharmony_ci OPTYPE_ANY, 48e5c31af7Sopenharmony_ci OPTYPE_ALLEQUAL, 49e5c31af7Sopenharmony_ci OPTYPE_LAST 50e5c31af7Sopenharmony_ci}; 51e5c31af7Sopenharmony_ci 52e5c31af7Sopenharmony_cistatic bool checkVertexPipelineStages(std::vector<const void*> datas, 53e5c31af7Sopenharmony_ci deUint32 width, deUint32) 54e5c31af7Sopenharmony_ci{ 55e5c31af7Sopenharmony_ci return glc::subgroups::check(datas, width, 0x1F); 56e5c31af7Sopenharmony_ci} 57e5c31af7Sopenharmony_ci 58e5c31af7Sopenharmony_cistatic bool checkFragmentPipelineStages(std::vector<const void*> datas, 59e5c31af7Sopenharmony_ci deUint32 width, deUint32 height, deUint32) 60e5c31af7Sopenharmony_ci{ 61e5c31af7Sopenharmony_ci const deUint32* data = 62e5c31af7Sopenharmony_ci reinterpret_cast<const deUint32*>(datas[0]); 63e5c31af7Sopenharmony_ci for (deUint32 x = 0u; x < width; ++x) 64e5c31af7Sopenharmony_ci { 65e5c31af7Sopenharmony_ci for (deUint32 y = 0u; y < height; ++y) 66e5c31af7Sopenharmony_ci { 67e5c31af7Sopenharmony_ci const deUint32 ndx = (x * height + y); 68e5c31af7Sopenharmony_ci deUint32 val = data[ndx] & 0x1F; 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_ci if (data[ndx] & 0x40) //Helper fragment shader invocation was executed 71e5c31af7Sopenharmony_ci { 72e5c31af7Sopenharmony_ci if(val != 0x1F) 73e5c31af7Sopenharmony_ci return false; 74e5c31af7Sopenharmony_ci } 75e5c31af7Sopenharmony_ci else //Helper fragment shader invocation was not executed yet 76e5c31af7Sopenharmony_ci { 77e5c31af7Sopenharmony_ci if (val != 0x1E) 78e5c31af7Sopenharmony_ci return false; 79e5c31af7Sopenharmony_ci } 80e5c31af7Sopenharmony_ci } 81e5c31af7Sopenharmony_ci } 82e5c31af7Sopenharmony_ci return true; 83e5c31af7Sopenharmony_ci} 84e5c31af7Sopenharmony_ci 85e5c31af7Sopenharmony_cistatic bool checkComputeStage(std::vector<const void*> datas, 86e5c31af7Sopenharmony_ci const deUint32 numWorkgroups[3], const deUint32 localSize[3], 87e5c31af7Sopenharmony_ci deUint32) 88e5c31af7Sopenharmony_ci{ 89e5c31af7Sopenharmony_ci return glc::subgroups::checkCompute(datas, numWorkgroups, localSize, 0x1F); 90e5c31af7Sopenharmony_ci} 91e5c31af7Sopenharmony_ci 92e5c31af7Sopenharmony_cistd::string getOpTypeName(int opType) 93e5c31af7Sopenharmony_ci{ 94e5c31af7Sopenharmony_ci switch (opType) 95e5c31af7Sopenharmony_ci { 96e5c31af7Sopenharmony_ci default: 97e5c31af7Sopenharmony_ci DE_FATAL("Unsupported op type"); 98e5c31af7Sopenharmony_ci return ""; 99e5c31af7Sopenharmony_ci case OPTYPE_ALL: 100e5c31af7Sopenharmony_ci return "subgroupAll"; 101e5c31af7Sopenharmony_ci case OPTYPE_ANY: 102e5c31af7Sopenharmony_ci return "subgroupAny"; 103e5c31af7Sopenharmony_ci case OPTYPE_ALLEQUAL: 104e5c31af7Sopenharmony_ci return "subgroupAllEqual"; 105e5c31af7Sopenharmony_ci } 106e5c31af7Sopenharmony_ci} 107e5c31af7Sopenharmony_ci 108e5c31af7Sopenharmony_cistruct CaseDefinition 109e5c31af7Sopenharmony_ci{ 110e5c31af7Sopenharmony_ci int opType; 111e5c31af7Sopenharmony_ci ShaderStageFlags shaderStage; 112e5c31af7Sopenharmony_ci Format format; 113e5c31af7Sopenharmony_ci}; 114e5c31af7Sopenharmony_ci 115e5c31af7Sopenharmony_civoid initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef) 116e5c31af7Sopenharmony_ci{ 117e5c31af7Sopenharmony_ci const bool formatIsBoolean = 118e5c31af7Sopenharmony_ci FORMAT_R32_BOOL == caseDef.format || FORMAT_R32G32_BOOL == caseDef.format || FORMAT_R32G32B32_BOOL == caseDef.format || FORMAT_R32G32B32A32_BOOL == caseDef.format; 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ci if (SHADER_STAGE_FRAGMENT_BIT != caseDef.shaderStage) 121e5c31af7Sopenharmony_ci subgroups::setFragmentShaderFrameBuffer(programCollection); 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_ci if (SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage) 124e5c31af7Sopenharmony_ci { 125e5c31af7Sopenharmony_ci const string vertex = "${VERSION_DECL}\n" 126e5c31af7Sopenharmony_ci "void main (void)\n" 127e5c31af7Sopenharmony_ci "{\n" 128e5c31af7Sopenharmony_ci " vec2 uv = vec2(float(gl_VertexID & 1), float((gl_VertexID >> 1) & 1));\n" 129e5c31af7Sopenharmony_ci " gl_Position = vec4(uv * 4.0f -2.0f, 0.0f, 1.0f);\n" 130e5c31af7Sopenharmony_ci " gl_PointSize = 1.0f;\n" 131e5c31af7Sopenharmony_ci "}\n"; 132e5c31af7Sopenharmony_ci programCollection.add("vert") << glu::VertexSource(vertex); 133e5c31af7Sopenharmony_ci } 134e5c31af7Sopenharmony_ci else if (SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage) 135e5c31af7Sopenharmony_ci subgroups::setVertexShaderFrameBuffer(programCollection); 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_ci const string source = 138e5c31af7Sopenharmony_ci (OPTYPE_ALL == caseDef.opType) ? 139e5c31af7Sopenharmony_ci " result = " + getOpTypeName(caseDef.opType) + 140e5c31af7Sopenharmony_ci "(true) ? 0x1u : 0u;\n" 141e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 142e5c31af7Sopenharmony_ci "(false) ? 0u : 0x1Au;\n" 143e5c31af7Sopenharmony_ci " result |= 0x4u;\n" 144e5c31af7Sopenharmony_ci : (OPTYPE_ANY == caseDef.opType) ? 145e5c31af7Sopenharmony_ci " result = " + getOpTypeName(caseDef.opType) + 146e5c31af7Sopenharmony_ci "(true) ? 0x1u : 0u;\n" 147e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 148e5c31af7Sopenharmony_ci "(false) ? 0u : 0x1Au;\n" 149e5c31af7Sopenharmony_ci " result |= 0x4u;\n" 150e5c31af7Sopenharmony_ci : (OPTYPE_ALLEQUAL == caseDef.opType) ? 151e5c31af7Sopenharmony_ci " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + "(1.25 * float(data[gl_SubgroupInvocationID]) + 5.0);\n" + 152e5c31af7Sopenharmony_ci " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueNoEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + (formatIsBoolean ? "(subgroupElect())\n;" : "(12.0 * float(data[gl_SubgroupInvocationID]) + float(gl_SubgroupInvocationID));\n") + 153e5c31af7Sopenharmony_ci " result = " + getOpTypeName(caseDef.opType) + "(" 154e5c31af7Sopenharmony_ci + subgroups::getFormatNameForGLSL(caseDef.format) + "(1)) ? 0x1u : 0u;\n" 155e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 156e5c31af7Sopenharmony_ci "(gl_SubgroupInvocationID) ? 0u : 0x2u;\n" 157e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 158e5c31af7Sopenharmony_ci "(data[0]) ? 0x4u : 0u;\n" 159e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 160e5c31af7Sopenharmony_ci "(valueEqual) ? 0x8u : 0x0u;\n" 161e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 162e5c31af7Sopenharmony_ci "(valueNoEqual) ? 0x0u : 0x10u;\n" 163e5c31af7Sopenharmony_ci " if (subgroupElect()) result |= 0x2u | 0x10u;\n" 164e5c31af7Sopenharmony_ci : ""; 165e5c31af7Sopenharmony_ci 166e5c31af7Sopenharmony_ci if (SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage) 167e5c31af7Sopenharmony_ci { 168e5c31af7Sopenharmony_ci std::ostringstream vertexSrc; 169e5c31af7Sopenharmony_ci vertexSrc << "${VERSION_DECL}\n" 170e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_vote: enable\n" 171e5c31af7Sopenharmony_ci << "layout(location = 0) out float out_color;\n" 172e5c31af7Sopenharmony_ci << "layout(location = 0) in highp vec4 in_position;\n" 173e5c31af7Sopenharmony_ci << "layout(binding = 0, std140) uniform Buffer1\n" 174e5c31af7Sopenharmony_ci << "{\n" 175e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n" 176e5c31af7Sopenharmony_ci << "};\n" 177e5c31af7Sopenharmony_ci << "\n" 178e5c31af7Sopenharmony_ci << "void main (void)\n" 179e5c31af7Sopenharmony_ci << "{\n" 180e5c31af7Sopenharmony_ci << " uint result;\n" 181e5c31af7Sopenharmony_ci << source 182e5c31af7Sopenharmony_ci << " out_color = float(result);\n" 183e5c31af7Sopenharmony_ci << " gl_Position = in_position;\n" 184e5c31af7Sopenharmony_ci << " gl_PointSize = 1.0f;\n" 185e5c31af7Sopenharmony_ci << "}\n"; 186e5c31af7Sopenharmony_ci 187e5c31af7Sopenharmony_ci programCollection.add("vert") << glu::VertexSource(vertexSrc.str()); 188e5c31af7Sopenharmony_ci } 189e5c31af7Sopenharmony_ci else if (SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage) 190e5c31af7Sopenharmony_ci { 191e5c31af7Sopenharmony_ci std::ostringstream geometry; 192e5c31af7Sopenharmony_ci 193e5c31af7Sopenharmony_ci geometry << "${VERSION_DECL}\n" 194e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_vote: enable\n" 195e5c31af7Sopenharmony_ci << "layout(points) in;\n" 196e5c31af7Sopenharmony_ci << "layout(points, max_vertices = 1) out;\n" 197e5c31af7Sopenharmony_ci << "layout(location = 0) out float out_color;\n" 198e5c31af7Sopenharmony_ci << "layout(binding = 0, std140) uniform Buffer1\n" 199e5c31af7Sopenharmony_ci << "{\n" 200e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n" 201e5c31af7Sopenharmony_ci << "};\n" 202e5c31af7Sopenharmony_ci << "\n" 203e5c31af7Sopenharmony_ci << "void main (void)\n" 204e5c31af7Sopenharmony_ci << "{\n" 205e5c31af7Sopenharmony_ci << " uint result;\n" 206e5c31af7Sopenharmony_ci << source 207e5c31af7Sopenharmony_ci << " out_color = float(result);\n" 208e5c31af7Sopenharmony_ci << " gl_Position = gl_in[0].gl_Position;\n" 209e5c31af7Sopenharmony_ci << " EmitVertex();\n" 210e5c31af7Sopenharmony_ci << " EndPrimitive();\n" 211e5c31af7Sopenharmony_ci << "}\n"; 212e5c31af7Sopenharmony_ci 213e5c31af7Sopenharmony_ci programCollection.add("geometry") << glu::GeometrySource(geometry.str()); 214e5c31af7Sopenharmony_ci } 215e5c31af7Sopenharmony_ci else if (SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage) 216e5c31af7Sopenharmony_ci { 217e5c31af7Sopenharmony_ci std::ostringstream controlSource; 218e5c31af7Sopenharmony_ci controlSource << "${VERSION_DECL}\n" 219e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_vote: enable\n" 220e5c31af7Sopenharmony_ci << "layout(vertices = 2) out;\n" 221e5c31af7Sopenharmony_ci << "layout(location = 0) out float out_color[];\n" 222e5c31af7Sopenharmony_ci << "layout(binding = 0, std140) uniform Buffer1\n" 223e5c31af7Sopenharmony_ci << "{\n" 224e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n" 225e5c31af7Sopenharmony_ci << "};\n" 226e5c31af7Sopenharmony_ci << "\n" 227e5c31af7Sopenharmony_ci << "void main (void)\n" 228e5c31af7Sopenharmony_ci << "{\n" 229e5c31af7Sopenharmony_ci << " uint result;\n" 230e5c31af7Sopenharmony_ci << " if (gl_InvocationID == 0)\n" 231e5c31af7Sopenharmony_ci <<" {\n" 232e5c31af7Sopenharmony_ci << " gl_TessLevelOuter[0] = 1.0f;\n" 233e5c31af7Sopenharmony_ci << " gl_TessLevelOuter[1] = 1.0f;\n" 234e5c31af7Sopenharmony_ci << " }\n" 235e5c31af7Sopenharmony_ci << source 236e5c31af7Sopenharmony_ci << " out_color[gl_InvocationID] = float(result);" 237e5c31af7Sopenharmony_ci << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 238e5c31af7Sopenharmony_ci << "}\n"; 239e5c31af7Sopenharmony_ci 240e5c31af7Sopenharmony_ci programCollection.add("tesc") << glu::TessellationControlSource(controlSource.str()); 241e5c31af7Sopenharmony_ci subgroups::setTesEvalShaderFrameBuffer(programCollection); 242e5c31af7Sopenharmony_ci } 243e5c31af7Sopenharmony_ci else if (SHADER_STAGE_TESS_EVALUATION_BIT == caseDef.shaderStage) 244e5c31af7Sopenharmony_ci { 245e5c31af7Sopenharmony_ci std::ostringstream evaluationSource; 246e5c31af7Sopenharmony_ci evaluationSource << "${VERSION_DECL}\n" 247e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_vote: enable\n" 248e5c31af7Sopenharmony_ci << "${TESS_EXTENSION}\n" 249e5c31af7Sopenharmony_ci << "layout(isolines, equal_spacing, ccw ) in;\n" 250e5c31af7Sopenharmony_ci << "layout(location = 0) out float out_color;\n" 251e5c31af7Sopenharmony_ci << "layout(binding = 0, std140) uniform Buffer1\n" 252e5c31af7Sopenharmony_ci << "{\n" 253e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n" 254e5c31af7Sopenharmony_ci << "};\n" 255e5c31af7Sopenharmony_ci << "\n" 256e5c31af7Sopenharmony_ci << "void main (void)\n" 257e5c31af7Sopenharmony_ci << "{\n" 258e5c31af7Sopenharmony_ci << " uint result;\n" 259e5c31af7Sopenharmony_ci << " highp uint offset = uint(gl_PrimitiveID) * 2u + uint(gl_TessCoord.x + 0.5);\n" 260e5c31af7Sopenharmony_ci << source 261e5c31af7Sopenharmony_ci << " out_color = float(result);\n" 262e5c31af7Sopenharmony_ci << " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n" 263e5c31af7Sopenharmony_ci << "}\n"; 264e5c31af7Sopenharmony_ci 265e5c31af7Sopenharmony_ci subgroups::setTesCtrlShaderFrameBuffer(programCollection); 266e5c31af7Sopenharmony_ci programCollection.add("tese") << glu::TessellationEvaluationSource(evaluationSource.str()); 267e5c31af7Sopenharmony_ci } 268e5c31af7Sopenharmony_ci else if (SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage) 269e5c31af7Sopenharmony_ci { 270e5c31af7Sopenharmony_ci const string sourceFragment = 271e5c31af7Sopenharmony_ci (OPTYPE_ALL == caseDef.opType) ? 272e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 273e5c31af7Sopenharmony_ci "(!gl_HelperInvocation) ? 0x0u : 0x1u;\n" 274e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 275e5c31af7Sopenharmony_ci "(false) ? 0u : 0x1Au;\n" 276e5c31af7Sopenharmony_ci " result |= 0x4u;\n" 277e5c31af7Sopenharmony_ci : (OPTYPE_ANY == caseDef.opType) ? 278e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 279e5c31af7Sopenharmony_ci "(gl_HelperInvocation) ? 0x1u : 0x0u;\n" 280e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 281e5c31af7Sopenharmony_ci "(false) ? 0u : 0x1Au;\n" 282e5c31af7Sopenharmony_ci " result |= 0x4u;\n" 283e5c31af7Sopenharmony_ci : (OPTYPE_ALLEQUAL == caseDef.opType) ? 284e5c31af7Sopenharmony_ci " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + "(1.25 * float(data[gl_SubgroupInvocationID]) + 5.0);\n" + 285e5c31af7Sopenharmony_ci " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueNoEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + (formatIsBoolean ? "(subgroupElect());\n" : "(12.0 * float(data[gl_SubgroupInvocationID]) + gl_FragCoord.x * float(gl_SubgroupInvocationID));\n") + 286e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + "(" 287e5c31af7Sopenharmony_ci + subgroups::getFormatNameForGLSL(caseDef.format) + "(1)) ? 0x10u : 0u;\n" 288e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 289e5c31af7Sopenharmony_ci "(gl_SubgroupInvocationID) ? 0u : 0x2u;\n" 290e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 291e5c31af7Sopenharmony_ci "(data[0]) ? 0x4u : 0u;\n" 292e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 293e5c31af7Sopenharmony_ci "(valueEqual) ? 0x8u : 0x0u;\n" 294e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 295e5c31af7Sopenharmony_ci "(gl_HelperInvocation) ? 0x0u : 0x1u;\n" 296e5c31af7Sopenharmony_ci " if (subgroupElect()) result |= 0x2u | 0x10u;\n" 297e5c31af7Sopenharmony_ci : ""; 298e5c31af7Sopenharmony_ci 299e5c31af7Sopenharmony_ci std::ostringstream fragmentSource; 300e5c31af7Sopenharmony_ci fragmentSource << "${VERSION_DECL}\n" 301e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_vote: enable\n" 302e5c31af7Sopenharmony_ci << "precision highp float;\n" 303e5c31af7Sopenharmony_ci << "layout(location = 0) out uint out_color;\n" 304e5c31af7Sopenharmony_ci << "layout(binding = 0, std140) uniform Buffer1\n" 305e5c31af7Sopenharmony_ci << "{\n" 306e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n" 307e5c31af7Sopenharmony_ci << "};\n" 308e5c31af7Sopenharmony_ci << "" 309e5c31af7Sopenharmony_ci << "void main()\n" 310e5c31af7Sopenharmony_ci << "{\n" 311e5c31af7Sopenharmony_ci << " uint result = 0u;\n" 312e5c31af7Sopenharmony_ci << " if (dFdx(float(gl_SubgroupInvocationID) * gl_FragCoord.x * gl_FragCoord.y) - dFdy(float(gl_SubgroupInvocationID) * gl_FragCoord.x * gl_FragCoord.y) > 0.0f)\n" 313e5c31af7Sopenharmony_ci << " {\n" 314e5c31af7Sopenharmony_ci << " result |= 0x20u;\n" // to be sure that compiler doesn't remove dFdx and dFdy executions 315e5c31af7Sopenharmony_ci << " }\n" 316e5c31af7Sopenharmony_ci << " bool helper = subgroupAny(gl_HelperInvocation);\n" 317e5c31af7Sopenharmony_ci << " if (helper)\n" 318e5c31af7Sopenharmony_ci << " {\n" 319e5c31af7Sopenharmony_ci << " result |= 0x40u;\n" 320e5c31af7Sopenharmony_ci << " }\n" 321e5c31af7Sopenharmony_ci << sourceFragment 322e5c31af7Sopenharmony_ci << " out_color = result;\n" 323e5c31af7Sopenharmony_ci << "}\n"; 324e5c31af7Sopenharmony_ci 325e5c31af7Sopenharmony_ci programCollection.add("fragment") << glu::FragmentSource(fragmentSource.str()); 326e5c31af7Sopenharmony_ci } 327e5c31af7Sopenharmony_ci else 328e5c31af7Sopenharmony_ci { 329e5c31af7Sopenharmony_ci DE_FATAL("Unsupported shader stage"); 330e5c31af7Sopenharmony_ci } 331e5c31af7Sopenharmony_ci} 332e5c31af7Sopenharmony_ci 333e5c31af7Sopenharmony_civoid initPrograms(SourceCollections& programCollection, CaseDefinition caseDef) 334e5c31af7Sopenharmony_ci{ 335e5c31af7Sopenharmony_ci const bool formatIsBoolean = 336e5c31af7Sopenharmony_ci FORMAT_R32_BOOL == caseDef.format || FORMAT_R32G32_BOOL == caseDef.format || FORMAT_R32G32B32_BOOL == caseDef.format || FORMAT_R32G32B32A32_BOOL == caseDef.format; 337e5c31af7Sopenharmony_ci if (SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage) 338e5c31af7Sopenharmony_ci { 339e5c31af7Sopenharmony_ci std::ostringstream src; 340e5c31af7Sopenharmony_ci 341e5c31af7Sopenharmony_ci src << "${VERSION_DECL}\n" 342e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_vote: enable\n" 343e5c31af7Sopenharmony_ci << "layout (${LOCAL_SIZE_X}, ${LOCAL_SIZE_Y}, ${LOCAL_SIZE_Z}) in;\n" 344e5c31af7Sopenharmony_ci << "layout(binding = 0, std430) buffer Buffer1\n" 345e5c31af7Sopenharmony_ci << "{\n" 346e5c31af7Sopenharmony_ci << " uint result[];\n" 347e5c31af7Sopenharmony_ci << "};\n" 348e5c31af7Sopenharmony_ci << "layout(binding = 1, std430) buffer Buffer2\n" 349e5c31af7Sopenharmony_ci << "{\n" 350e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[];\n" 351e5c31af7Sopenharmony_ci << "};\n" 352e5c31af7Sopenharmony_ci << "\n" 353e5c31af7Sopenharmony_ci << "void main (void)\n" 354e5c31af7Sopenharmony_ci << "{\n" 355e5c31af7Sopenharmony_ci << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n" 356e5c31af7Sopenharmony_ci << " highp uint offset = globalSize.x * ((globalSize.y * " 357e5c31af7Sopenharmony_ci "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + " 358e5c31af7Sopenharmony_ci "gl_GlobalInvocationID.x;\n"; 359e5c31af7Sopenharmony_ci if (OPTYPE_ALL == caseDef.opType) 360e5c31af7Sopenharmony_ci { 361e5c31af7Sopenharmony_ci src << " result[offset] = " << getOpTypeName(caseDef.opType) 362e5c31af7Sopenharmony_ci << "(true) ? 0x1u : 0u;\n" 363e5c31af7Sopenharmony_ci << " result[offset] |= " << getOpTypeName(caseDef.opType) 364e5c31af7Sopenharmony_ci << "(false) ? 0u : 0x1Au;\n" 365e5c31af7Sopenharmony_ci << " result[offset] |= " << getOpTypeName(caseDef.opType) 366e5c31af7Sopenharmony_ci << "(data[gl_SubgroupInvocationID] > 0u) ? 0x4u : 0u;\n"; 367e5c31af7Sopenharmony_ci } 368e5c31af7Sopenharmony_ci else if (OPTYPE_ANY == caseDef.opType) 369e5c31af7Sopenharmony_ci { 370e5c31af7Sopenharmony_ci src << " result[offset] = " << getOpTypeName(caseDef.opType) 371e5c31af7Sopenharmony_ci << "(true) ? 0x1u : 0u;\n" 372e5c31af7Sopenharmony_ci << " result[offset] |= " << getOpTypeName(caseDef.opType) 373e5c31af7Sopenharmony_ci << "(false) ? 0u : 0x1Au;\n" 374e5c31af7Sopenharmony_ci << " result[offset] |= " << getOpTypeName(caseDef.opType) 375e5c31af7Sopenharmony_ci << "(data[gl_SubgroupInvocationID] == data[0]) ? 0x4u : 0u;\n"; 376e5c31af7Sopenharmony_ci } 377e5c31af7Sopenharmony_ci 378e5c31af7Sopenharmony_ci else if (OPTYPE_ALLEQUAL == caseDef.opType) 379e5c31af7Sopenharmony_ci { 380e5c31af7Sopenharmony_ci src << " " << subgroups::getFormatNameForGLSL(caseDef.format) <<" valueEqual = " << subgroups::getFormatNameForGLSL(caseDef.format) << "(1.25 * float(data[gl_SubgroupInvocationID]) + 5.0);\n" 381e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) <<" valueNoEqual = " << subgroups::getFormatNameForGLSL(caseDef.format) << (formatIsBoolean ? "(subgroupElect());\n" : "(12.0 * float(data[gl_SubgroupInvocationID]) + float(offset));\n") 382e5c31af7Sopenharmony_ci <<" result[offset] = " << getOpTypeName(caseDef.opType) << "(" 383e5c31af7Sopenharmony_ci << subgroups::getFormatNameForGLSL(caseDef.format) << "(1)) ? 0x1u : 0x0u;\n" 384e5c31af7Sopenharmony_ci << " result[offset] |= " << getOpTypeName(caseDef.opType) 385e5c31af7Sopenharmony_ci << "(gl_SubgroupInvocationID) ? 0x0u : 0x2u;\n" 386e5c31af7Sopenharmony_ci << " result[offset] |= " << getOpTypeName(caseDef.opType) 387e5c31af7Sopenharmony_ci << "(data[0]) ? 0x4u : 0x0u;\n" 388e5c31af7Sopenharmony_ci << " result[offset] |= "<< getOpTypeName(caseDef.opType) 389e5c31af7Sopenharmony_ci << "(valueEqual) ? 0x8u : 0x0u;\n" 390e5c31af7Sopenharmony_ci << " result[offset] |= "<< getOpTypeName(caseDef.opType) 391e5c31af7Sopenharmony_ci << "(valueNoEqual) ? 0x0u : 0x10u;\n" 392e5c31af7Sopenharmony_ci << " if (subgroupElect()) result[offset] |= 0x2u | 0x10u;\n"; 393e5c31af7Sopenharmony_ci } 394e5c31af7Sopenharmony_ci 395e5c31af7Sopenharmony_ci src << "}\n"; 396e5c31af7Sopenharmony_ci 397e5c31af7Sopenharmony_ci programCollection.add("comp") << glu::ComputeSource(src.str()); 398e5c31af7Sopenharmony_ci } 399e5c31af7Sopenharmony_ci else 400e5c31af7Sopenharmony_ci { 401e5c31af7Sopenharmony_ci const string source = 402e5c31af7Sopenharmony_ci (OPTYPE_ALL == caseDef.opType) ? 403e5c31af7Sopenharmony_ci " b${SSBO1}.result[offset] = " + getOpTypeName(caseDef.opType) + 404e5c31af7Sopenharmony_ci "(true) ? 0x1u : 0u;\n" 405e5c31af7Sopenharmony_ci " b${SSBO1}.result[offset] |= " + getOpTypeName(caseDef.opType) + 406e5c31af7Sopenharmony_ci "(false) ? 0u : 0x1Au;\n" 407e5c31af7Sopenharmony_ci " b${SSBO1}.result[offset] |= 0x4u;\n" 408e5c31af7Sopenharmony_ci : (OPTYPE_ANY == caseDef.opType) ? 409e5c31af7Sopenharmony_ci " b${SSBO1}.result[offset] = " + getOpTypeName(caseDef.opType) + 410e5c31af7Sopenharmony_ci "(true) ? 0x1u : 0u;\n" 411e5c31af7Sopenharmony_ci " b${SSBO1}.result[offset] |= " + getOpTypeName(caseDef.opType) + 412e5c31af7Sopenharmony_ci "(false) ? 0u : 0x1Au;\n" 413e5c31af7Sopenharmony_ci " b${SSBO1}.result[offset] |= 0x4u;\n" 414e5c31af7Sopenharmony_ci : (OPTYPE_ALLEQUAL == caseDef.opType) ? 415e5c31af7Sopenharmony_ci " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + "(1.25 * float(data[gl_SubgroupInvocationID]) + 5.0);\n" + 416e5c31af7Sopenharmony_ci " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueNoEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + (formatIsBoolean ? "(subgroupElect());\n" : "(12.0 * float(data[gl_SubgroupInvocationID]) + float(gl_SubgroupInvocationID));\n") + 417e5c31af7Sopenharmony_ci " b${SSBO1}.result[offset] = " + getOpTypeName(caseDef.opType) + "(" 418e5c31af7Sopenharmony_ci + subgroups::getFormatNameForGLSL(caseDef.format) + "(1)) ? 0x1u : 0u;\n" 419e5c31af7Sopenharmony_ci " b${SSBO1}.result[offset] |= " + getOpTypeName(caseDef.opType) + 420e5c31af7Sopenharmony_ci "(gl_SubgroupInvocationID) ? 0u : 0x2u;\n" 421e5c31af7Sopenharmony_ci " b${SSBO1}.result[offset] |= " + getOpTypeName(caseDef.opType) + 422e5c31af7Sopenharmony_ci "(data[0]) ? 0x4u : 0u;\n" 423e5c31af7Sopenharmony_ci " b${SSBO1}.result[offset] |= " + getOpTypeName(caseDef.opType) + 424e5c31af7Sopenharmony_ci "(valueEqual) ? 0x8u : 0x0u;\n" 425e5c31af7Sopenharmony_ci " b${SSBO1}.result[offset] |= " + getOpTypeName(caseDef.opType) + 426e5c31af7Sopenharmony_ci "(valueNoEqual) ? 0x0u : 0x10u;\n" 427e5c31af7Sopenharmony_ci " if (subgroupElect()) b${SSBO1}.result[offset] |= 0x2u | 0x10u;\n" 428e5c31af7Sopenharmony_ci : ""; 429e5c31af7Sopenharmony_ci 430e5c31af7Sopenharmony_ci tcu::StringTemplate sourceTemplate(source); 431e5c31af7Sopenharmony_ci 432e5c31af7Sopenharmony_ci const string formatString = subgroups::getFormatNameForGLSL(caseDef.format); 433e5c31af7Sopenharmony_ci 434e5c31af7Sopenharmony_ci { 435e5c31af7Sopenharmony_ci map<string, string> bufferNameMapping; 436e5c31af7Sopenharmony_ci bufferNameMapping.insert(pair<string, string>("SSBO1", "0")); 437e5c31af7Sopenharmony_ci 438e5c31af7Sopenharmony_ci const string vertex = 439e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 440e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_vote: enable\n" 441e5c31af7Sopenharmony_ci "layout(binding = 0, std430) buffer Buffer0\n" 442e5c31af7Sopenharmony_ci "{\n" 443e5c31af7Sopenharmony_ci " uint result[];\n" 444e5c31af7Sopenharmony_ci "} b0;\n" 445e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 446e5c31af7Sopenharmony_ci "{\n" 447e5c31af7Sopenharmony_ci " " + formatString + " data[];\n" 448e5c31af7Sopenharmony_ci "};\n" 449e5c31af7Sopenharmony_ci "\n" 450e5c31af7Sopenharmony_ci "void main (void)\n" 451e5c31af7Sopenharmony_ci "{\n" 452e5c31af7Sopenharmony_ci " highp int offset = gl_VertexID;\n" 453e5c31af7Sopenharmony_ci + sourceTemplate.specialize(bufferNameMapping) + 454e5c31af7Sopenharmony_ci " float pixelSize = 2.0f/1024.0f;\n" 455e5c31af7Sopenharmony_ci " float pixelPosition = pixelSize/2.0f - 1.0f;\n" 456e5c31af7Sopenharmony_ci " gl_Position = vec4(float(gl_VertexID) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n" 457e5c31af7Sopenharmony_ci " gl_PointSize = 1.0f;\n" 458e5c31af7Sopenharmony_ci "}\n"; 459e5c31af7Sopenharmony_ci programCollection.add("vert") << glu::VertexSource(vertex); 460e5c31af7Sopenharmony_ci } 461e5c31af7Sopenharmony_ci 462e5c31af7Sopenharmony_ci { 463e5c31af7Sopenharmony_ci map<string, string> bufferNameMapping; 464e5c31af7Sopenharmony_ci bufferNameMapping.insert(pair<string, string>("SSBO1", "1")); 465e5c31af7Sopenharmony_ci 466e5c31af7Sopenharmony_ci const string tesc = 467e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 468e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_vote: enable\n" 469e5c31af7Sopenharmony_ci "layout(vertices=1) out;\n" 470e5c31af7Sopenharmony_ci "layout(binding = 1, std430) buffer Buffer1\n" 471e5c31af7Sopenharmony_ci "{\n" 472e5c31af7Sopenharmony_ci " uint result[];\n" 473e5c31af7Sopenharmony_ci "} b1;\n" 474e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 475e5c31af7Sopenharmony_ci "{\n" 476e5c31af7Sopenharmony_ci " " + formatString + " data[];\n" 477e5c31af7Sopenharmony_ci "};\n" 478e5c31af7Sopenharmony_ci "\n" 479e5c31af7Sopenharmony_ci "void main (void)\n" 480e5c31af7Sopenharmony_ci "{\n" 481e5c31af7Sopenharmony_ci " highp int offset = gl_PrimitiveID;\n" 482e5c31af7Sopenharmony_ci + sourceTemplate.specialize(bufferNameMapping) + 483e5c31af7Sopenharmony_ci " if (gl_InvocationID == 0)\n" 484e5c31af7Sopenharmony_ci " {\n" 485e5c31af7Sopenharmony_ci " gl_TessLevelOuter[0] = 1.0f;\n" 486e5c31af7Sopenharmony_ci " gl_TessLevelOuter[1] = 1.0f;\n" 487e5c31af7Sopenharmony_ci " }\n" 488e5c31af7Sopenharmony_ci " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 489e5c31af7Sopenharmony_ci "}\n"; 490e5c31af7Sopenharmony_ci 491e5c31af7Sopenharmony_ci programCollection.add("tesc") << glu::TessellationControlSource(tesc); 492e5c31af7Sopenharmony_ci } 493e5c31af7Sopenharmony_ci 494e5c31af7Sopenharmony_ci { 495e5c31af7Sopenharmony_ci map<string, string> bufferNameMapping; 496e5c31af7Sopenharmony_ci bufferNameMapping.insert(pair<string, string>("SSBO1", "2")); 497e5c31af7Sopenharmony_ci 498e5c31af7Sopenharmony_ci const string tese = 499e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 500e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_vote: enable\n" 501e5c31af7Sopenharmony_ci "layout(isolines) in;\n" 502e5c31af7Sopenharmony_ci "layout(binding = 2, std430) buffer Buffer2\n" 503e5c31af7Sopenharmony_ci "{\n" 504e5c31af7Sopenharmony_ci " uint result[];\n" 505e5c31af7Sopenharmony_ci "} b2;\n" 506e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 507e5c31af7Sopenharmony_ci "{\n" 508e5c31af7Sopenharmony_ci " " + formatString + " data[];\n" 509e5c31af7Sopenharmony_ci "};\n" 510e5c31af7Sopenharmony_ci "\n" 511e5c31af7Sopenharmony_ci "void main (void)\n" 512e5c31af7Sopenharmony_ci "{\n" 513e5c31af7Sopenharmony_ci " highp uint offset = uint(gl_PrimitiveID * 2) + uint(gl_TessCoord.x + 0.5);\n" 514e5c31af7Sopenharmony_ci + sourceTemplate.specialize(bufferNameMapping) + 515e5c31af7Sopenharmony_ci " float pixelSize = 2.0f/1024.0f;\n" 516e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n" 517e5c31af7Sopenharmony_ci "}\n"; 518e5c31af7Sopenharmony_ci 519e5c31af7Sopenharmony_ci programCollection.add("tese") << glu::TessellationEvaluationSource(tese); 520e5c31af7Sopenharmony_ci } 521e5c31af7Sopenharmony_ci 522e5c31af7Sopenharmony_ci { 523e5c31af7Sopenharmony_ci map<string, string> bufferNameMapping; 524e5c31af7Sopenharmony_ci bufferNameMapping.insert(pair<string, string>("SSBO1", "3")); 525e5c31af7Sopenharmony_ci 526e5c31af7Sopenharmony_ci const string geometry = 527e5c31af7Sopenharmony_ci // version string added by addGeometryShadersFromTemplate 528e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_vote: enable\n" 529e5c31af7Sopenharmony_ci "layout(${TOPOLOGY}) in;\n" 530e5c31af7Sopenharmony_ci "layout(points, max_vertices = 1) out;\n" 531e5c31af7Sopenharmony_ci "layout(binding = 3, std430) buffer Buffer3\n" 532e5c31af7Sopenharmony_ci "{\n" 533e5c31af7Sopenharmony_ci " uint result[];\n" 534e5c31af7Sopenharmony_ci "} b3;\n" 535e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 536e5c31af7Sopenharmony_ci "{\n" 537e5c31af7Sopenharmony_ci " " + formatString + " data[];\n" 538e5c31af7Sopenharmony_ci "};\n" 539e5c31af7Sopenharmony_ci "\n" 540e5c31af7Sopenharmony_ci "void main (void)\n" 541e5c31af7Sopenharmony_ci "{\n" 542e5c31af7Sopenharmony_ci " highp int offset = gl_PrimitiveIDIn;\n" 543e5c31af7Sopenharmony_ci + sourceTemplate.specialize(bufferNameMapping) + 544e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 545e5c31af7Sopenharmony_ci " EmitVertex();\n" 546e5c31af7Sopenharmony_ci " EndPrimitive();\n" 547e5c31af7Sopenharmony_ci "}\n"; 548e5c31af7Sopenharmony_ci 549e5c31af7Sopenharmony_ci subgroups::addGeometryShadersFromTemplate(geometry, programCollection); 550e5c31af7Sopenharmony_ci } 551e5c31af7Sopenharmony_ci 552e5c31af7Sopenharmony_ci { 553e5c31af7Sopenharmony_ci const string sourceFragment = 554e5c31af7Sopenharmony_ci (OPTYPE_ALL == caseDef.opType) ? 555e5c31af7Sopenharmony_ci " result = " + getOpTypeName(caseDef.opType) + 556e5c31af7Sopenharmony_ci "(true) ? 0x1u : 0u;\n" 557e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 558e5c31af7Sopenharmony_ci "(false) ? 0u : 0x1Au;\n" 559e5c31af7Sopenharmony_ci " result |= 0x4u;\n" 560e5c31af7Sopenharmony_ci : (OPTYPE_ANY == caseDef.opType) ? 561e5c31af7Sopenharmony_ci " result = " + getOpTypeName(caseDef.opType) + 562e5c31af7Sopenharmony_ci "(true) ? 0x1u : 0u;\n" 563e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 564e5c31af7Sopenharmony_ci "(false) ? 0u : 0x1Au;\n" 565e5c31af7Sopenharmony_ci " result |= 0x4u;\n" 566e5c31af7Sopenharmony_ci : (OPTYPE_ALLEQUAL == caseDef.opType) ? 567e5c31af7Sopenharmony_ci " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + "(1.25 * float(data[gl_SubgroupInvocationID]) + 5.0);\n" + 568e5c31af7Sopenharmony_ci " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueNoEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + (formatIsBoolean ? "(subgroupElect());\n" : "(12.0 * float(data[gl_SubgroupInvocationID]) + gl_FragCoord.x * float(gl_SubgroupInvocationID));\n") + 569e5c31af7Sopenharmony_ci " result = " + getOpTypeName(caseDef.opType) + "(" 570e5c31af7Sopenharmony_ci + subgroups::getFormatNameForGLSL(caseDef.format) + "(1)) ? 0x1u : 0u;\n" 571e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 572e5c31af7Sopenharmony_ci "(gl_SubgroupInvocationID) ? 0u : 0x2u;\n" 573e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 574e5c31af7Sopenharmony_ci "(data[0]) ? 0x4u : 0u;\n" 575e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 576e5c31af7Sopenharmony_ci "(valueEqual) ? 0x8u : 0x0u;\n" 577e5c31af7Sopenharmony_ci " result |= " + getOpTypeName(caseDef.opType) + 578e5c31af7Sopenharmony_ci "(valueNoEqual) ? 0x0u : 0x10u;\n" 579e5c31af7Sopenharmony_ci " if (subgroupElect()) result |= 0x2u | 0x10u;\n" 580e5c31af7Sopenharmony_ci : ""; 581e5c31af7Sopenharmony_ci const string fragment = 582e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 583e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_vote: enable\n" 584e5c31af7Sopenharmony_ci "precision highp float;\n" 585e5c31af7Sopenharmony_ci "layout(location = 0) out uint result;\n" 586e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 587e5c31af7Sopenharmony_ci "{\n" 588e5c31af7Sopenharmony_ci " " + formatString + " data[];\n" 589e5c31af7Sopenharmony_ci "};\n" 590e5c31af7Sopenharmony_ci "void main (void)\n" 591e5c31af7Sopenharmony_ci "{\n" 592e5c31af7Sopenharmony_ci + sourceFragment + 593e5c31af7Sopenharmony_ci "}\n"; 594e5c31af7Sopenharmony_ci 595e5c31af7Sopenharmony_ci programCollection.add("fragment") << glu::FragmentSource(fragment); 596e5c31af7Sopenharmony_ci } 597e5c31af7Sopenharmony_ci 598e5c31af7Sopenharmony_ci subgroups::addNoSubgroupShader(programCollection); 599e5c31af7Sopenharmony_ci } 600e5c31af7Sopenharmony_ci} 601e5c31af7Sopenharmony_ci 602e5c31af7Sopenharmony_civoid supportedCheck (Context& context, CaseDefinition caseDef) 603e5c31af7Sopenharmony_ci{ 604e5c31af7Sopenharmony_ci if (!subgroups::isSubgroupSupported(context)) 605e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Subgroup operations are not supported"); 606e5c31af7Sopenharmony_ci 607e5c31af7Sopenharmony_ci if (!subgroups::isSubgroupFeatureSupportedForDevice(context, subgroups::SUBGROUP_FEATURE_VOTE_BIT)) 608e5c31af7Sopenharmony_ci { 609e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support subgroup vote operations"); 610e5c31af7Sopenharmony_ci } 611e5c31af7Sopenharmony_ci 612e5c31af7Sopenharmony_ci if (subgroups::isDoubleFormat(caseDef.format) && 613e5c31af7Sopenharmony_ci !subgroups::isDoubleSupportedForDevice(context)) 614e5c31af7Sopenharmony_ci { 615e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support subgroup double operations"); 616e5c31af7Sopenharmony_ci } 617e5c31af7Sopenharmony_ci} 618e5c31af7Sopenharmony_ci 619e5c31af7Sopenharmony_citcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef) 620e5c31af7Sopenharmony_ci{ 621e5c31af7Sopenharmony_ci if (!subgroups::areSubgroupOperationsSupportedForStage( 622e5c31af7Sopenharmony_ci context, caseDef.shaderStage)) 623e5c31af7Sopenharmony_ci { 624e5c31af7Sopenharmony_ci if (subgroups::areSubgroupOperationsRequiredForStage( 625e5c31af7Sopenharmony_ci caseDef.shaderStage)) 626e5c31af7Sopenharmony_ci { 627e5c31af7Sopenharmony_ci return tcu::TestStatus::fail( 628e5c31af7Sopenharmony_ci "Shader stage " + 629e5c31af7Sopenharmony_ci subgroups::getShaderStageName(caseDef.shaderStage) + 630e5c31af7Sopenharmony_ci " is required to support subgroup operations!"); 631e5c31af7Sopenharmony_ci } 632e5c31af7Sopenharmony_ci else 633e5c31af7Sopenharmony_ci { 634e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage"); 635e5c31af7Sopenharmony_ci } 636e5c31af7Sopenharmony_ci } 637e5c31af7Sopenharmony_ci 638e5c31af7Sopenharmony_ci subgroups::SSBOData inputData; 639e5c31af7Sopenharmony_ci inputData.format = caseDef.format; 640e5c31af7Sopenharmony_ci inputData.layout = subgroups::SSBOData::LayoutStd140; 641e5c31af7Sopenharmony_ci inputData.numElements = subgroups::maxSupportedSubgroupSize(); 642e5c31af7Sopenharmony_ci inputData.initializeType = OPTYPE_ALLEQUAL == caseDef.opType ? subgroups::SSBOData::InitializeZero : subgroups::SSBOData::InitializeNonZero; 643e5c31af7Sopenharmony_ci 644e5c31af7Sopenharmony_ci if (SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage) 645e5c31af7Sopenharmony_ci return subgroups::makeVertexFrameBufferTest(context, FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages); 646e5c31af7Sopenharmony_ci else if (SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage) 647e5c31af7Sopenharmony_ci return subgroups::makeGeometryFrameBufferTest(context, FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages); 648e5c31af7Sopenharmony_ci else if (SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage) 649e5c31af7Sopenharmony_ci return subgroups::makeTessellationEvaluationFrameBufferTest(context, FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, SHADER_STAGE_TESS_CONTROL_BIT); 650e5c31af7Sopenharmony_ci else if (SHADER_STAGE_TESS_EVALUATION_BIT == caseDef.shaderStage) 651e5c31af7Sopenharmony_ci return subgroups::makeTessellationEvaluationFrameBufferTest(context, FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, SHADER_STAGE_TESS_EVALUATION_BIT); 652e5c31af7Sopenharmony_ci else if (SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage) 653e5c31af7Sopenharmony_ci return subgroups::makeFragmentFrameBufferTest(context, FORMAT_R32_UINT, &inputData, 1, checkFragmentPipelineStages); 654e5c31af7Sopenharmony_ci else 655e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Unhandled shader stage"); 656e5c31af7Sopenharmony_ci} 657e5c31af7Sopenharmony_ci 658e5c31af7Sopenharmony_ci 659e5c31af7Sopenharmony_citcu::TestStatus test(Context& context, const CaseDefinition caseDef) 660e5c31af7Sopenharmony_ci{ 661e5c31af7Sopenharmony_ci if (SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage) 662e5c31af7Sopenharmony_ci { 663e5c31af7Sopenharmony_ci if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage)) 664e5c31af7Sopenharmony_ci { 665e5c31af7Sopenharmony_ci return tcu::TestStatus::fail( 666e5c31af7Sopenharmony_ci "Shader stage " + 667e5c31af7Sopenharmony_ci subgroups::getShaderStageName(caseDef.shaderStage) + 668e5c31af7Sopenharmony_ci " is required to support subgroup operations!"); 669e5c31af7Sopenharmony_ci } 670e5c31af7Sopenharmony_ci 671e5c31af7Sopenharmony_ci subgroups::SSBOData inputData; 672e5c31af7Sopenharmony_ci inputData.format = caseDef.format; 673e5c31af7Sopenharmony_ci inputData.layout = subgroups::SSBOData::LayoutStd430; 674e5c31af7Sopenharmony_ci inputData.numElements = subgroups::maxSupportedSubgroupSize(); 675e5c31af7Sopenharmony_ci inputData.initializeType = OPTYPE_ALLEQUAL == caseDef.opType ? subgroups::SSBOData::InitializeZero : subgroups::SSBOData::InitializeNonZero; 676e5c31af7Sopenharmony_ci inputData.binding = 1u; 677e5c31af7Sopenharmony_ci 678e5c31af7Sopenharmony_ci return subgroups::makeComputeTest(context, FORMAT_R32_UINT, &inputData, 679e5c31af7Sopenharmony_ci 1, checkComputeStage); 680e5c31af7Sopenharmony_ci } 681e5c31af7Sopenharmony_ci else 682e5c31af7Sopenharmony_ci { 683e5c31af7Sopenharmony_ci int supportedStages = context.getDeqpContext().getContextInfo().getInt(GL_SUBGROUP_SUPPORTED_STAGES_KHR); 684e5c31af7Sopenharmony_ci 685e5c31af7Sopenharmony_ci ShaderStageFlags stages = (ShaderStageFlags)(caseDef.shaderStage & supportedStages); 686e5c31af7Sopenharmony_ci 687e5c31af7Sopenharmony_ci if (SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context)) 688e5c31af7Sopenharmony_ci { 689e5c31af7Sopenharmony_ci if ( (stages & SHADER_STAGE_FRAGMENT_BIT) == 0) 690e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes"); 691e5c31af7Sopenharmony_ci else 692e5c31af7Sopenharmony_ci stages = SHADER_STAGE_FRAGMENT_BIT; 693e5c31af7Sopenharmony_ci } 694e5c31af7Sopenharmony_ci 695e5c31af7Sopenharmony_ci if ((ShaderStageFlags)0u == stages) 696e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Subgroup operations are not supported for any graphic shader"); 697e5c31af7Sopenharmony_ci 698e5c31af7Sopenharmony_ci subgroups::SSBOData inputData; 699e5c31af7Sopenharmony_ci inputData.format = caseDef.format; 700e5c31af7Sopenharmony_ci inputData.layout = subgroups::SSBOData::LayoutStd430; 701e5c31af7Sopenharmony_ci inputData.numElements = subgroups::maxSupportedSubgroupSize(); 702e5c31af7Sopenharmony_ci inputData.initializeType = OPTYPE_ALLEQUAL == caseDef.opType ? subgroups::SSBOData::InitializeZero : subgroups::SSBOData::InitializeNonZero; 703e5c31af7Sopenharmony_ci inputData.binding = 4u; 704e5c31af7Sopenharmony_ci inputData.stages = stages; 705e5c31af7Sopenharmony_ci 706e5c31af7Sopenharmony_ci return subgroups::allStages(context, FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, stages); 707e5c31af7Sopenharmony_ci } 708e5c31af7Sopenharmony_ci} 709e5c31af7Sopenharmony_ci 710e5c31af7Sopenharmony_ci} // namespace 711e5c31af7Sopenharmony_ci 712e5c31af7Sopenharmony_cideqp::TestCaseGroup* createSubgroupsVoteTests(deqp::Context& testCtx) 713e5c31af7Sopenharmony_ci{ 714e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> graphicGroup(new deqp::TestCaseGroup( 715e5c31af7Sopenharmony_ci testCtx, "graphics", "Subgroup arithmetic category tests: graphics")); 716e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> computeGroup(new deqp::TestCaseGroup( 717e5c31af7Sopenharmony_ci testCtx, "compute", "Subgroup arithmetic category tests: compute")); 718e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> framebufferGroup(new deqp::TestCaseGroup( 719e5c31af7Sopenharmony_ci testCtx, "framebuffer", "Subgroup arithmetic category tests: framebuffer")); 720e5c31af7Sopenharmony_ci 721e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> fragHelperGroup(new deqp::TestCaseGroup( 722e5c31af7Sopenharmony_ci testCtx, "frag_helper", "Subgroup arithmetic category tests: fragment helper invocation")); 723e5c31af7Sopenharmony_ci 724e5c31af7Sopenharmony_ci const ShaderStageFlags stages[] = 725e5c31af7Sopenharmony_ci { 726e5c31af7Sopenharmony_ci SHADER_STAGE_VERTEX_BIT, 727e5c31af7Sopenharmony_ci SHADER_STAGE_TESS_EVALUATION_BIT, 728e5c31af7Sopenharmony_ci SHADER_STAGE_TESS_CONTROL_BIT, 729e5c31af7Sopenharmony_ci SHADER_STAGE_GEOMETRY_BIT, 730e5c31af7Sopenharmony_ci }; 731e5c31af7Sopenharmony_ci 732e5c31af7Sopenharmony_ci const Format formats[] = 733e5c31af7Sopenharmony_ci { 734e5c31af7Sopenharmony_ci FORMAT_R32_SINT, FORMAT_R32G32_SINT, FORMAT_R32G32B32_SINT, 735e5c31af7Sopenharmony_ci FORMAT_R32G32B32A32_SINT, FORMAT_R32_UINT, FORMAT_R32G32_UINT, 736e5c31af7Sopenharmony_ci FORMAT_R32G32B32_UINT, FORMAT_R32G32B32A32_UINT, 737e5c31af7Sopenharmony_ci FORMAT_R32_SFLOAT, FORMAT_R32G32_SFLOAT, 738e5c31af7Sopenharmony_ci FORMAT_R32G32B32_SFLOAT, FORMAT_R32G32B32A32_SFLOAT, 739e5c31af7Sopenharmony_ci FORMAT_R64_SFLOAT, FORMAT_R64G64_SFLOAT, 740e5c31af7Sopenharmony_ci FORMAT_R64G64B64_SFLOAT, FORMAT_R64G64B64A64_SFLOAT, 741e5c31af7Sopenharmony_ci FORMAT_R32_BOOL, FORMAT_R32G32_BOOL, 742e5c31af7Sopenharmony_ci FORMAT_R32G32B32_BOOL, FORMAT_R32G32B32A32_BOOL, 743e5c31af7Sopenharmony_ci }; 744e5c31af7Sopenharmony_ci 745e5c31af7Sopenharmony_ci for (int formatIndex = 0; formatIndex < DE_LENGTH_OF_ARRAY(formats); ++formatIndex) 746e5c31af7Sopenharmony_ci { 747e5c31af7Sopenharmony_ci const Format format = formats[formatIndex]; 748e5c31af7Sopenharmony_ci 749e5c31af7Sopenharmony_ci for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex) 750e5c31af7Sopenharmony_ci { 751e5c31af7Sopenharmony_ci // Skip the typed tests for all but subgroupAllEqual() 752e5c31af7Sopenharmony_ci if ((FORMAT_R32_UINT != format) && (OPTYPE_ALLEQUAL != opTypeIndex)) 753e5c31af7Sopenharmony_ci { 754e5c31af7Sopenharmony_ci continue; 755e5c31af7Sopenharmony_ci } 756e5c31af7Sopenharmony_ci 757e5c31af7Sopenharmony_ci const std::string op = de::toLower(getOpTypeName(opTypeIndex)); 758e5c31af7Sopenharmony_ci 759e5c31af7Sopenharmony_ci { 760e5c31af7Sopenharmony_ci const CaseDefinition caseDef = {opTypeIndex, SHADER_STAGE_COMPUTE_BIT, format}; 761e5c31af7Sopenharmony_ci SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(computeGroup.get(), 762e5c31af7Sopenharmony_ci op + "_" + subgroups::getFormatNameForGLSL(format), 763e5c31af7Sopenharmony_ci "", supportedCheck, initPrograms, test, caseDef); 764e5c31af7Sopenharmony_ci } 765e5c31af7Sopenharmony_ci 766e5c31af7Sopenharmony_ci { 767e5c31af7Sopenharmony_ci const CaseDefinition caseDef = {opTypeIndex, SHADER_STAGE_ALL_GRAPHICS, format}; 768e5c31af7Sopenharmony_ci SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(graphicGroup.get(), 769e5c31af7Sopenharmony_ci op + "_" + subgroups::getFormatNameForGLSL(format), 770e5c31af7Sopenharmony_ci "", supportedCheck, initPrograms, test, caseDef); 771e5c31af7Sopenharmony_ci } 772e5c31af7Sopenharmony_ci 773e5c31af7Sopenharmony_ci for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex) 774e5c31af7Sopenharmony_ci { 775e5c31af7Sopenharmony_ci const CaseDefinition caseDef = {opTypeIndex, stages[stageIndex], format}; 776e5c31af7Sopenharmony_ci SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(framebufferGroup.get(), 777e5c31af7Sopenharmony_ci op + "_" + 778e5c31af7Sopenharmony_ci subgroups::getFormatNameForGLSL(format) 779e5c31af7Sopenharmony_ci + "_" + getShaderStageName(caseDef.shaderStage), "", 780e5c31af7Sopenharmony_ci supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef); 781e5c31af7Sopenharmony_ci } 782e5c31af7Sopenharmony_ci 783e5c31af7Sopenharmony_ci const CaseDefinition caseDef = {opTypeIndex, SHADER_STAGE_FRAGMENT_BIT, format}; 784e5c31af7Sopenharmony_ci SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(fragHelperGroup.get(), 785e5c31af7Sopenharmony_ci op + "_" + 786e5c31af7Sopenharmony_ci subgroups::getFormatNameForGLSL(format) 787e5c31af7Sopenharmony_ci + "_" + getShaderStageName(caseDef.shaderStage), "", 788e5c31af7Sopenharmony_ci supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef); 789e5c31af7Sopenharmony_ci } 790e5c31af7Sopenharmony_ci } 791e5c31af7Sopenharmony_ci 792e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> group(new deqp::TestCaseGroup( 793e5c31af7Sopenharmony_ci testCtx, "vote", "Subgroup vote category tests")); 794e5c31af7Sopenharmony_ci 795e5c31af7Sopenharmony_ci group->addChild(graphicGroup.release()); 796e5c31af7Sopenharmony_ci group->addChild(computeGroup.release()); 797e5c31af7Sopenharmony_ci group->addChild(framebufferGroup.release()); 798e5c31af7Sopenharmony_ci group->addChild(fragHelperGroup.release()); 799e5c31af7Sopenharmony_ci 800e5c31af7Sopenharmony_ci return group.release(); 801e5c31af7Sopenharmony_ci} 802e5c31af7Sopenharmony_ci 803e5c31af7Sopenharmony_ci} // subgroups 804e5c31af7Sopenharmony_ci} // glc 805