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 "glcSubgroupsClusteredTests.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_CLUSTERED_ADD = 0, 44e5c31af7Sopenharmony_ci OPTYPE_CLUSTERED_MUL, 45e5c31af7Sopenharmony_ci OPTYPE_CLUSTERED_MIN, 46e5c31af7Sopenharmony_ci OPTYPE_CLUSTERED_MAX, 47e5c31af7Sopenharmony_ci OPTYPE_CLUSTERED_AND, 48e5c31af7Sopenharmony_ci OPTYPE_CLUSTERED_OR, 49e5c31af7Sopenharmony_ci OPTYPE_CLUSTERED_XOR, 50e5c31af7Sopenharmony_ci OPTYPE_CLUSTERED_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, 1); 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, 1); 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_CLUSTERED_ADD: 74e5c31af7Sopenharmony_ci return "subgroupClusteredAdd"; 75e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_MUL: 76e5c31af7Sopenharmony_ci return "subgroupClusteredMul"; 77e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_MIN: 78e5c31af7Sopenharmony_ci return "subgroupClusteredMin"; 79e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_MAX: 80e5c31af7Sopenharmony_ci return "subgroupClusteredMax"; 81e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_AND: 82e5c31af7Sopenharmony_ci return "subgroupClusteredAnd"; 83e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_OR: 84e5c31af7Sopenharmony_ci return "subgroupClusteredOr"; 85e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_XOR: 86e5c31af7Sopenharmony_ci return "subgroupClusteredXor"; 87e5c31af7Sopenharmony_ci } 88e5c31af7Sopenharmony_ci} 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_cistd::string getOpTypeOperation(int opType, Format format, std::string lhs, std::string rhs) 91e5c31af7Sopenharmony_ci{ 92e5c31af7Sopenharmony_ci switch (opType) 93e5c31af7Sopenharmony_ci { 94e5c31af7Sopenharmony_ci default: 95e5c31af7Sopenharmony_ci DE_FATAL("Unsupported op type"); 96e5c31af7Sopenharmony_ci return ""; 97e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_ADD: 98e5c31af7Sopenharmony_ci return lhs + " + " + rhs; 99e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_MUL: 100e5c31af7Sopenharmony_ci return lhs + " * " + rhs; 101e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_MIN: 102e5c31af7Sopenharmony_ci switch (format) 103e5c31af7Sopenharmony_ci { 104e5c31af7Sopenharmony_ci default: 105e5c31af7Sopenharmony_ci return "min(" + lhs + ", " + rhs + ")"; 106e5c31af7Sopenharmony_ci case FORMAT_R32_SFLOAT: 107e5c31af7Sopenharmony_ci case FORMAT_R64_SFLOAT: 108e5c31af7Sopenharmony_ci return "(isnan(" + lhs + ") ? " + rhs + " : (isnan(" + rhs + ") ? " + lhs + " : min(" + lhs + ", " + rhs + ")))"; 109e5c31af7Sopenharmony_ci case FORMAT_R32G32_SFLOAT: 110e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_SFLOAT: 111e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_SFLOAT: 112e5c31af7Sopenharmony_ci case FORMAT_R64G64_SFLOAT: 113e5c31af7Sopenharmony_ci case FORMAT_R64G64B64_SFLOAT: 114e5c31af7Sopenharmony_ci case FORMAT_R64G64B64A64_SFLOAT: 115e5c31af7Sopenharmony_ci return "mix(mix(min(" + lhs + ", " + rhs + "), " + lhs + ", isnan(" + rhs + ")), " + rhs + ", isnan(" + lhs + "))"; 116e5c31af7Sopenharmony_ci } 117e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_MAX: 118e5c31af7Sopenharmony_ci switch (format) 119e5c31af7Sopenharmony_ci { 120e5c31af7Sopenharmony_ci default: 121e5c31af7Sopenharmony_ci return "max(" + lhs + ", " + rhs + ")"; 122e5c31af7Sopenharmony_ci case FORMAT_R32_SFLOAT: 123e5c31af7Sopenharmony_ci case FORMAT_R64_SFLOAT: 124e5c31af7Sopenharmony_ci return "(isnan(" + lhs + ") ? " + rhs + " : (isnan(" + rhs + ") ? " + lhs + " : max(" + lhs + ", " + rhs + ")))"; 125e5c31af7Sopenharmony_ci case FORMAT_R32G32_SFLOAT: 126e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_SFLOAT: 127e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_SFLOAT: 128e5c31af7Sopenharmony_ci case FORMAT_R64G64_SFLOAT: 129e5c31af7Sopenharmony_ci case FORMAT_R64G64B64_SFLOAT: 130e5c31af7Sopenharmony_ci case FORMAT_R64G64B64A64_SFLOAT: 131e5c31af7Sopenharmony_ci return "mix(mix(max(" + lhs + ", " + rhs + "), " + lhs + ", isnan(" + rhs + ")), " + rhs + ", isnan(" + lhs + "))"; 132e5c31af7Sopenharmony_ci } 133e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_AND: 134e5c31af7Sopenharmony_ci switch (format) 135e5c31af7Sopenharmony_ci { 136e5c31af7Sopenharmony_ci default: 137e5c31af7Sopenharmony_ci return lhs + " & " + rhs; 138e5c31af7Sopenharmony_ci case FORMAT_R32_BOOL: 139e5c31af7Sopenharmony_ci return lhs + " && " + rhs; 140e5c31af7Sopenharmony_ci case FORMAT_R32G32_BOOL: 141e5c31af7Sopenharmony_ci return "bvec2(" + lhs + ".x && " + rhs + ".x, " + lhs + ".y && " + rhs + ".y)"; 142e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_BOOL: 143e5c31af7Sopenharmony_ci return "bvec3(" + lhs + ".x && " + rhs + ".x, " + lhs + ".y && " + rhs + ".y, " + lhs + ".z && " + rhs + ".z)"; 144e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_BOOL: 145e5c31af7Sopenharmony_ci return "bvec4(" + lhs + ".x && " + rhs + ".x, " + lhs + ".y && " + rhs + ".y, " + lhs + ".z && " + rhs + ".z, " + lhs + ".w && " + rhs + ".w)"; 146e5c31af7Sopenharmony_ci } 147e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_OR: 148e5c31af7Sopenharmony_ci switch (format) 149e5c31af7Sopenharmony_ci { 150e5c31af7Sopenharmony_ci default: 151e5c31af7Sopenharmony_ci return lhs + " | " + rhs; 152e5c31af7Sopenharmony_ci case FORMAT_R32_BOOL: 153e5c31af7Sopenharmony_ci return lhs + " || " + rhs; 154e5c31af7Sopenharmony_ci case FORMAT_R32G32_BOOL: 155e5c31af7Sopenharmony_ci return "bvec2(" + lhs + ".x || " + rhs + ".x, " + lhs + ".y || " + rhs + ".y)"; 156e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_BOOL: 157e5c31af7Sopenharmony_ci return "bvec3(" + lhs + ".x || " + rhs + ".x, " + lhs + ".y || " + rhs + ".y, " + lhs + ".z || " + rhs + ".z)"; 158e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_BOOL: 159e5c31af7Sopenharmony_ci return "bvec4(" + lhs + ".x || " + rhs + ".x, " + lhs + ".y || " + rhs + ".y, " + lhs + ".z || " + rhs + ".z, " + lhs + ".w || " + rhs + ".w)"; 160e5c31af7Sopenharmony_ci } 161e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_XOR: 162e5c31af7Sopenharmony_ci switch (format) 163e5c31af7Sopenharmony_ci { 164e5c31af7Sopenharmony_ci default: 165e5c31af7Sopenharmony_ci return lhs + " ^ " + rhs; 166e5c31af7Sopenharmony_ci case FORMAT_R32_BOOL: 167e5c31af7Sopenharmony_ci return lhs + " ^^ " + rhs; 168e5c31af7Sopenharmony_ci case FORMAT_R32G32_BOOL: 169e5c31af7Sopenharmony_ci return "bvec2(" + lhs + ".x ^^ " + rhs + ".x, " + lhs + ".y ^^ " + rhs + ".y)"; 170e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_BOOL: 171e5c31af7Sopenharmony_ci return "bvec3(" + lhs + ".x ^^ " + rhs + ".x, " + lhs + ".y ^^ " + rhs + ".y, " + lhs + ".z ^^ " + rhs + ".z)"; 172e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_BOOL: 173e5c31af7Sopenharmony_ci return "bvec4(" + lhs + ".x ^^ " + rhs + ".x, " + lhs + ".y ^^ " + rhs + ".y, " + lhs + ".z ^^ " + rhs + ".z, " + lhs + ".w ^^ " + rhs + ".w)"; 174e5c31af7Sopenharmony_ci } 175e5c31af7Sopenharmony_ci } 176e5c31af7Sopenharmony_ci} 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_cistd::string getIdentity(int opType, Format format) 179e5c31af7Sopenharmony_ci{ 180e5c31af7Sopenharmony_ci bool isFloat = false; 181e5c31af7Sopenharmony_ci bool isInt = false; 182e5c31af7Sopenharmony_ci bool isUnsigned = false; 183e5c31af7Sopenharmony_ci 184e5c31af7Sopenharmony_ci switch (format) 185e5c31af7Sopenharmony_ci { 186e5c31af7Sopenharmony_ci default: 187e5c31af7Sopenharmony_ci DE_FATAL("Unhandled format!"); 188e5c31af7Sopenharmony_ci break; 189e5c31af7Sopenharmony_ci case FORMAT_R32_SINT: 190e5c31af7Sopenharmony_ci case FORMAT_R32G32_SINT: 191e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_SINT: 192e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_SINT: 193e5c31af7Sopenharmony_ci isInt = true; 194e5c31af7Sopenharmony_ci break; 195e5c31af7Sopenharmony_ci case FORMAT_R32_UINT: 196e5c31af7Sopenharmony_ci case FORMAT_R32G32_UINT: 197e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_UINT: 198e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_UINT: 199e5c31af7Sopenharmony_ci isUnsigned = true; 200e5c31af7Sopenharmony_ci break; 201e5c31af7Sopenharmony_ci case FORMAT_R32_SFLOAT: 202e5c31af7Sopenharmony_ci case FORMAT_R32G32_SFLOAT: 203e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_SFLOAT: 204e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_SFLOAT: 205e5c31af7Sopenharmony_ci case FORMAT_R64_SFLOAT: 206e5c31af7Sopenharmony_ci case FORMAT_R64G64_SFLOAT: 207e5c31af7Sopenharmony_ci case FORMAT_R64G64B64_SFLOAT: 208e5c31af7Sopenharmony_ci case FORMAT_R64G64B64A64_SFLOAT: 209e5c31af7Sopenharmony_ci isFloat = true; 210e5c31af7Sopenharmony_ci break; 211e5c31af7Sopenharmony_ci case FORMAT_R32_BOOL: 212e5c31af7Sopenharmony_ci case FORMAT_R32G32_BOOL: 213e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_BOOL: 214e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_BOOL: 215e5c31af7Sopenharmony_ci break; // bool types are not anything 216e5c31af7Sopenharmony_ci } 217e5c31af7Sopenharmony_ci 218e5c31af7Sopenharmony_ci switch (opType) 219e5c31af7Sopenharmony_ci { 220e5c31af7Sopenharmony_ci default: 221e5c31af7Sopenharmony_ci DE_FATAL("Unsupported op type"); 222e5c31af7Sopenharmony_ci return ""; 223e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_ADD: 224e5c31af7Sopenharmony_ci return subgroups::getFormatNameForGLSL(format) + "(0)"; 225e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_MUL: 226e5c31af7Sopenharmony_ci return subgroups::getFormatNameForGLSL(format) + "(1)"; 227e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_MIN: 228e5c31af7Sopenharmony_ci if (isFloat) 229e5c31af7Sopenharmony_ci { 230e5c31af7Sopenharmony_ci return subgroups::getFormatNameForGLSL(format) + "(intBitsToFloat(0x7f800000))"; 231e5c31af7Sopenharmony_ci } 232e5c31af7Sopenharmony_ci else if (isInt) 233e5c31af7Sopenharmony_ci { 234e5c31af7Sopenharmony_ci return subgroups::getFormatNameForGLSL(format) + "(0x7fffffff)"; 235e5c31af7Sopenharmony_ci } 236e5c31af7Sopenharmony_ci else if (isUnsigned) 237e5c31af7Sopenharmony_ci { 238e5c31af7Sopenharmony_ci return subgroups::getFormatNameForGLSL(format) + "(0xffffffffu)"; 239e5c31af7Sopenharmony_ci } 240e5c31af7Sopenharmony_ci else 241e5c31af7Sopenharmony_ci { 242e5c31af7Sopenharmony_ci DE_FATAL("Unhandled case"); 243e5c31af7Sopenharmony_ci return ""; 244e5c31af7Sopenharmony_ci } 245e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_MAX: 246e5c31af7Sopenharmony_ci if (isFloat) 247e5c31af7Sopenharmony_ci { 248e5c31af7Sopenharmony_ci return subgroups::getFormatNameForGLSL(format) + "(intBitsToFloat(0xff800000))"; 249e5c31af7Sopenharmony_ci } 250e5c31af7Sopenharmony_ci else if (isInt) 251e5c31af7Sopenharmony_ci { 252e5c31af7Sopenharmony_ci return subgroups::getFormatNameForGLSL(format) + "(0x80000000)"; 253e5c31af7Sopenharmony_ci } 254e5c31af7Sopenharmony_ci else if (isUnsigned) 255e5c31af7Sopenharmony_ci { 256e5c31af7Sopenharmony_ci return subgroups::getFormatNameForGLSL(format) + "(0u)"; 257e5c31af7Sopenharmony_ci } 258e5c31af7Sopenharmony_ci else 259e5c31af7Sopenharmony_ci { 260e5c31af7Sopenharmony_ci DE_FATAL("Unhandled case"); 261e5c31af7Sopenharmony_ci return ""; 262e5c31af7Sopenharmony_ci } 263e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_AND: 264e5c31af7Sopenharmony_ci return subgroups::getFormatNameForGLSL(format) + "(~0)"; 265e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_OR: 266e5c31af7Sopenharmony_ci return subgroups::getFormatNameForGLSL(format) + "(0)"; 267e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_XOR: 268e5c31af7Sopenharmony_ci return subgroups::getFormatNameForGLSL(format) + "(0)"; 269e5c31af7Sopenharmony_ci } 270e5c31af7Sopenharmony_ci} 271e5c31af7Sopenharmony_ci 272e5c31af7Sopenharmony_cistd::string getCompare(int opType, Format format, std::string lhs, std::string rhs) 273e5c31af7Sopenharmony_ci{ 274e5c31af7Sopenharmony_ci std::string formatName = subgroups::getFormatNameForGLSL(format); 275e5c31af7Sopenharmony_ci switch (format) 276e5c31af7Sopenharmony_ci { 277e5c31af7Sopenharmony_ci default: 278e5c31af7Sopenharmony_ci return "all(equal(" + lhs + ", " + rhs + "))"; 279e5c31af7Sopenharmony_ci case FORMAT_R32_BOOL: 280e5c31af7Sopenharmony_ci case FORMAT_R32_UINT: 281e5c31af7Sopenharmony_ci case FORMAT_R32_SINT: 282e5c31af7Sopenharmony_ci return "(" + lhs + " == " + rhs + ")"; 283e5c31af7Sopenharmony_ci case FORMAT_R32_SFLOAT: 284e5c31af7Sopenharmony_ci case FORMAT_R64_SFLOAT: 285e5c31af7Sopenharmony_ci switch (opType) 286e5c31af7Sopenharmony_ci { 287e5c31af7Sopenharmony_ci default: 288e5c31af7Sopenharmony_ci return "(abs(" + lhs + " - " + rhs + ") < 0.00001)"; 289e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_MIN: 290e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_MAX: 291e5c31af7Sopenharmony_ci return "(" + lhs + " == " + rhs + ")"; 292e5c31af7Sopenharmony_ci } 293e5c31af7Sopenharmony_ci case FORMAT_R32G32_SFLOAT: 294e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_SFLOAT: 295e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_SFLOAT: 296e5c31af7Sopenharmony_ci case FORMAT_R64G64_SFLOAT: 297e5c31af7Sopenharmony_ci case FORMAT_R64G64B64_SFLOAT: 298e5c31af7Sopenharmony_ci case FORMAT_R64G64B64A64_SFLOAT: 299e5c31af7Sopenharmony_ci switch (opType) 300e5c31af7Sopenharmony_ci { 301e5c31af7Sopenharmony_ci default: 302e5c31af7Sopenharmony_ci return "all(lessThan(abs(" + lhs + " - " + rhs + "), " + formatName + "(0.00001)))"; 303e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_MIN: 304e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_MAX: 305e5c31af7Sopenharmony_ci return "all(equal(" + lhs + ", " + rhs + "))"; 306e5c31af7Sopenharmony_ci } 307e5c31af7Sopenharmony_ci } 308e5c31af7Sopenharmony_ci} 309e5c31af7Sopenharmony_ci 310e5c31af7Sopenharmony_cistruct CaseDefinition 311e5c31af7Sopenharmony_ci{ 312e5c31af7Sopenharmony_ci int opType; 313e5c31af7Sopenharmony_ci ShaderStageFlags shaderStage; 314e5c31af7Sopenharmony_ci Format format; 315e5c31af7Sopenharmony_ci}; 316e5c31af7Sopenharmony_ci 317e5c31af7Sopenharmony_cistd::string getBodySource(CaseDefinition caseDef) 318e5c31af7Sopenharmony_ci{ 319e5c31af7Sopenharmony_ci std::ostringstream bdy; 320e5c31af7Sopenharmony_ci bdy << " bool tempResult = true;\n"; 321e5c31af7Sopenharmony_ci 322e5c31af7Sopenharmony_ci for (deUint32 i = 1; i <= subgroups::maxSupportedSubgroupSize(); i *= 2) 323e5c31af7Sopenharmony_ci { 324e5c31af7Sopenharmony_ci bdy << " {\n" 325e5c31af7Sopenharmony_ci << " const uint clusterSize = " << i << "u;\n" 326e5c31af7Sopenharmony_ci << " if (clusterSize <= gl_SubgroupSize)\n" 327e5c31af7Sopenharmony_ci << " {\n" 328e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " op = " 329e5c31af7Sopenharmony_ci << getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID], clusterSize);\n" 330e5c31af7Sopenharmony_ci << " for (uint clusterOffset = 0u; clusterOffset < gl_SubgroupSize; clusterOffset += clusterSize)\n" 331e5c31af7Sopenharmony_ci << " {\n" 332e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " ref = " 333e5c31af7Sopenharmony_ci << getIdentity(caseDef.opType, caseDef.format) << ";\n" 334e5c31af7Sopenharmony_ci << " for (uint index = clusterOffset; index < (clusterOffset + clusterSize); index++)\n" 335e5c31af7Sopenharmony_ci << " {\n" 336e5c31af7Sopenharmony_ci << " if (subgroupBallotBitExtract(mask, index))\n" 337e5c31af7Sopenharmony_ci << " {\n" 338e5c31af7Sopenharmony_ci << " ref = " << getOpTypeOperation(caseDef.opType, caseDef.format, "ref", "data[index]") << ";\n" 339e5c31af7Sopenharmony_ci << " }\n" 340e5c31af7Sopenharmony_ci << " }\n" 341e5c31af7Sopenharmony_ci << " if ((clusterOffset <= gl_SubgroupInvocationID) && (gl_SubgroupInvocationID < (clusterOffset + clusterSize)))\n" 342e5c31af7Sopenharmony_ci << " {\n" 343e5c31af7Sopenharmony_ci << " if (!" << getCompare(caseDef.opType, caseDef.format, "ref", "op") << ")\n" 344e5c31af7Sopenharmony_ci << " {\n" 345e5c31af7Sopenharmony_ci << " tempResult = false;\n" 346e5c31af7Sopenharmony_ci << " }\n" 347e5c31af7Sopenharmony_ci << " }\n" 348e5c31af7Sopenharmony_ci << " }\n" 349e5c31af7Sopenharmony_ci << " }\n" 350e5c31af7Sopenharmony_ci << " }\n"; 351e5c31af7Sopenharmony_ci } 352e5c31af7Sopenharmony_ci return bdy.str(); 353e5c31af7Sopenharmony_ci} 354e5c31af7Sopenharmony_ci 355e5c31af7Sopenharmony_civoid initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef) 356e5c31af7Sopenharmony_ci{ 357e5c31af7Sopenharmony_ci subgroups::setFragmentShaderFrameBuffer(programCollection); 358e5c31af7Sopenharmony_ci 359e5c31af7Sopenharmony_ci if (SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage) 360e5c31af7Sopenharmony_ci subgroups::setVertexShaderFrameBuffer(programCollection); 361e5c31af7Sopenharmony_ci 362e5c31af7Sopenharmony_ci std::string bdy = getBodySource(caseDef); 363e5c31af7Sopenharmony_ci 364e5c31af7Sopenharmony_ci if (SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage) 365e5c31af7Sopenharmony_ci { 366e5c31af7Sopenharmony_ci std::ostringstream vertexSrc; 367e5c31af7Sopenharmony_ci vertexSrc << "${VERSION_DECL}\n" 368e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_clustered: enable\n" 369e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_ballot: enable\n" 370e5c31af7Sopenharmony_ci << "layout(location = 0) in highp vec4 in_position;\n" 371e5c31af7Sopenharmony_ci << "layout(location = 0) out float out_color;\n" 372e5c31af7Sopenharmony_ci << "layout(binding = 0, std140) uniform Buffer0\n" 373e5c31af7Sopenharmony_ci << "{\n" 374e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n" 375e5c31af7Sopenharmony_ci << "};\n" 376e5c31af7Sopenharmony_ci << "\n" 377e5c31af7Sopenharmony_ci << "void main (void)\n" 378e5c31af7Sopenharmony_ci << "{\n" 379e5c31af7Sopenharmony_ci << " uvec4 mask = subgroupBallot(true);\n" 380e5c31af7Sopenharmony_ci << bdy 381e5c31af7Sopenharmony_ci << " out_color = float(tempResult ? 1 : 0);\n" 382e5c31af7Sopenharmony_ci << " gl_Position = in_position;\n" 383e5c31af7Sopenharmony_ci << " gl_PointSize = 1.0f;\n" 384e5c31af7Sopenharmony_ci << "}\n"; 385e5c31af7Sopenharmony_ci programCollection.add("vert") << glu::VertexSource(vertexSrc.str()); 386e5c31af7Sopenharmony_ci } 387e5c31af7Sopenharmony_ci else if (SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage) 388e5c31af7Sopenharmony_ci { 389e5c31af7Sopenharmony_ci std::ostringstream geometry; 390e5c31af7Sopenharmony_ci 391e5c31af7Sopenharmony_ci geometry << "${VERSION_DECL}\n" 392e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_clustered: enable\n" 393e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_ballot: enable\n" 394e5c31af7Sopenharmony_ci << "layout(points) in;\n" 395e5c31af7Sopenharmony_ci << "layout(points, max_vertices = 1) out;\n" 396e5c31af7Sopenharmony_ci << "layout(location = 0) out float out_color;\n" 397e5c31af7Sopenharmony_ci << "layout(binding = 0, std140) uniform Buffer0\n" 398e5c31af7Sopenharmony_ci << "{\n" 399e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n" 400e5c31af7Sopenharmony_ci << "};\n" 401e5c31af7Sopenharmony_ci << "\n" 402e5c31af7Sopenharmony_ci << "void main (void)\n" 403e5c31af7Sopenharmony_ci << "{\n" 404e5c31af7Sopenharmony_ci << " uvec4 mask = subgroupBallot(true);\n" 405e5c31af7Sopenharmony_ci << bdy 406e5c31af7Sopenharmony_ci << " out_color = tempResult ? 1.0 : 0.0;\n" 407e5c31af7Sopenharmony_ci << " gl_Position = gl_in[0].gl_Position;\n" 408e5c31af7Sopenharmony_ci << " EmitVertex();\n" 409e5c31af7Sopenharmony_ci << " EndPrimitive();\n" 410e5c31af7Sopenharmony_ci << "}\n"; 411e5c31af7Sopenharmony_ci 412e5c31af7Sopenharmony_ci programCollection.add("geometry") << glu::GeometrySource(geometry.str()); 413e5c31af7Sopenharmony_ci } 414e5c31af7Sopenharmony_ci else if (SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage) 415e5c31af7Sopenharmony_ci { 416e5c31af7Sopenharmony_ci std::ostringstream controlSource; 417e5c31af7Sopenharmony_ci 418e5c31af7Sopenharmony_ci controlSource << "${VERSION_DECL}\n" 419e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_clustered: enable\n" 420e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_ballot: enable\n" 421e5c31af7Sopenharmony_ci << "layout(vertices = 2) out;\n" 422e5c31af7Sopenharmony_ci << "layout(location = 0) out float out_color[];\n" 423e5c31af7Sopenharmony_ci << "layout(binding = 0, std140) uniform Buffer0\n" 424e5c31af7Sopenharmony_ci << "{\n" 425e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n" 426e5c31af7Sopenharmony_ci << "};\n" 427e5c31af7Sopenharmony_ci << "\n" 428e5c31af7Sopenharmony_ci << "void main (void)\n" 429e5c31af7Sopenharmony_ci << "{\n" 430e5c31af7Sopenharmony_ci << " if (gl_InvocationID == 0)\n" 431e5c31af7Sopenharmony_ci <<" {\n" 432e5c31af7Sopenharmony_ci << " gl_TessLevelOuter[0] = 1.0f;\n" 433e5c31af7Sopenharmony_ci << " gl_TessLevelOuter[1] = 1.0f;\n" 434e5c31af7Sopenharmony_ci << " }\n" 435e5c31af7Sopenharmony_ci << " uvec4 mask = subgroupBallot(true);\n" 436e5c31af7Sopenharmony_ci << bdy 437e5c31af7Sopenharmony_ci << " out_color[gl_InvocationID] = tempResult ? 1.0 : 0.0;\n" 438e5c31af7Sopenharmony_ci << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 439e5c31af7Sopenharmony_ci << "}\n"; 440e5c31af7Sopenharmony_ci 441e5c31af7Sopenharmony_ci programCollection.add("tesc") << glu::TessellationControlSource(controlSource.str()); 442e5c31af7Sopenharmony_ci subgroups::setTesEvalShaderFrameBuffer(programCollection); 443e5c31af7Sopenharmony_ci } 444e5c31af7Sopenharmony_ci else if (SHADER_STAGE_TESS_EVALUATION_BIT == caseDef.shaderStage) 445e5c31af7Sopenharmony_ci { 446e5c31af7Sopenharmony_ci std::ostringstream evaluationSource; 447e5c31af7Sopenharmony_ci 448e5c31af7Sopenharmony_ci evaluationSource << "${VERSION_DECL}\n" 449e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_clustered: enable\n" 450e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_ballot: enable\n" 451e5c31af7Sopenharmony_ci << "layout(isolines, equal_spacing, ccw ) in;\n" 452e5c31af7Sopenharmony_ci << "layout(location = 0) out float out_color;\n" 453e5c31af7Sopenharmony_ci << "layout(binding = 0, std140) uniform Buffer0\n" 454e5c31af7Sopenharmony_ci << "{\n" 455e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n" 456e5c31af7Sopenharmony_ci << "};\n" 457e5c31af7Sopenharmony_ci << "\n" 458e5c31af7Sopenharmony_ci << "void main (void)\n" 459e5c31af7Sopenharmony_ci << "{\n" 460e5c31af7Sopenharmony_ci << " uvec4 mask = subgroupBallot(true);\n" 461e5c31af7Sopenharmony_ci << bdy 462e5c31af7Sopenharmony_ci << " out_color = tempResult ? 1.0 : 0.0;\n" 463e5c31af7Sopenharmony_ci << " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n" 464e5c31af7Sopenharmony_ci << "}\n"; 465e5c31af7Sopenharmony_ci 466e5c31af7Sopenharmony_ci subgroups::setTesCtrlShaderFrameBuffer(programCollection); 467e5c31af7Sopenharmony_ci programCollection.add("tese") << glu::TessellationEvaluationSource(evaluationSource.str()); 468e5c31af7Sopenharmony_ci } 469e5c31af7Sopenharmony_ci else 470e5c31af7Sopenharmony_ci { 471e5c31af7Sopenharmony_ci DE_FATAL("Unsupported shader stage"); 472e5c31af7Sopenharmony_ci } 473e5c31af7Sopenharmony_ci} 474e5c31af7Sopenharmony_ci 475e5c31af7Sopenharmony_civoid initPrograms(SourceCollections& programCollection, CaseDefinition caseDef) 476e5c31af7Sopenharmony_ci{ 477e5c31af7Sopenharmony_ci std::string bdy = getBodySource(caseDef); 478e5c31af7Sopenharmony_ci 479e5c31af7Sopenharmony_ci if (SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage) 480e5c31af7Sopenharmony_ci { 481e5c31af7Sopenharmony_ci std::ostringstream src; 482e5c31af7Sopenharmony_ci 483e5c31af7Sopenharmony_ci src << "${VERSION_DECL}\n" 484e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_clustered: enable\n" 485e5c31af7Sopenharmony_ci << "#extension GL_KHR_shader_subgroup_ballot: enable\n" 486e5c31af7Sopenharmony_ci << "layout (${LOCAL_SIZE_X}, ${LOCAL_SIZE_Y}, ${LOCAL_SIZE_Z}) in;\n" 487e5c31af7Sopenharmony_ci << "layout(binding = 0, std430) buffer Buffer0\n" 488e5c31af7Sopenharmony_ci << "{\n" 489e5c31af7Sopenharmony_ci << " uint result[];\n" 490e5c31af7Sopenharmony_ci << "};\n" 491e5c31af7Sopenharmony_ci << "layout(binding = 1, std430) buffer Buffer1\n" 492e5c31af7Sopenharmony_ci << "{\n" 493e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[];\n" 494e5c31af7Sopenharmony_ci << "};\n" 495e5c31af7Sopenharmony_ci << "\n" 496e5c31af7Sopenharmony_ci << "void main (void)\n" 497e5c31af7Sopenharmony_ci << "{\n" 498e5c31af7Sopenharmony_ci << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n" 499e5c31af7Sopenharmony_ci << " highp uint offset = globalSize.x * ((globalSize.y * " 500e5c31af7Sopenharmony_ci "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + " 501e5c31af7Sopenharmony_ci "gl_GlobalInvocationID.x;\n" 502e5c31af7Sopenharmony_ci << " uvec4 mask = subgroupBallot(true);\n" 503e5c31af7Sopenharmony_ci << bdy 504e5c31af7Sopenharmony_ci << " result[offset] = tempResult ? 1u : 0u;\n" 505e5c31af7Sopenharmony_ci << "}\n"; 506e5c31af7Sopenharmony_ci 507e5c31af7Sopenharmony_ci programCollection.add("comp") << glu::ComputeSource(src.str()); 508e5c31af7Sopenharmony_ci } 509e5c31af7Sopenharmony_ci else 510e5c31af7Sopenharmony_ci { 511e5c31af7Sopenharmony_ci { 512e5c31af7Sopenharmony_ci const string vertex = 513e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 514e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_clustered: enable\n" 515e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 516e5c31af7Sopenharmony_ci "layout(binding = 0, std430) buffer Buffer0\n" 517e5c31af7Sopenharmony_ci "{\n" 518e5c31af7Sopenharmony_ci " uint result[];\n" 519e5c31af7Sopenharmony_ci "} b0;\n" 520e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 521e5c31af7Sopenharmony_ci "{\n" 522e5c31af7Sopenharmony_ci " " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n" 523e5c31af7Sopenharmony_ci "};\n" 524e5c31af7Sopenharmony_ci "\n" 525e5c31af7Sopenharmony_ci "void main (void)\n" 526e5c31af7Sopenharmony_ci "{\n" 527e5c31af7Sopenharmony_ci " uvec4 mask = subgroupBallot(true);\n" 528e5c31af7Sopenharmony_ci + bdy + 529e5c31af7Sopenharmony_ci " b0.result[gl_VertexID] = tempResult ? 1u : 0u;\n" 530e5c31af7Sopenharmony_ci " float pixelSize = 2.0f/1024.0f;\n" 531e5c31af7Sopenharmony_ci " float pixelPosition = pixelSize/2.0f - 1.0f;\n" 532e5c31af7Sopenharmony_ci " gl_Position = vec4(float(gl_VertexID) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n" 533e5c31af7Sopenharmony_ci "}\n"; 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_ci programCollection.add("vert") << glu::VertexSource(vertex); 536e5c31af7Sopenharmony_ci } 537e5c31af7Sopenharmony_ci 538e5c31af7Sopenharmony_ci { 539e5c31af7Sopenharmony_ci const string tesc = 540e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 541e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_clustered: enable\n" 542e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 543e5c31af7Sopenharmony_ci "layout(vertices=1) out;\n" 544e5c31af7Sopenharmony_ci "layout(binding = 1, std430) buffer Buffer1\n" 545e5c31af7Sopenharmony_ci "{\n" 546e5c31af7Sopenharmony_ci " uint result[];\n" 547e5c31af7Sopenharmony_ci "} b1;\n" 548e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 549e5c31af7Sopenharmony_ci "{\n" 550e5c31af7Sopenharmony_ci " " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n" 551e5c31af7Sopenharmony_ci "};\n" 552e5c31af7Sopenharmony_ci "\n" 553e5c31af7Sopenharmony_ci "void main (void)\n" 554e5c31af7Sopenharmony_ci "{\n" 555e5c31af7Sopenharmony_ci " uvec4 mask = subgroupBallot(true);\n" 556e5c31af7Sopenharmony_ci + bdy + 557e5c31af7Sopenharmony_ci " b1.result[gl_PrimitiveID] = tempResult ? 1u : 0u;\n" 558e5c31af7Sopenharmony_ci " if (gl_InvocationID == 0)\n" 559e5c31af7Sopenharmony_ci " {\n" 560e5c31af7Sopenharmony_ci " gl_TessLevelOuter[0] = 1.0f;\n" 561e5c31af7Sopenharmony_ci " gl_TessLevelOuter[1] = 1.0f;\n" 562e5c31af7Sopenharmony_ci " }\n" 563e5c31af7Sopenharmony_ci " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 564e5c31af7Sopenharmony_ci "}\n"; 565e5c31af7Sopenharmony_ci 566e5c31af7Sopenharmony_ci programCollection.add("tesc") << glu::TessellationControlSource(tesc); 567e5c31af7Sopenharmony_ci } 568e5c31af7Sopenharmony_ci 569e5c31af7Sopenharmony_ci { 570e5c31af7Sopenharmony_ci const string tese = 571e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 572e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_clustered: enable\n" 573e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 574e5c31af7Sopenharmony_ci "layout(isolines) in;\n" 575e5c31af7Sopenharmony_ci "layout(binding = 2, std430) buffer Buffer2\n" 576e5c31af7Sopenharmony_ci "{\n" 577e5c31af7Sopenharmony_ci " uint result[];\n" 578e5c31af7Sopenharmony_ci "} b2;\n" 579e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 580e5c31af7Sopenharmony_ci "{\n" 581e5c31af7Sopenharmony_ci " " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n" 582e5c31af7Sopenharmony_ci "};\n" 583e5c31af7Sopenharmony_ci "\n" 584e5c31af7Sopenharmony_ci "void main (void)\n" 585e5c31af7Sopenharmony_ci "{\n" 586e5c31af7Sopenharmony_ci " uvec4 mask = subgroupBallot(true);\n" 587e5c31af7Sopenharmony_ci + bdy + 588e5c31af7Sopenharmony_ci " b2.result[gl_PrimitiveID * 2 + int(gl_TessCoord.x + 0.5)] = tempResult ? 1u : 0u;\n" 589e5c31af7Sopenharmony_ci " float pixelSize = 2.0f/1024.0f;\n" 590e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n" 591e5c31af7Sopenharmony_ci "}\n"; 592e5c31af7Sopenharmony_ci programCollection.add("tese") << glu::TessellationEvaluationSource(tese); 593e5c31af7Sopenharmony_ci } 594e5c31af7Sopenharmony_ci 595e5c31af7Sopenharmony_ci { 596e5c31af7Sopenharmony_ci const string geometry = 597e5c31af7Sopenharmony_ci // version string added by addGeometryShadersFromTemplate 598e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_clustered: enable\n" 599e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 600e5c31af7Sopenharmony_ci "layout(${TOPOLOGY}) in;\n" 601e5c31af7Sopenharmony_ci "layout(points, max_vertices = 1) out;\n" 602e5c31af7Sopenharmony_ci "layout(binding = 3, std430) buffer Buffer3\n" 603e5c31af7Sopenharmony_ci "{\n" 604e5c31af7Sopenharmony_ci " uint result[];\n" 605e5c31af7Sopenharmony_ci "} b3;\n" 606e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 607e5c31af7Sopenharmony_ci "{\n" 608e5c31af7Sopenharmony_ci " " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n" 609e5c31af7Sopenharmony_ci "};\n" 610e5c31af7Sopenharmony_ci "\n" 611e5c31af7Sopenharmony_ci "void main (void)\n" 612e5c31af7Sopenharmony_ci "{\n" 613e5c31af7Sopenharmony_ci " uvec4 mask = subgroupBallot(true);\n" 614e5c31af7Sopenharmony_ci + bdy + 615e5c31af7Sopenharmony_ci " b3.result[gl_PrimitiveIDIn] = tempResult ? 1u : 0u;\n" 616e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 617e5c31af7Sopenharmony_ci " EmitVertex();\n" 618e5c31af7Sopenharmony_ci " EndPrimitive();\n" 619e5c31af7Sopenharmony_ci "}\n"; 620e5c31af7Sopenharmony_ci subgroups::addGeometryShadersFromTemplate(geometry, programCollection); 621e5c31af7Sopenharmony_ci } 622e5c31af7Sopenharmony_ci 623e5c31af7Sopenharmony_ci { 624e5c31af7Sopenharmony_ci const string fragment = 625e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 626e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_clustered: enable\n" 627e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 628e5c31af7Sopenharmony_ci "precision highp int;\n" 629e5c31af7Sopenharmony_ci "precision highp float;\n" 630e5c31af7Sopenharmony_ci "layout(location = 0) out uint result;\n" 631e5c31af7Sopenharmony_ci "layout(binding = 4, std430) readonly buffer Buffer4\n" 632e5c31af7Sopenharmony_ci "{\n" 633e5c31af7Sopenharmony_ci " " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n" 634e5c31af7Sopenharmony_ci "};\n" 635e5c31af7Sopenharmony_ci "void main (void)\n" 636e5c31af7Sopenharmony_ci "{\n" 637e5c31af7Sopenharmony_ci " uvec4 mask = subgroupBallot(true);\n" 638e5c31af7Sopenharmony_ci + bdy + 639e5c31af7Sopenharmony_ci " result = tempResult ? 1u : 0u;\n" 640e5c31af7Sopenharmony_ci "}\n"; 641e5c31af7Sopenharmony_ci programCollection.add("fragment") << glu::FragmentSource(fragment); 642e5c31af7Sopenharmony_ci } 643e5c31af7Sopenharmony_ci 644e5c31af7Sopenharmony_ci subgroups::addNoSubgroupShader(programCollection); 645e5c31af7Sopenharmony_ci } 646e5c31af7Sopenharmony_ci} 647e5c31af7Sopenharmony_ci 648e5c31af7Sopenharmony_civoid supportedCheck (Context& context, CaseDefinition caseDef) 649e5c31af7Sopenharmony_ci{ 650e5c31af7Sopenharmony_ci if (!subgroups::isSubgroupSupported(context)) 651e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Subgroup operations are not supported"); 652e5c31af7Sopenharmony_ci 653e5c31af7Sopenharmony_ci if (!subgroups::isSubgroupFeatureSupportedForDevice(context, SUBGROUP_FEATURE_CLUSTERED_BIT)) 654e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support subgroup clustered operations"); 655e5c31af7Sopenharmony_ci 656e5c31af7Sopenharmony_ci if (subgroups::isDoubleFormat(caseDef.format) && 657e5c31af7Sopenharmony_ci !subgroups::isDoubleSupportedForDevice(context)) 658e5c31af7Sopenharmony_ci { 659e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support subgroup double operations"); 660e5c31af7Sopenharmony_ci } 661e5c31af7Sopenharmony_ci} 662e5c31af7Sopenharmony_ci 663e5c31af7Sopenharmony_citcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef) 664e5c31af7Sopenharmony_ci{ 665e5c31af7Sopenharmony_ci if (!subgroups::areSubgroupOperationsSupportedForStage( 666e5c31af7Sopenharmony_ci context, caseDef.shaderStage)) 667e5c31af7Sopenharmony_ci { 668e5c31af7Sopenharmony_ci if (subgroups::areSubgroupOperationsRequiredForStage( 669e5c31af7Sopenharmony_ci caseDef.shaderStage)) 670e5c31af7Sopenharmony_ci { 671e5c31af7Sopenharmony_ci return tcu::TestStatus::fail( 672e5c31af7Sopenharmony_ci "Shader stage " + 673e5c31af7Sopenharmony_ci subgroups::getShaderStageName(caseDef.shaderStage) + 674e5c31af7Sopenharmony_ci " is required to support subgroup operations!"); 675e5c31af7Sopenharmony_ci } 676e5c31af7Sopenharmony_ci else 677e5c31af7Sopenharmony_ci { 678e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage"); 679e5c31af7Sopenharmony_ci } 680e5c31af7Sopenharmony_ci } 681e5c31af7Sopenharmony_ci 682e5c31af7Sopenharmony_ci subgroups::SSBOData inputData; 683e5c31af7Sopenharmony_ci inputData.format = caseDef.format; 684e5c31af7Sopenharmony_ci inputData.layout = subgroups::SSBOData::LayoutStd140; 685e5c31af7Sopenharmony_ci inputData.numElements = subgroups::maxSupportedSubgroupSize(); 686e5c31af7Sopenharmony_ci inputData.initializeType = subgroups::SSBOData::InitializeNonZero; 687e5c31af7Sopenharmony_ci inputData.binding = 0u; 688e5c31af7Sopenharmony_ci 689e5c31af7Sopenharmony_ci if (SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage) 690e5c31af7Sopenharmony_ci return subgroups::makeVertexFrameBufferTest(context, FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages); 691e5c31af7Sopenharmony_ci else if (SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage) 692e5c31af7Sopenharmony_ci return subgroups::makeGeometryFrameBufferTest(context, FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages); 693e5c31af7Sopenharmony_ci else if (SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage) 694e5c31af7Sopenharmony_ci return subgroups::makeTessellationEvaluationFrameBufferTest(context, FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, SHADER_STAGE_TESS_CONTROL_BIT); 695e5c31af7Sopenharmony_ci else if (SHADER_STAGE_TESS_EVALUATION_BIT == caseDef.shaderStage) 696e5c31af7Sopenharmony_ci return subgroups::makeTessellationEvaluationFrameBufferTest(context, FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, SHADER_STAGE_TESS_EVALUATION_BIT); 697e5c31af7Sopenharmony_ci else 698e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Unhandled shader stage"); 699e5c31af7Sopenharmony_ci} 700e5c31af7Sopenharmony_ci 701e5c31af7Sopenharmony_citcu::TestStatus test(Context& context, const CaseDefinition caseDef) 702e5c31af7Sopenharmony_ci{ 703e5c31af7Sopenharmony_ci if (SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage) 704e5c31af7Sopenharmony_ci { 705e5c31af7Sopenharmony_ci if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage)) 706e5c31af7Sopenharmony_ci { 707e5c31af7Sopenharmony_ci return tcu::TestStatus::fail( 708e5c31af7Sopenharmony_ci "Shader stage " + 709e5c31af7Sopenharmony_ci subgroups::getShaderStageName(caseDef.shaderStage) + 710e5c31af7Sopenharmony_ci " is required to support subgroup operations!"); 711e5c31af7Sopenharmony_ci } 712e5c31af7Sopenharmony_ci subgroups::SSBOData inputData; 713e5c31af7Sopenharmony_ci inputData.format = caseDef.format; 714e5c31af7Sopenharmony_ci inputData.layout = subgroups::SSBOData::LayoutStd430; 715e5c31af7Sopenharmony_ci inputData.numElements = subgroups::maxSupportedSubgroupSize(); 716e5c31af7Sopenharmony_ci inputData.initializeType = subgroups::SSBOData::InitializeNonZero; 717e5c31af7Sopenharmony_ci inputData.binding = 1u; 718e5c31af7Sopenharmony_ci 719e5c31af7Sopenharmony_ci return subgroups::makeComputeTest(context, FORMAT_R32_UINT, &inputData, 1, checkComputeStage); 720e5c31af7Sopenharmony_ci } 721e5c31af7Sopenharmony_ci else 722e5c31af7Sopenharmony_ci { 723e5c31af7Sopenharmony_ci int supportedStages = context.getDeqpContext().getContextInfo().getInt(GL_SUBGROUP_SUPPORTED_STAGES_KHR); 724e5c31af7Sopenharmony_ci 725e5c31af7Sopenharmony_ci ShaderStageFlags stages = (ShaderStageFlags)(caseDef.shaderStage & supportedStages); 726e5c31af7Sopenharmony_ci 727e5c31af7Sopenharmony_ci if (SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context)) 728e5c31af7Sopenharmony_ci { 729e5c31af7Sopenharmony_ci if ( (stages & SHADER_STAGE_FRAGMENT_BIT) == 0) 730e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes"); 731e5c31af7Sopenharmony_ci else 732e5c31af7Sopenharmony_ci stages = SHADER_STAGE_FRAGMENT_BIT; 733e5c31af7Sopenharmony_ci } 734e5c31af7Sopenharmony_ci 735e5c31af7Sopenharmony_ci if ((ShaderStageFlags)0u == stages) 736e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Subgroup operations are not supported for any graphic shader"); 737e5c31af7Sopenharmony_ci 738e5c31af7Sopenharmony_ci subgroups::SSBOData inputData; 739e5c31af7Sopenharmony_ci inputData.format = caseDef.format; 740e5c31af7Sopenharmony_ci inputData.layout = subgroups::SSBOData::LayoutStd430; 741e5c31af7Sopenharmony_ci inputData.numElements = subgroups::maxSupportedSubgroupSize(); 742e5c31af7Sopenharmony_ci inputData.initializeType = subgroups::SSBOData::InitializeNonZero; 743e5c31af7Sopenharmony_ci inputData.binding = 4u; 744e5c31af7Sopenharmony_ci inputData.stages = stages; 745e5c31af7Sopenharmony_ci 746e5c31af7Sopenharmony_ci return subgroups::allStages(context, FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, stages); 747e5c31af7Sopenharmony_ci } 748e5c31af7Sopenharmony_ci} 749e5c31af7Sopenharmony_ci} 750e5c31af7Sopenharmony_ci 751e5c31af7Sopenharmony_cideqp::TestCaseGroup* createSubgroupsClusteredTests(deqp::Context& testCtx) 752e5c31af7Sopenharmony_ci{ 753e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> graphicGroup(new deqp::TestCaseGroup( 754e5c31af7Sopenharmony_ci testCtx, "graphics", "Subgroup clustered category tests: graphics")); 755e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> computeGroup(new deqp::TestCaseGroup( 756e5c31af7Sopenharmony_ci testCtx, "compute", "Subgroup clustered category tests: compute")); 757e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> framebufferGroup(new deqp::TestCaseGroup( 758e5c31af7Sopenharmony_ci testCtx, "framebuffer", "Subgroup clustered category tests: framebuffer")); 759e5c31af7Sopenharmony_ci 760e5c31af7Sopenharmony_ci const ShaderStageFlags stages[] = 761e5c31af7Sopenharmony_ci { 762e5c31af7Sopenharmony_ci SHADER_STAGE_VERTEX_BIT, 763e5c31af7Sopenharmony_ci SHADER_STAGE_TESS_EVALUATION_BIT, 764e5c31af7Sopenharmony_ci SHADER_STAGE_TESS_CONTROL_BIT, 765e5c31af7Sopenharmony_ci SHADER_STAGE_GEOMETRY_BIT 766e5c31af7Sopenharmony_ci }; 767e5c31af7Sopenharmony_ci 768e5c31af7Sopenharmony_ci const Format formats[] = 769e5c31af7Sopenharmony_ci { 770e5c31af7Sopenharmony_ci FORMAT_R32_SINT, FORMAT_R32G32_SINT, FORMAT_R32G32B32_SINT, 771e5c31af7Sopenharmony_ci FORMAT_R32G32B32A32_SINT, FORMAT_R32_UINT, FORMAT_R32G32_UINT, 772e5c31af7Sopenharmony_ci FORMAT_R32G32B32_UINT, FORMAT_R32G32B32A32_UINT, 773e5c31af7Sopenharmony_ci FORMAT_R32_SFLOAT, FORMAT_R32G32_SFLOAT, 774e5c31af7Sopenharmony_ci FORMAT_R32G32B32_SFLOAT, FORMAT_R32G32B32A32_SFLOAT, 775e5c31af7Sopenharmony_ci FORMAT_R64_SFLOAT, FORMAT_R64G64_SFLOAT, 776e5c31af7Sopenharmony_ci FORMAT_R64G64B64_SFLOAT, FORMAT_R64G64B64A64_SFLOAT, 777e5c31af7Sopenharmony_ci FORMAT_R32_BOOL, FORMAT_R32G32_BOOL, 778e5c31af7Sopenharmony_ci FORMAT_R32G32B32_BOOL, FORMAT_R32G32B32A32_BOOL, 779e5c31af7Sopenharmony_ci }; 780e5c31af7Sopenharmony_ci 781e5c31af7Sopenharmony_ci for (int formatIndex = 0; formatIndex < DE_LENGTH_OF_ARRAY(formats); ++formatIndex) 782e5c31af7Sopenharmony_ci { 783e5c31af7Sopenharmony_ci const Format format = formats[formatIndex]; 784e5c31af7Sopenharmony_ci 785e5c31af7Sopenharmony_ci for (int opTypeIndex = 0; opTypeIndex < OPTYPE_CLUSTERED_LAST; ++opTypeIndex) 786e5c31af7Sopenharmony_ci { 787e5c31af7Sopenharmony_ci bool isBool = false; 788e5c31af7Sopenharmony_ci bool isFloat = false; 789e5c31af7Sopenharmony_ci 790e5c31af7Sopenharmony_ci switch (format) 791e5c31af7Sopenharmony_ci { 792e5c31af7Sopenharmony_ci default: 793e5c31af7Sopenharmony_ci break; 794e5c31af7Sopenharmony_ci case FORMAT_R32_SFLOAT: 795e5c31af7Sopenharmony_ci case FORMAT_R32G32_SFLOAT: 796e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_SFLOAT: 797e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_SFLOAT: 798e5c31af7Sopenharmony_ci case FORMAT_R64_SFLOAT: 799e5c31af7Sopenharmony_ci case FORMAT_R64G64_SFLOAT: 800e5c31af7Sopenharmony_ci case FORMAT_R64G64B64_SFLOAT: 801e5c31af7Sopenharmony_ci case FORMAT_R64G64B64A64_SFLOAT: 802e5c31af7Sopenharmony_ci isFloat = true; 803e5c31af7Sopenharmony_ci break; 804e5c31af7Sopenharmony_ci case FORMAT_R32_BOOL: 805e5c31af7Sopenharmony_ci case FORMAT_R32G32_BOOL: 806e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_BOOL: 807e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_BOOL: 808e5c31af7Sopenharmony_ci isBool = true; 809e5c31af7Sopenharmony_ci break; 810e5c31af7Sopenharmony_ci } 811e5c31af7Sopenharmony_ci 812e5c31af7Sopenharmony_ci bool isBitwiseOp = false; 813e5c31af7Sopenharmony_ci 814e5c31af7Sopenharmony_ci switch (opTypeIndex) 815e5c31af7Sopenharmony_ci { 816e5c31af7Sopenharmony_ci default: 817e5c31af7Sopenharmony_ci break; 818e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_AND: 819e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_OR: 820e5c31af7Sopenharmony_ci case OPTYPE_CLUSTERED_XOR: 821e5c31af7Sopenharmony_ci isBitwiseOp = true; 822e5c31af7Sopenharmony_ci break; 823e5c31af7Sopenharmony_ci } 824e5c31af7Sopenharmony_ci 825e5c31af7Sopenharmony_ci if (isFloat && isBitwiseOp) 826e5c31af7Sopenharmony_ci { 827e5c31af7Sopenharmony_ci // Skip float with bitwise category. 828e5c31af7Sopenharmony_ci continue; 829e5c31af7Sopenharmony_ci } 830e5c31af7Sopenharmony_ci 831e5c31af7Sopenharmony_ci if (isBool && !isBitwiseOp) 832e5c31af7Sopenharmony_ci { 833e5c31af7Sopenharmony_ci // Skip bool when its not the bitwise category. 834e5c31af7Sopenharmony_ci continue; 835e5c31af7Sopenharmony_ci } 836e5c31af7Sopenharmony_ci 837e5c31af7Sopenharmony_ci const std::string name = de::toLower(getOpTypeName(opTypeIndex)) 838e5c31af7Sopenharmony_ci +"_" + subgroups::getFormatNameForGLSL(format); 839e5c31af7Sopenharmony_ci 840e5c31af7Sopenharmony_ci { 841e5c31af7Sopenharmony_ci const CaseDefinition caseDef = {opTypeIndex, SHADER_STAGE_COMPUTE_BIT, format}; 842e5c31af7Sopenharmony_ci SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(computeGroup.get(), name, "", supportedCheck, initPrograms, test, caseDef); 843e5c31af7Sopenharmony_ci } 844e5c31af7Sopenharmony_ci 845e5c31af7Sopenharmony_ci { 846e5c31af7Sopenharmony_ci const CaseDefinition caseDef = {opTypeIndex, SHADER_STAGE_ALL_GRAPHICS, format}; 847e5c31af7Sopenharmony_ci SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(graphicGroup.get(), name, 848e5c31af7Sopenharmony_ci "", supportedCheck, initPrograms, test, caseDef); 849e5c31af7Sopenharmony_ci } 850e5c31af7Sopenharmony_ci 851e5c31af7Sopenharmony_ci for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex) 852e5c31af7Sopenharmony_ci { 853e5c31af7Sopenharmony_ci const CaseDefinition caseDef = {opTypeIndex, stages[stageIndex], format}; 854e5c31af7Sopenharmony_ci SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(framebufferGroup.get(), name +"_" + getShaderStageName(caseDef.shaderStage), "", 855e5c31af7Sopenharmony_ci supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef); 856e5c31af7Sopenharmony_ci } 857e5c31af7Sopenharmony_ci } 858e5c31af7Sopenharmony_ci } 859e5c31af7Sopenharmony_ci de::MovePtr<deqp::TestCaseGroup> group(new deqp::TestCaseGroup( 860e5c31af7Sopenharmony_ci testCtx, "clustered", "Subgroup clustered category tests")); 861e5c31af7Sopenharmony_ci 862e5c31af7Sopenharmony_ci group->addChild(graphicGroup.release()); 863e5c31af7Sopenharmony_ci group->addChild(computeGroup.release()); 864e5c31af7Sopenharmony_ci group->addChild(framebufferGroup.release()); 865e5c31af7Sopenharmony_ci 866e5c31af7Sopenharmony_ci return group.release(); 867e5c31af7Sopenharmony_ci} 868e5c31af7Sopenharmony_ci 869e5c31af7Sopenharmony_ci} // subgroups 870e5c31af7Sopenharmony_ci} // glc 871