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