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 "glcSubgroupsBallotOtherTests.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_cienum OpType 42e5c31af7Sopenharmony_ci{ 43e5c31af7Sopenharmony_ci OPTYPE_INVERSE_BALLOT = 0, 44e5c31af7Sopenharmony_ci OPTYPE_BALLOT_BIT_EXTRACT, 45e5c31af7Sopenharmony_ci OPTYPE_BALLOT_BIT_COUNT, 46e5c31af7Sopenharmony_ci OPTYPE_BALLOT_INCLUSIVE_BIT_COUNT, 47e5c31af7Sopenharmony_ci OPTYPE_BALLOT_EXCLUSIVE_BIT_COUNT, 48e5c31af7Sopenharmony_ci OPTYPE_BALLOT_FIND_LSB, 49e5c31af7Sopenharmony_ci OPTYPE_BALLOT_FIND_MSB, 50e5c31af7Sopenharmony_ci OPTYPE_LAST 51e5c31af7Sopenharmony_ci}; 52e5c31af7Sopenharmony_ci 53e5c31af7Sopenharmony_cistatic bool checkVertexPipelineStages(std::vector<const void*> datas, 54e5c31af7Sopenharmony_ci deUint32 width, deUint32) 55e5c31af7Sopenharmony_ci{ 56e5c31af7Sopenharmony_ci return glc::subgroups::check(datas, width, 0xf); 57e5c31af7Sopenharmony_ci} 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_cistatic bool checkComputeStage(std::vector<const void*> datas, 60e5c31af7Sopenharmony_ci const deUint32 numWorkgroups[3], const deUint32 localSize[3], 61e5c31af7Sopenharmony_ci deUint32) 62e5c31af7Sopenharmony_ci{ 63e5c31af7Sopenharmony_ci return glc::subgroups::checkCompute(datas, numWorkgroups, localSize, 0xf); 64e5c31af7Sopenharmony_ci} 65e5c31af7Sopenharmony_ci 66e5c31af7Sopenharmony_cistd::string getOpTypeName(int opType) 67e5c31af7Sopenharmony_ci{ 68e5c31af7Sopenharmony_ci switch (opType) 69e5c31af7Sopenharmony_ci { 70e5c31af7Sopenharmony_ci default: 71e5c31af7Sopenharmony_ci DE_FATAL("Unsupported op type"); 72e5c31af7Sopenharmony_ci return ""; 73e5c31af7Sopenharmony_ci case OPTYPE_INVERSE_BALLOT: 74e5c31af7Sopenharmony_ci return "subgroupInverseBallot"; 75e5c31af7Sopenharmony_ci case OPTYPE_BALLOT_BIT_EXTRACT: 76e5c31af7Sopenharmony_ci return "subgroupBallotBitExtract"; 77e5c31af7Sopenharmony_ci case OPTYPE_BALLOT_BIT_COUNT: 78e5c31af7Sopenharmony_ci return "subgroupBallotBitCount"; 79e5c31af7Sopenharmony_ci case OPTYPE_BALLOT_INCLUSIVE_BIT_COUNT: 80e5c31af7Sopenharmony_ci return "subgroupBallotInclusiveBitCount"; 81e5c31af7Sopenharmony_ci case OPTYPE_BALLOT_EXCLUSIVE_BIT_COUNT: 82e5c31af7Sopenharmony_ci return "subgroupBallotExclusiveBitCount"; 83e5c31af7Sopenharmony_ci case OPTYPE_BALLOT_FIND_LSB: 84e5c31af7Sopenharmony_ci return "subgroupBallotFindLSB"; 85e5c31af7Sopenharmony_ci case OPTYPE_BALLOT_FIND_MSB: 86e5c31af7Sopenharmony_ci return "subgroupBallotFindMSB"; 87e5c31af7Sopenharmony_ci } 88e5c31af7Sopenharmony_ci} 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_cistruct CaseDefinition 91e5c31af7Sopenharmony_ci{ 92e5c31af7Sopenharmony_ci int opType; 93e5c31af7Sopenharmony_ci ShaderStageFlags shaderStage; 94e5c31af7Sopenharmony_ci}; 95e5c31af7Sopenharmony_ci 96e5c31af7Sopenharmony_cistd::string getBodySource(CaseDefinition caseDef) 97e5c31af7Sopenharmony_ci{ 98e5c31af7Sopenharmony_ci std::ostringstream bdy; 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_ci bdy << " uvec4 allOnes = uvec4(0xFFFFFFFF);\n" 101e5c31af7Sopenharmony_ci << " uvec4 allZeros = uvec4(0);\n" 102e5c31af7Sopenharmony_ci << " uint tempResult = 0u;\n" 103e5c31af7Sopenharmony_ci << "#define MAKE_HIGH_BALLOT_RESULT(i) uvec4(" 104e5c31af7Sopenharmony_ci << "i >= 32u ? 0u : (0xFFFFFFFFu << i), " 105e5c31af7Sopenharmony_ci << "i >= 64u ? 0u : (0xFFFFFFFFu << ((i < 32u) ? 0u : (i - 32u))), " 106e5c31af7Sopenharmony_ci << "i >= 96u ? 0u : (0xFFFFFFFFu << ((i < 64u) ? 0u : (i - 64u))), " 107e5c31af7Sopenharmony_ci << "i == 128u ? 0u : (0xFFFFFFFFu << ((i < 96u) ? 0u : (i - 96u))))\n" 108e5c31af7Sopenharmony_ci << "#define MAKE_SINGLE_BIT_BALLOT_RESULT(i) uvec4(" 109e5c31af7Sopenharmony_ci << "i >= 32u ? 0u : 0x1u << i, " 110e5c31af7Sopenharmony_ci << "i < 32u || i >= 64u ? 0u : 0x1u << (i - 32u), " 111e5c31af7Sopenharmony_ci << "i < 64u || i >= 96u ? 0u : 0x1u << (i - 64u), " 112e5c31af7Sopenharmony_ci << "i < 96u ? 0u : 0x1u << (i - 96u))\n"; 113e5c31af7Sopenharmony_ci 114e5c31af7Sopenharmony_ci switch (caseDef.opType) 115e5c31af7Sopenharmony_ci { 116e5c31af7Sopenharmony_ci default: 117e5c31af7Sopenharmony_ci DE_FATAL("Unknown op type!"); 118e5c31af7Sopenharmony_ci break; 119e5c31af7Sopenharmony_ci case OPTYPE_INVERSE_BALLOT: 120e5c31af7Sopenharmony_ci bdy << " tempResult |= subgroupInverseBallot(allOnes) ? 0x1u : 0u;\n" 121e5c31af7Sopenharmony_ci << " tempResult |= subgroupInverseBallot(allZeros) ? 0u : 0x2u;\n" 122e5c31af7Sopenharmony_ci << " tempResult |= subgroupInverseBallot(subgroupBallot(true)) ? 0x4u : 0u;\n" 123e5c31af7Sopenharmony_ci << " tempResult |= 0x8u;\n"; 124e5c31af7Sopenharmony_ci break; 125e5c31af7Sopenharmony_ci case OPTYPE_BALLOT_BIT_EXTRACT: 126e5c31af7Sopenharmony_ci bdy << " tempResult |= subgroupBallotBitExtract(allOnes, gl_SubgroupInvocationID) ? 0x1u : 0u;\n" 127e5c31af7Sopenharmony_ci << " tempResult |= subgroupBallotBitExtract(allZeros, gl_SubgroupInvocationID) ? 0u : 0x2u;\n" 128e5c31af7Sopenharmony_ci << " tempResult |= subgroupBallotBitExtract(subgroupBallot(true), gl_SubgroupInvocationID) ? 0x4u : 0u;\n" 129e5c31af7Sopenharmony_ci << " tempResult |= 0x8u;\n" 130e5c31af7Sopenharmony_ci << " for (uint i = 0u; i < gl_SubgroupSize; i++)\n" 131e5c31af7Sopenharmony_ci << " {\n" 132e5c31af7Sopenharmony_ci << " if (!subgroupBallotBitExtract(allOnes, gl_SubgroupInvocationID))\n" 133e5c31af7Sopenharmony_ci << " {\n" 134e5c31af7Sopenharmony_ci << " tempResult &= ~0x8u;\n" 135e5c31af7Sopenharmony_ci << " }\n" 136e5c31af7Sopenharmony_ci << " }\n"; 137e5c31af7Sopenharmony_ci break; 138e5c31af7Sopenharmony_ci case OPTYPE_BALLOT_BIT_COUNT: 139e5c31af7Sopenharmony_ci bdy << " tempResult |= gl_SubgroupSize == subgroupBallotBitCount(allOnes) ? 0x1u : 0u;\n" 140e5c31af7Sopenharmony_ci << " tempResult |= 0u == subgroupBallotBitCount(allZeros) ? 0x2u : 0u;\n" 141e5c31af7Sopenharmony_ci << " tempResult |= 0u < subgroupBallotBitCount(subgroupBallot(true)) ? 0x4u : 0u;\n" 142e5c31af7Sopenharmony_ci << " tempResult |= 0u == subgroupBallotBitCount(MAKE_HIGH_BALLOT_RESULT(gl_SubgroupSize)) ? 0x8u : 0u;\n"; 143e5c31af7Sopenharmony_ci break; 144e5c31af7Sopenharmony_ci case OPTYPE_BALLOT_INCLUSIVE_BIT_COUNT: 145e5c31af7Sopenharmony_ci bdy << " uint inclusiveOffset = gl_SubgroupInvocationID + 1u;\n" 146e5c31af7Sopenharmony_ci << " tempResult |= inclusiveOffset == subgroupBallotInclusiveBitCount(allOnes) ? 0x1u : 0u;\n" 147e5c31af7Sopenharmony_ci << " tempResult |= 0u == subgroupBallotInclusiveBitCount(allZeros) ? 0x2u : 0u;\n" 148e5c31af7Sopenharmony_ci << " tempResult |= 0u < subgroupBallotInclusiveBitCount(subgroupBallot(true)) ? 0x4u : 0u;\n" 149e5c31af7Sopenharmony_ci << " tempResult |= 0x8u;\n" 150e5c31af7Sopenharmony_ci << " uvec4 inclusiveUndef = MAKE_HIGH_BALLOT_RESULT(inclusiveOffset);\n" 151e5c31af7Sopenharmony_ci << " bool undefTerritory = false;\n" 152e5c31af7Sopenharmony_ci << " for (uint i = 0u; i <= 128u; i++)\n" 153e5c31af7Sopenharmony_ci << " {\n" 154e5c31af7Sopenharmony_ci << " uvec4 iUndef = MAKE_HIGH_BALLOT_RESULT(i);\n" 155e5c31af7Sopenharmony_ci << " if (iUndef == inclusiveUndef)" 156e5c31af7Sopenharmony_ci << " {\n" 157e5c31af7Sopenharmony_ci << " undefTerritory = true;\n" 158e5c31af7Sopenharmony_ci << " }\n" 159e5c31af7Sopenharmony_ci << " uint inclusiveBitCount = subgroupBallotInclusiveBitCount(iUndef);\n" 160e5c31af7Sopenharmony_ci << " if (undefTerritory && (0u != inclusiveBitCount))\n" 161e5c31af7Sopenharmony_ci << " {\n" 162e5c31af7Sopenharmony_ci << " tempResult &= ~0x8u;\n" 163e5c31af7Sopenharmony_ci << " }\n" 164e5c31af7Sopenharmony_ci << " else if (!undefTerritory && (0u == inclusiveBitCount))\n" 165e5c31af7Sopenharmony_ci << " {\n" 166e5c31af7Sopenharmony_ci << " tempResult &= ~0x8u;\n" 167e5c31af7Sopenharmony_ci << " }\n" 168e5c31af7Sopenharmony_ci << " }\n"; 169e5c31af7Sopenharmony_ci break; 170e5c31af7Sopenharmony_ci case OPTYPE_BALLOT_EXCLUSIVE_BIT_COUNT: 171e5c31af7Sopenharmony_ci bdy << " uint exclusiveOffset = gl_SubgroupInvocationID;\n" 172e5c31af7Sopenharmony_ci << " tempResult |= exclusiveOffset == subgroupBallotExclusiveBitCount(allOnes) ? 0x1u : 0u;\n" 173e5c31af7Sopenharmony_ci << " tempResult |= 0u == subgroupBallotExclusiveBitCount(allZeros) ? 0x2u : 0u;\n" 174e5c31af7Sopenharmony_ci << " tempResult |= 0x4u;\n" 175e5c31af7Sopenharmony_ci << " tempResult |= 0x8u;\n" 176e5c31af7Sopenharmony_ci << " uvec4 exclusiveUndef = MAKE_HIGH_BALLOT_RESULT(exclusiveOffset);\n" 177e5c31af7Sopenharmony_ci << " bool undefTerritory = false;\n" 178e5c31af7Sopenharmony_ci << " for (uint i = 0u; i <= 128u; i++)\n" 179e5c31af7Sopenharmony_ci << " {\n" 180e5c31af7Sopenharmony_ci << " uvec4 iUndef = MAKE_HIGH_BALLOT_RESULT(i);\n" 181e5c31af7Sopenharmony_ci << " if (iUndef == exclusiveUndef)" 182e5c31af7Sopenharmony_ci << " {\n" 183e5c31af7Sopenharmony_ci << " undefTerritory = true;\n" 184e5c31af7Sopenharmony_ci << " }\n" 185e5c31af7Sopenharmony_ci << " uint exclusiveBitCount = subgroupBallotExclusiveBitCount(iUndef);\n" 186e5c31af7Sopenharmony_ci << " if (undefTerritory && (0u != exclusiveBitCount))\n" 187e5c31af7Sopenharmony_ci << " {\n" 188e5c31af7Sopenharmony_ci << " tempResult &= ~0x4u;\n" 189e5c31af7Sopenharmony_ci << " }\n" 190e5c31af7Sopenharmony_ci << " else if (!undefTerritory && (0u == exclusiveBitCount))\n" 191e5c31af7Sopenharmony_ci << " {\n" 192e5c31af7Sopenharmony_ci << " tempResult &= ~0x8u;\n" 193e5c31af7Sopenharmony_ci << " }\n" 194e5c31af7Sopenharmony_ci << " }\n"; 195e5c31af7Sopenharmony_ci break; 196e5c31af7Sopenharmony_ci case OPTYPE_BALLOT_FIND_LSB: 197e5c31af7Sopenharmony_ci bdy << " tempResult |= 0u == subgroupBallotFindLSB(allOnes) ? 0x1u : 0u;\n" 198e5c31af7Sopenharmony_ci << " if (subgroupElect())\n" 199e5c31af7Sopenharmony_ci << " {\n" 200e5c31af7Sopenharmony_ci << " tempResult |= 0x2u;\n" 201e5c31af7Sopenharmony_ci << " }\n" 202e5c31af7Sopenharmony_ci << " else\n" 203e5c31af7Sopenharmony_ci << " {\n" 204e5c31af7Sopenharmony_ci << " tempResult |= 0u < subgroupBallotFindLSB(subgroupBallot(true)) ? 0x2u : 0u;\n" 205e5c31af7Sopenharmony_ci << " }\n" 206e5c31af7Sopenharmony_ci << " tempResult |= gl_SubgroupSize > subgroupBallotFindLSB(subgroupBallot(true)) ? 0x4u : 0u;\n" 207e5c31af7Sopenharmony_ci << " tempResult |= 0x8u;\n" 208e5c31af7Sopenharmony_ci << " for (uint i = 0u; i < gl_SubgroupSize; i++)\n" 209e5c31af7Sopenharmony_ci << " {\n" 210e5c31af7Sopenharmony_ci << " if (i != subgroupBallotFindLSB(MAKE_HIGH_BALLOT_RESULT(i)))\n" 211e5c31af7Sopenharmony_ci << " {\n" 212e5c31af7Sopenharmony_ci << " tempResult &= ~0x8u;\n" 213e5c31af7Sopenharmony_ci << " }\n" 214e5c31af7Sopenharmony_ci << " }\n"; 215e5c31af7Sopenharmony_ci break; 216e5c31af7Sopenharmony_ci case OPTYPE_BALLOT_FIND_MSB: 217e5c31af7Sopenharmony_ci bdy << " tempResult |= (gl_SubgroupSize - 1u) == subgroupBallotFindMSB(allOnes) ? 0x1u : 0u;\n" 218e5c31af7Sopenharmony_ci << " if (subgroupElect())\n" 219e5c31af7Sopenharmony_ci << " {\n" 220e5c31af7Sopenharmony_ci << " tempResult |= 0x2u;\n" 221e5c31af7Sopenharmony_ci << " }\n" 222e5c31af7Sopenharmony_ci << " else\n" 223e5c31af7Sopenharmony_ci << " {\n" 224e5c31af7Sopenharmony_ci << " tempResult |= 0u < subgroupBallotFindMSB(subgroupBallot(true)) ? 0x2u : 0u;\n" 225e5c31af7Sopenharmony_ci << " }\n" 226e5c31af7Sopenharmony_ci << " tempResult |= gl_SubgroupSize > subgroupBallotFindMSB(subgroupBallot(true)) ? 0x4u : 0u;\n" 227e5c31af7Sopenharmony_ci << " tempResult |= 0x8u;\n" 228e5c31af7Sopenharmony_ci << " for (uint i = 0u; i < gl_SubgroupSize; i++)\n" 229e5c31af7Sopenharmony_ci << " {\n" 230e5c31af7Sopenharmony_ci << " if (i != subgroupBallotFindMSB(MAKE_SINGLE_BIT_BALLOT_RESULT(i)))\n" 231e5c31af7Sopenharmony_ci << " {\n" 232e5c31af7Sopenharmony_ci << " tempResult &= ~0x8u;\n" 233e5c31af7Sopenharmony_ci << " }\n" 234e5c31af7Sopenharmony_ci << " }\n"; 235e5c31af7Sopenharmony_ci break; 236e5c31af7Sopenharmony_ci } 237e5c31af7Sopenharmony_ci return bdy.str(); 238e5c31af7Sopenharmony_ci} 239e5c31af7Sopenharmony_ci 240e5c31af7Sopenharmony_civoid initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef) 241e5c31af7Sopenharmony_ci{ 242e5c31af7Sopenharmony_ci subgroups::setFragmentShaderFrameBuffer(programCollection); 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci if (SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage) 245e5c31af7Sopenharmony_ci subgroups::setVertexShaderFrameBuffer(programCollection); 246e5c31af7Sopenharmony_ci 247e5c31af7Sopenharmony_ci std::string bdyStr = getBodySource(caseDef); 248e5c31af7Sopenharmony_ci 249e5c31af7Sopenharmony_ci if (SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage) 250e5c31af7Sopenharmony_ci { 251e5c31af7Sopenharmony_ci std::ostringstream vertex; 252e5c31af7Sopenharmony_ci vertex << "${VERSION_DECL}\n" 253e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_ballot: enable\n" 254e5c31af7Sopenharmony_ci << "layout(location = 0) in highp vec4 in_position;\n" 255e5c31af7Sopenharmony_ci << "layout(location = 0) out float out_color;\n" 256e5c31af7Sopenharmony_ci << "\n" 257e5c31af7Sopenharmony_ci << "void main (void)\n" 258e5c31af7Sopenharmony_ci << "{\n" 259e5c31af7Sopenharmony_ci << bdyStr 260e5c31af7Sopenharmony_ci << " out_color = float(tempResult);\n" 261e5c31af7Sopenharmony_ci << " gl_Position = in_position;\n" 262e5c31af7Sopenharmony_ci << " gl_PointSize = 1.0f;\n" 263e5c31af7Sopenharmony_ci << "}\n"; 264e5c31af7Sopenharmony_ci programCollection.add("vert") << glu::VertexSource(vertex.str()); 265e5c31af7Sopenharmony_ci } 266e5c31af7Sopenharmony_ci else if (SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage) 267e5c31af7Sopenharmony_ci { 268e5c31af7Sopenharmony_ci std::ostringstream geometry; 269e5c31af7Sopenharmony_ci 270e5c31af7Sopenharmony_ci geometry << "${VERSION_DECL}\n" 271e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_ballot: enable\n" 272e5c31af7Sopenharmony_ci << "layout(points) in;\n" 273e5c31af7Sopenharmony_ci << "layout(points, max_vertices = 1) out;\n" 274e5c31af7Sopenharmony_ci << "layout(location = 0) out float out_color;\n" 275e5c31af7Sopenharmony_ci << "void main (void)\n" 276e5c31af7Sopenharmony_ci << "{\n" 277e5c31af7Sopenharmony_ci << bdyStr 278e5c31af7Sopenharmony_ci << " out_color = float(tempResult);\n" 279e5c31af7Sopenharmony_ci << " gl_Position = gl_in[0].gl_Position;\n" 280e5c31af7Sopenharmony_ci << " EmitVertex();\n" 281e5c31af7Sopenharmony_ci << " EndPrimitive();\n" 282e5c31af7Sopenharmony_ci << "}\n"; 283e5c31af7Sopenharmony_ci 284e5c31af7Sopenharmony_ci programCollection.add("geometry") << glu::GeometrySource(geometry.str()); 285e5c31af7Sopenharmony_ci } 286e5c31af7Sopenharmony_ci else if (SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage) 287e5c31af7Sopenharmony_ci { 288e5c31af7Sopenharmony_ci std::ostringstream controlSource; 289e5c31af7Sopenharmony_ci 290e5c31af7Sopenharmony_ci controlSource << "${VERSION_DECL}\n" 291e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_ballot: enable\n" 292e5c31af7Sopenharmony_ci << "layout(vertices = 2) out;\n" 293e5c31af7Sopenharmony_ci << "layout(location = 0) out float out_color[];\n" 294e5c31af7Sopenharmony_ci << "\n" 295e5c31af7Sopenharmony_ci << "void main (void)\n" 296e5c31af7Sopenharmony_ci << "{\n" 297e5c31af7Sopenharmony_ci << " if (gl_InvocationID == 0)\n" 298e5c31af7Sopenharmony_ci << " {\n" 299e5c31af7Sopenharmony_ci << " gl_TessLevelOuter[0] = 1.0f;\n" 300e5c31af7Sopenharmony_ci << " gl_TessLevelOuter[1] = 1.0f;\n" 301e5c31af7Sopenharmony_ci << " }\n" 302e5c31af7Sopenharmony_ci << bdyStr 303e5c31af7Sopenharmony_ci << " out_color[gl_InvocationID ] = float(tempResult);\n" 304e5c31af7Sopenharmony_ci << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 305e5c31af7Sopenharmony_ci << "}\n"; 306e5c31af7Sopenharmony_ci 307e5c31af7Sopenharmony_ci programCollection.add("tesc") << glu::TessellationControlSource(controlSource.str()); 308e5c31af7Sopenharmony_ci subgroups::setTesEvalShaderFrameBuffer(programCollection); 309e5c31af7Sopenharmony_ci } 310e5c31af7Sopenharmony_ci else if (SHADER_STAGE_TESS_EVALUATION_BIT == caseDef.shaderStage) 311e5c31af7Sopenharmony_ci { 312e5c31af7Sopenharmony_ci std::ostringstream evaluationSource; 313e5c31af7Sopenharmony_ci evaluationSource << "${VERSION_DECL}\n" 314e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_ballot: enable\n" 315e5c31af7Sopenharmony_ci << "layout(isolines, equal_spacing, ccw ) in;\n" 316e5c31af7Sopenharmony_ci << "layout(location = 0) out float out_color;\n" 317e5c31af7Sopenharmony_ci << "void main (void)\n" 318e5c31af7Sopenharmony_ci << "{\n" 319e5c31af7Sopenharmony_ci << bdyStr 320e5c31af7Sopenharmony_ci << " out_color = float(tempResult);\n" 321e5c31af7Sopenharmony_ci << " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n" 322e5c31af7Sopenharmony_ci << "}\n"; 323e5c31af7Sopenharmony_ci 324e5c31af7Sopenharmony_ci subgroups::setTesCtrlShaderFrameBuffer(programCollection); 325e5c31af7Sopenharmony_ci programCollection.add("tese") << glu::TessellationEvaluationSource(evaluationSource.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 std::string bdyStr = getBodySource(caseDef); 336e5c31af7Sopenharmony_ci 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_ballot: enable\n" 343e5c31af7Sopenharmony_ci << "layout (${LOCAL_SIZE_X}, ${LOCAL_SIZE_Y}, ${LOCAL_SIZE_Z}) in;\n" 344e5c31af7Sopenharmony_ci << "layout(binding = 0, std430) buffer Buffer0\n" 345e5c31af7Sopenharmony_ci << "{\n" 346e5c31af7Sopenharmony_ci << " uint result[];\n" 347e5c31af7Sopenharmony_ci << "};\n" 348e5c31af7Sopenharmony_ci << "\n" 349e5c31af7Sopenharmony_ci << "void main (void)\n" 350e5c31af7Sopenharmony_ci << "{\n" 351e5c31af7Sopenharmony_ci << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n" 352e5c31af7Sopenharmony_ci << " highp uint offset = globalSize.x * ((globalSize.y * " 353e5c31af7Sopenharmony_ci "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + " 354e5c31af7Sopenharmony_ci "gl_GlobalInvocationID.x;\n" 355e5c31af7Sopenharmony_ci << bdyStr 356e5c31af7Sopenharmony_ci << " result[offset] = tempResult;\n" 357e5c31af7Sopenharmony_ci << "}\n"; 358e5c31af7Sopenharmony_ci 359e5c31af7Sopenharmony_ci programCollection.add("comp") << glu::ComputeSource(src.str()); 360e5c31af7Sopenharmony_ci } 361e5c31af7Sopenharmony_ci else 362e5c31af7Sopenharmony_ci { 363e5c31af7Sopenharmony_ci const string vertex = 364e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 365e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 366e5c31af7Sopenharmony_ci "layout(binding = 0, std430) buffer Buffer0\n" 367e5c31af7Sopenharmony_ci "{\n" 368e5c31af7Sopenharmony_ci " uint result[];\n" 369e5c31af7Sopenharmony_ci "} b0;\n" 370e5c31af7Sopenharmony_ci "\n" 371e5c31af7Sopenharmony_ci "void main (void)\n" 372e5c31af7Sopenharmony_ci "{\n" 373e5c31af7Sopenharmony_ci + bdyStr + 374e5c31af7Sopenharmony_ci " b0.result[gl_VertexID] = tempResult;\n" 375e5c31af7Sopenharmony_ci " float pixelSize = 2.0f/1024.0f;\n" 376e5c31af7Sopenharmony_ci " float pixelPosition = pixelSize/2.0f - 1.0f;\n" 377e5c31af7Sopenharmony_ci " gl_Position = vec4(float(gl_VertexID) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n" 378e5c31af7Sopenharmony_ci " gl_PointSize = 1.0f;\n" 379e5c31af7Sopenharmony_ci "}\n"; 380e5c31af7Sopenharmony_ci 381e5c31af7Sopenharmony_ci const string tesc = 382e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 383e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 384e5c31af7Sopenharmony_ci "layout(vertices=1) out;\n" 385e5c31af7Sopenharmony_ci "layout(binding = 1, std430) buffer Buffer1\n" 386e5c31af7Sopenharmony_ci "{\n" 387e5c31af7Sopenharmony_ci " uint result[];\n" 388e5c31af7Sopenharmony_ci "} b1;\n" 389e5c31af7Sopenharmony_ci "\n" 390e5c31af7Sopenharmony_ci "void main (void)\n" 391e5c31af7Sopenharmony_ci "{\n" 392e5c31af7Sopenharmony_ci + bdyStr + 393e5c31af7Sopenharmony_ci " b1.result[gl_PrimitiveID] = tempResult;\n" 394e5c31af7Sopenharmony_ci " if (gl_InvocationID == 0)\n" 395e5c31af7Sopenharmony_ci " {\n" 396e5c31af7Sopenharmony_ci " gl_TessLevelOuter[0] = 1.0f;\n" 397e5c31af7Sopenharmony_ci " gl_TessLevelOuter[1] = 1.0f;\n" 398e5c31af7Sopenharmony_ci " }\n" 399e5c31af7Sopenharmony_ci " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 400e5c31af7Sopenharmony_ci "}\n"; 401e5c31af7Sopenharmony_ci 402e5c31af7Sopenharmony_ci const string tese = 403e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 404e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 405e5c31af7Sopenharmony_ci "layout(isolines) in;\n" 406e5c31af7Sopenharmony_ci "layout(binding = 2, std430) buffer Buffer2\n" 407e5c31af7Sopenharmony_ci "{\n" 408e5c31af7Sopenharmony_ci " uint result[];\n" 409e5c31af7Sopenharmony_ci "} b2;\n" 410e5c31af7Sopenharmony_ci "\n" 411e5c31af7Sopenharmony_ci "void main (void)\n" 412e5c31af7Sopenharmony_ci "{\n" 413e5c31af7Sopenharmony_ci + bdyStr + 414e5c31af7Sopenharmony_ci " b2.result[gl_PrimitiveID * 2 + int(gl_TessCoord.x + 0.5)] = tempResult;\n" 415e5c31af7Sopenharmony_ci " float pixelSize = 2.0f/1024.0f;\n" 416e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n" 417e5c31af7Sopenharmony_ci "}\n"; 418e5c31af7Sopenharmony_ci 419e5c31af7Sopenharmony_ci const string geometry = 420e5c31af7Sopenharmony_ci // version string added by addGeometryShadersFromTemplate 421e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 422e5c31af7Sopenharmony_ci "layout(${TOPOLOGY}) in;\n" 423e5c31af7Sopenharmony_ci "layout(points, max_vertices = 1) out;\n" 424e5c31af7Sopenharmony_ci "layout(binding = 3, std430) buffer Buffer3\n" 425e5c31af7Sopenharmony_ci "{\n" 426e5c31af7Sopenharmony_ci " uint result[];\n" 427e5c31af7Sopenharmony_ci "} b3;\n" 428e5c31af7Sopenharmony_ci "\n" 429e5c31af7Sopenharmony_ci "void main (void)\n" 430e5c31af7Sopenharmony_ci "{\n" 431e5c31af7Sopenharmony_ci + bdyStr + 432e5c31af7Sopenharmony_ci " b3.result[gl_PrimitiveIDIn] = tempResult;\n" 433e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 434e5c31af7Sopenharmony_ci " EmitVertex();\n" 435e5c31af7Sopenharmony_ci " EndPrimitive();\n" 436e5c31af7Sopenharmony_ci "}\n"; 437e5c31af7Sopenharmony_ci 438e5c31af7Sopenharmony_ci const string fragment = 439e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 440e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 441e5c31af7Sopenharmony_ci "precision highp int;\n" 442e5c31af7Sopenharmony_ci "layout(location = 0) out uint result;\n" 443e5c31af7Sopenharmony_ci "void main (void)\n" 444e5c31af7Sopenharmony_ci "{\n" 445e5c31af7Sopenharmony_ci + bdyStr + 446e5c31af7Sopenharmony_ci " result = tempResult;\n" 447e5c31af7Sopenharmony_ci "}\n"; 448e5c31af7Sopenharmony_ci 449e5c31af7Sopenharmony_ci subgroups::addNoSubgroupShader(programCollection); 450e5c31af7Sopenharmony_ci 451e5c31af7Sopenharmony_ci programCollection.add("vert") << glu::VertexSource(vertex); 452e5c31af7Sopenharmony_ci programCollection.add("tesc") << glu::TessellationControlSource(tesc); 453e5c31af7Sopenharmony_ci programCollection.add("tese") << glu::TessellationEvaluationSource(tese); 454e5c31af7Sopenharmony_ci subgroups::addGeometryShadersFromTemplate(geometry, programCollection); 455e5c31af7Sopenharmony_ci programCollection.add("fragment") << glu::FragmentSource(fragment); 456e5c31af7Sopenharmony_ci } 457e5c31af7Sopenharmony_ci} 458e5c31af7Sopenharmony_ci 459e5c31af7Sopenharmony_civoid supportedCheck (Context& context, CaseDefinition caseDef) 460e5c31af7Sopenharmony_ci{ 461e5c31af7Sopenharmony_ci DE_UNREF(caseDef); 462e5c31af7Sopenharmony_ci if (!subgroups::isSubgroupSupported(context)) 463e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Subgroup operations are not supported"); 464e5c31af7Sopenharmony_ci 465e5c31af7Sopenharmony_ci if (!subgroups::isSubgroupFeatureSupportedForDevice(context, SUBGROUP_FEATURE_BALLOT_BIT)) 466e5c31af7Sopenharmony_ci { 467e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support subgroup ballot operations"); 468e5c31af7Sopenharmony_ci } 469e5c31af7Sopenharmony_ci} 470e5c31af7Sopenharmony_ci 471e5c31af7Sopenharmony_citcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef) 472e5c31af7Sopenharmony_ci{ 473e5c31af7Sopenharmony_ci if (!subgroups::areSubgroupOperationsSupportedForStage( 474e5c31af7Sopenharmony_ci context, caseDef.shaderStage)) 475e5c31af7Sopenharmony_ci { 476e5c31af7Sopenharmony_ci if (subgroups::areSubgroupOperationsRequiredForStage(caseDef.shaderStage)) 477e5c31af7Sopenharmony_ci { 478e5c31af7Sopenharmony_ci return tcu::TestStatus::fail( 479e5c31af7Sopenharmony_ci "Shader stage " + 480e5c31af7Sopenharmony_ci subgroups::getShaderStageName(caseDef.shaderStage) + 481e5c31af7Sopenharmony_ci " is required to support subgroup operations!"); 482e5c31af7Sopenharmony_ci } 483e5c31af7Sopenharmony_ci else 484e5c31af7Sopenharmony_ci { 485e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage"); 486e5c31af7Sopenharmony_ci } 487e5c31af7Sopenharmony_ci } 488e5c31af7Sopenharmony_ci 489e5c31af7Sopenharmony_ci if (SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage) 490e5c31af7Sopenharmony_ci return subgroups::makeVertexFrameBufferTest(context, FORMAT_R32_UINT, DE_NULL, 0, checkVertexPipelineStages); 491e5c31af7Sopenharmony_ci else if (SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage) 492e5c31af7Sopenharmony_ci return subgroups::makeGeometryFrameBufferTest(context, FORMAT_R32_UINT, DE_NULL, 0, checkVertexPipelineStages); 493e5c31af7Sopenharmony_ci else if ((SHADER_STAGE_TESS_CONTROL_BIT | SHADER_STAGE_TESS_EVALUATION_BIT) & caseDef.shaderStage) 494e5c31af7Sopenharmony_ci return subgroups::makeTessellationEvaluationFrameBufferTest(context, FORMAT_R32_UINT, DE_NULL, 0, checkVertexPipelineStages); 495e5c31af7Sopenharmony_ci else 496e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Unhandled shader stage"); 497e5c31af7Sopenharmony_ci} 498e5c31af7Sopenharmony_ci 499e5c31af7Sopenharmony_citcu::TestStatus test (Context& context, const CaseDefinition caseDef) 500e5c31af7Sopenharmony_ci{ 501e5c31af7Sopenharmony_ci if (SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage) 502e5c31af7Sopenharmony_ci { 503e5c31af7Sopenharmony_ci if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage)) 504e5c31af7Sopenharmony_ci { 505e5c31af7Sopenharmony_ci return tcu::TestStatus::fail( 506e5c31af7Sopenharmony_ci "Shader stage " + 507e5c31af7Sopenharmony_ci subgroups::getShaderStageName(caseDef.shaderStage) + 508e5c31af7Sopenharmony_ci " is required to support subgroup operations!"); 509e5c31af7Sopenharmony_ci } 510e5c31af7Sopenharmony_ci return subgroups::makeComputeTest(context, FORMAT_R32_UINT, DE_NULL, 0, checkComputeStage); 511e5c31af7Sopenharmony_ci } 512e5c31af7Sopenharmony_ci else 513e5c31af7Sopenharmony_ci { 514e5c31af7Sopenharmony_ci int supportedStages = context.getDeqpContext().getContextInfo().getInt(GL_SUBGROUP_SUPPORTED_STAGES_KHR); 515e5c31af7Sopenharmony_ci 516e5c31af7Sopenharmony_ci ShaderStageFlags stages = (ShaderStageFlags)(caseDef.shaderStage & supportedStages); 517e5c31af7Sopenharmony_ci 518e5c31af7Sopenharmony_ci if ( SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context)) 519e5c31af7Sopenharmony_ci { 520e5c31af7Sopenharmony_ci if ( (stages & SHADER_STAGE_FRAGMENT_BIT) == 0) 521e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes"); 522e5c31af7Sopenharmony_ci else 523e5c31af7Sopenharmony_ci stages = SHADER_STAGE_FRAGMENT_BIT; 524e5c31af7Sopenharmony_ci } 525e5c31af7Sopenharmony_ci 526e5c31af7Sopenharmony_ci if ((ShaderStageFlags)0u == stages) 527e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Subgroup operations are not supported for any graphic shader"); 528e5c31af7Sopenharmony_ci 529e5c31af7Sopenharmony_ci return subgroups::allStages(context, FORMAT_R32_UINT, DE_NULL, 0, checkVertexPipelineStages, stages); 530e5c31af7Sopenharmony_ci } 531e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("OK"); 532e5c31af7Sopenharmony_ci} 533e5c31af7Sopenharmony_ci} 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_cideqp::TestCaseGroup* createSubgroupsBallotOtherTests(deqp::Context& testCtx) 536e5c31af7Sopenharmony_ci{ 537e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> graphicGroup(new deqp::TestCaseGroup( 538e5c31af7Sopenharmony_ci testCtx, "graphics", "Subgroup ballot other category tests: graphics")); 539e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> computeGroup(new deqp::TestCaseGroup( 540e5c31af7Sopenharmony_ci testCtx, "compute", "Subgroup ballot other category tests: compute")); 541e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> framebufferGroup(new deqp::TestCaseGroup( 542e5c31af7Sopenharmony_ci testCtx, "framebuffer", "Subgroup ballot other category tests: framebuffer")); 543e5c31af7Sopenharmony_ci 544e5c31af7Sopenharmony_ci const ShaderStageFlags stages[] = 545e5c31af7Sopenharmony_ci { 546e5c31af7Sopenharmony_ci SHADER_STAGE_VERTEX_BIT, 547e5c31af7Sopenharmony_ci SHADER_STAGE_TESS_EVALUATION_BIT, 548e5c31af7Sopenharmony_ci SHADER_STAGE_TESS_CONTROL_BIT, 549e5c31af7Sopenharmony_ci SHADER_STAGE_GEOMETRY_BIT, 550e5c31af7Sopenharmony_ci }; 551e5c31af7Sopenharmony_ci 552e5c31af7Sopenharmony_ci for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex) 553e5c31af7Sopenharmony_ci { 554e5c31af7Sopenharmony_ci const string op = de::toLower(getOpTypeName(opTypeIndex)); 555e5c31af7Sopenharmony_ci { 556e5c31af7Sopenharmony_ci const CaseDefinition caseDef = {opTypeIndex, SHADER_STAGE_COMPUTE_BIT}; 557e5c31af7Sopenharmony_ci SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(computeGroup.get(), op, "", supportedCheck, initPrograms, test, caseDef); 558e5c31af7Sopenharmony_ci } 559e5c31af7Sopenharmony_ci 560e5c31af7Sopenharmony_ci { 561e5c31af7Sopenharmony_ci const CaseDefinition caseDef = {opTypeIndex, SHADER_STAGE_ALL_GRAPHICS}; 562e5c31af7Sopenharmony_ci SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(graphicGroup.get(), op, "", supportedCheck, initPrograms, test, caseDef); 563e5c31af7Sopenharmony_ci } 564e5c31af7Sopenharmony_ci 565e5c31af7Sopenharmony_ci for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex) 566e5c31af7Sopenharmony_ci { 567e5c31af7Sopenharmony_ci const CaseDefinition caseDef = {opTypeIndex, stages[stageIndex]}; 568e5c31af7Sopenharmony_ci SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(framebufferGroup.get(), op + "_" + getShaderStageName(caseDef.shaderStage), "", supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef); 569e5c31af7Sopenharmony_ci } 570e5c31af7Sopenharmony_ci } 571e5c31af7Sopenharmony_ci 572e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> group(new deqp::TestCaseGroup( 573e5c31af7Sopenharmony_ci testCtx, "ballot_other", "Subgroup ballot other category tests")); 574e5c31af7Sopenharmony_ci 575e5c31af7Sopenharmony_ci group->addChild(graphicGroup.release()); 576e5c31af7Sopenharmony_ci group->addChild(computeGroup.release()); 577e5c31af7Sopenharmony_ci group->addChild(framebufferGroup.release()); 578e5c31af7Sopenharmony_ci 579e5c31af7Sopenharmony_ci return group.release(); 580e5c31af7Sopenharmony_ci} 581e5c31af7Sopenharmony_ci 582e5c31af7Sopenharmony_ci} // subgroups 583e5c31af7Sopenharmony_ci} // glc 584