1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------ 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2019 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * Copyright (c) 2019 Google Inc. 7e5c31af7Sopenharmony_ci * Copyright (c) 2017 Codeplay Software Ltd. 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 "vktSubgroupsVoteTests.hpp" 27e5c31af7Sopenharmony_ci#include "vktSubgroupsTestsUtils.hpp" 28e5c31af7Sopenharmony_ci 29e5c31af7Sopenharmony_ci#include <string> 30e5c31af7Sopenharmony_ci#include <vector> 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ciusing namespace tcu; 33e5c31af7Sopenharmony_ciusing namespace std; 34e5c31af7Sopenharmony_ciusing namespace vk; 35e5c31af7Sopenharmony_ciusing namespace vkt; 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_cinamespace 38e5c31af7Sopenharmony_ci{ 39e5c31af7Sopenharmony_cienum OpType 40e5c31af7Sopenharmony_ci{ 41e5c31af7Sopenharmony_ci OPTYPE_ALL = 0, 42e5c31af7Sopenharmony_ci OPTYPE_ANY = 1, 43e5c31af7Sopenharmony_ci OPTYPE_ALLEQUAL = 2, 44e5c31af7Sopenharmony_ci OPTYPE_LAST_NON_ARB = 3, 45e5c31af7Sopenharmony_ci OPTYPE_ALL_ARB = 4, 46e5c31af7Sopenharmony_ci OPTYPE_ANY_ARB = 5, 47e5c31af7Sopenharmony_ci OPTYPE_ALLEQUAL_ARB = 6, 48e5c31af7Sopenharmony_ci OPTYPE_LAST 49e5c31af7Sopenharmony_ci}; 50e5c31af7Sopenharmony_ci 51e5c31af7Sopenharmony_cistruct CaseDefinition 52e5c31af7Sopenharmony_ci{ 53e5c31af7Sopenharmony_ci OpType opType; 54e5c31af7Sopenharmony_ci VkShaderStageFlags shaderStage; 55e5c31af7Sopenharmony_ci VkFormat format; 56e5c31af7Sopenharmony_ci de::SharedPtr<bool> geometryPointSizeSupported; 57e5c31af7Sopenharmony_ci deBool requiredSubgroupSize; 58e5c31af7Sopenharmony_ci deBool requires8BitUniformBuffer; 59e5c31af7Sopenharmony_ci deBool requires16BitUniformBuffer; 60e5c31af7Sopenharmony_ci}; 61e5c31af7Sopenharmony_ci 62e5c31af7Sopenharmony_cistatic bool checkVertexPipelineStages (const void* internalData, 63e5c31af7Sopenharmony_ci vector<const void*> datas, 64e5c31af7Sopenharmony_ci deUint32 width, 65e5c31af7Sopenharmony_ci deUint32) 66e5c31af7Sopenharmony_ci{ 67e5c31af7Sopenharmony_ci DE_UNREF(internalData); 68e5c31af7Sopenharmony_ci 69e5c31af7Sopenharmony_ci return subgroups::check(datas, width, 0x1F); 70e5c31af7Sopenharmony_ci} 71e5c31af7Sopenharmony_ci 72e5c31af7Sopenharmony_cistatic bool checkFragmentPipelineStages (const void* internalData, 73e5c31af7Sopenharmony_ci vector<const void*> datas, 74e5c31af7Sopenharmony_ci deUint32 width, 75e5c31af7Sopenharmony_ci deUint32 height, 76e5c31af7Sopenharmony_ci deUint32) 77e5c31af7Sopenharmony_ci{ 78e5c31af7Sopenharmony_ci DE_UNREF(internalData); 79e5c31af7Sopenharmony_ci 80e5c31af7Sopenharmony_ci const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]); 81e5c31af7Sopenharmony_ci 82e5c31af7Sopenharmony_ci for (deUint32 x = 0u; x < width; ++x) 83e5c31af7Sopenharmony_ci { 84e5c31af7Sopenharmony_ci for (deUint32 y = 0u; y < height; ++y) 85e5c31af7Sopenharmony_ci { 86e5c31af7Sopenharmony_ci const deUint32 ndx = (x * height + y); 87e5c31af7Sopenharmony_ci const deUint32 val = data[ndx] & 0x1F; 88e5c31af7Sopenharmony_ci 89e5c31af7Sopenharmony_ci if (data[ndx] & 0x40) //Helper fragment shader invocation was executed 90e5c31af7Sopenharmony_ci { 91e5c31af7Sopenharmony_ci if(val != 0x1F) 92e5c31af7Sopenharmony_ci return false; 93e5c31af7Sopenharmony_ci } 94e5c31af7Sopenharmony_ci else //Helper fragment shader invocation was not executed yet 95e5c31af7Sopenharmony_ci { 96e5c31af7Sopenharmony_ci if (val != 0x1E) 97e5c31af7Sopenharmony_ci return false; 98e5c31af7Sopenharmony_ci } 99e5c31af7Sopenharmony_ci } 100e5c31af7Sopenharmony_ci } 101e5c31af7Sopenharmony_ci 102e5c31af7Sopenharmony_ci return true; 103e5c31af7Sopenharmony_ci} 104e5c31af7Sopenharmony_ci 105e5c31af7Sopenharmony_cistatic bool checkComputeOrMesh (const void* internalData, 106e5c31af7Sopenharmony_ci vector<const void*> datas, 107e5c31af7Sopenharmony_ci const deUint32 numWorkgroups[3], 108e5c31af7Sopenharmony_ci const deUint32 localSize[3], 109e5c31af7Sopenharmony_ci deUint32) 110e5c31af7Sopenharmony_ci{ 111e5c31af7Sopenharmony_ci DE_UNREF(internalData); 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ci return subgroups::checkComputeOrMesh(datas, numWorkgroups, localSize, 0x1F); 114e5c31af7Sopenharmony_ci} 115e5c31af7Sopenharmony_ci 116e5c31af7Sopenharmony_cistring getOpTypeName (int opType) 117e5c31af7Sopenharmony_ci{ 118e5c31af7Sopenharmony_ci switch (opType) 119e5c31af7Sopenharmony_ci { 120e5c31af7Sopenharmony_ci case OPTYPE_ALL: return "subgroupAll"; 121e5c31af7Sopenharmony_ci case OPTYPE_ANY: return "subgroupAny"; 122e5c31af7Sopenharmony_ci case OPTYPE_ALLEQUAL: return "subgroupAllEqual"; 123e5c31af7Sopenharmony_ci case OPTYPE_ALL_ARB: return "allInvocationsARB"; 124e5c31af7Sopenharmony_ci case OPTYPE_ANY_ARB: return "anyInvocationARB"; 125e5c31af7Sopenharmony_ci case OPTYPE_ALLEQUAL_ARB: return "allInvocationsEqualARB"; 126e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Unsupported op type"); 127e5c31af7Sopenharmony_ci } 128e5c31af7Sopenharmony_ci} 129e5c31af7Sopenharmony_ci 130e5c31af7Sopenharmony_cibool fmtIsBoolean (VkFormat format) 131e5c31af7Sopenharmony_ci{ 132e5c31af7Sopenharmony_ci // For reasons unknown, the tests use R8_USCALED as the boolean format 133e5c31af7Sopenharmony_ci return format == VK_FORMAT_R8_USCALED || format == VK_FORMAT_R8G8_USCALED || 134e5c31af7Sopenharmony_ci format == VK_FORMAT_R8G8B8_USCALED || format == VK_FORMAT_R8G8B8A8_USCALED; 135e5c31af7Sopenharmony_ci} 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_ciconst string getExtensions (bool arbFunctions) 138e5c31af7Sopenharmony_ci{ 139e5c31af7Sopenharmony_ci return arbFunctions ? "#extension GL_ARB_shader_group_vote: enable\n" 140e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_basic: enable\n" 141e5c31af7Sopenharmony_ci : "#extension GL_KHR_shader_subgroup_vote: enable\n"; 142e5c31af7Sopenharmony_ci} 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_ciconst string getStageTestSource (const CaseDefinition& caseDef) 145e5c31af7Sopenharmony_ci{ 146e5c31af7Sopenharmony_ci const bool formatIsBoolean = fmtIsBoolean(caseDef.format); 147e5c31af7Sopenharmony_ci const string op = getOpTypeName(caseDef.opType); 148e5c31af7Sopenharmony_ci const string fmt = subgroups::getFormatNameForGLSL(caseDef.format); 149e5c31af7Sopenharmony_ci const string computePart = isAllComputeStages(caseDef.shaderStage) 150e5c31af7Sopenharmony_ci ? op + "(data[gl_SubgroupInvocationID] > 0) ? 0x4 : 0x0" 151e5c31af7Sopenharmony_ci : "0x4"; 152e5c31af7Sopenharmony_ci 153e5c31af7Sopenharmony_ci return 154e5c31af7Sopenharmony_ci (OPTYPE_ALL == caseDef.opType || OPTYPE_ALL_ARB == caseDef.opType) ? 155e5c31af7Sopenharmony_ci " tempRes = " + op + "(true) ? 0x1 : 0;\n" 156e5c31af7Sopenharmony_ci " tempRes |= " + op + "(false) ? 0 : 0x1A;\n" 157e5c31af7Sopenharmony_ci " tempRes |= " + computePart + ";\n" 158e5c31af7Sopenharmony_ci : (OPTYPE_ANY == caseDef.opType || OPTYPE_ANY_ARB == caseDef.opType) ? 159e5c31af7Sopenharmony_ci " tempRes = " + op + "(true) ? 0x1 : 0;\n" 160e5c31af7Sopenharmony_ci " tempRes |= " + op + "(false) ? 0 : 0x1A;\n" 161e5c31af7Sopenharmony_ci " tempRes |= " + computePart + ";\n" 162e5c31af7Sopenharmony_ci : (OPTYPE_ALLEQUAL == caseDef.opType || OPTYPE_ALLEQUAL_ARB == caseDef.opType) ? 163e5c31af7Sopenharmony_ci " " + fmt + " valueEqual = " + fmt + "(1.25 * float(data[gl_SubgroupInvocationID]) + 5.0);\n" + 164e5c31af7Sopenharmony_ci " " + fmt + " valueNoEqual = " + fmt + (formatIsBoolean ? "(subgroupElect());\n" : "(gl_SubgroupInvocationID);\n") + 165e5c31af7Sopenharmony_ci " tempRes = " + op + "(" + fmt + "(1)) ? 0x1 : 0;\n" 166e5c31af7Sopenharmony_ci " tempRes |= " 167e5c31af7Sopenharmony_ci + (formatIsBoolean ? "0x2" : op + "(" + fmt + "(gl_SubgroupInvocationID)) ? 0 : 0x2") 168e5c31af7Sopenharmony_ci + ";\n" 169e5c31af7Sopenharmony_ci " tempRes |= " + op + "(data[0]) ? 0x4 : 0;\n" 170e5c31af7Sopenharmony_ci " tempRes |= " + op + "(valueEqual) ? 0x8 : 0x0;\n" 171e5c31af7Sopenharmony_ci " tempRes |= " + op + "(valueNoEqual) ? 0x0 : 0x10;\n" 172e5c31af7Sopenharmony_ci " if (subgroupElect()) tempRes |= 0x2 | 0x10;\n" 173e5c31af7Sopenharmony_ci : ""; 174e5c31af7Sopenharmony_ci} 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_civoid initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef) 177e5c31af7Sopenharmony_ci{ 178e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 179e5c31af7Sopenharmony_ci const bool spirv14required = isAllRayTracingStages(caseDef.shaderStage); 180e5c31af7Sopenharmony_ci#else 181e5c31af7Sopenharmony_ci const bool spirv14required = false; 182e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 183e5c31af7Sopenharmony_ci const SpirvVersion spirvVersion = spirv14required ? SPIRV_VERSION_1_4 : SPIRV_VERSION_1_3; 184e5c31af7Sopenharmony_ci const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, spirvVersion, 0u); 185e5c31af7Sopenharmony_ci const bool arbFunctions = caseDef.opType > OPTYPE_LAST_NON_ARB; 186e5c31af7Sopenharmony_ci const string extensions = getExtensions(arbFunctions) + subgroups::getAdditionalExtensionForFormat(caseDef.format); 187e5c31af7Sopenharmony_ci const bool pointSize = *caseDef.geometryPointSizeSupported; 188e5c31af7Sopenharmony_ci 189e5c31af7Sopenharmony_ci subgroups::initStdFrameBufferPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, pointSize, extensions, getStageTestSource(caseDef), ""); 190e5c31af7Sopenharmony_ci} 191e5c31af7Sopenharmony_ci 192e5c31af7Sopenharmony_ciconst string getStageTestSourceFrag (const CaseDefinition& caseDef) 193e5c31af7Sopenharmony_ci{ 194e5c31af7Sopenharmony_ci const bool formatIsBoolean = fmtIsBoolean(caseDef.format); 195e5c31af7Sopenharmony_ci const string op = getOpTypeName(caseDef.opType); 196e5c31af7Sopenharmony_ci const string fmt = subgroups::getFormatNameForGLSL(caseDef.format); 197e5c31af7Sopenharmony_ci 198e5c31af7Sopenharmony_ci return 199e5c31af7Sopenharmony_ci (OPTYPE_ALL == caseDef.opType || OPTYPE_ALL_ARB == caseDef.opType) ? 200e5c31af7Sopenharmony_ci " tempRes |= " + op + "(!gl_HelperInvocation) ? 0x0 : 0x1;\n" 201e5c31af7Sopenharmony_ci " tempRes |= " + op + "(false) ? 0 : 0x1A;\n" 202e5c31af7Sopenharmony_ci " tempRes |= 0x4;\n" 203e5c31af7Sopenharmony_ci : (OPTYPE_ANY == caseDef.opType || OPTYPE_ANY_ARB == caseDef.opType) ? 204e5c31af7Sopenharmony_ci " tempRes |= " + op + "(gl_HelperInvocation) ? 0x1 : 0x0;\n" 205e5c31af7Sopenharmony_ci " tempRes |= " + op + "(false) ? 0 : 0x1A;\n" 206e5c31af7Sopenharmony_ci " tempRes |= 0x4;\n" 207e5c31af7Sopenharmony_ci : (OPTYPE_ALLEQUAL == caseDef.opType || OPTYPE_ALLEQUAL_ARB == caseDef.opType) ? 208e5c31af7Sopenharmony_ci " " + fmt + " valueEqual = " + fmt + "(1.25 * float(data[gl_SubgroupInvocationID]) + 5.0);\n" + 209e5c31af7Sopenharmony_ci " " + fmt + " valueNoEqual = " + fmt + (formatIsBoolean ? "(subgroupElect());\n" : "(gl_SubgroupInvocationID);\n") + 210e5c31af7Sopenharmony_ci " tempRes |= " + getOpTypeName(caseDef.opType) + "(" 211e5c31af7Sopenharmony_ci + fmt + "(1)) ? 0x10 : 0;\n" 212e5c31af7Sopenharmony_ci " tempRes |= " 213e5c31af7Sopenharmony_ci + (formatIsBoolean ? "0x2" : op + "(" + fmt + "(gl_SubgroupInvocationID)) ? 0 : 0x2") 214e5c31af7Sopenharmony_ci + ";\n" 215e5c31af7Sopenharmony_ci " tempRes |= " + op + "(data[0]) ? 0x4 : 0;\n" 216e5c31af7Sopenharmony_ci " tempRes |= " + op + "(valueEqual) ? 0x8 : 0x0;\n" 217e5c31af7Sopenharmony_ci " tempRes |= " + op + "(gl_HelperInvocation) ? 0x0 : 0x1;\n" 218e5c31af7Sopenharmony_ci " if (subgroupElect()) tempRes |= 0x2 | 0x10;\n" 219e5c31af7Sopenharmony_ci : ""; 220e5c31af7Sopenharmony_ci} 221e5c31af7Sopenharmony_ci 222e5c31af7Sopenharmony_civoid initFrameBufferProgramsFrag (SourceCollections& programCollection, CaseDefinition caseDef) 223e5c31af7Sopenharmony_ci{ 224e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 225e5c31af7Sopenharmony_ci const bool spirv14required = isAllRayTracingStages(caseDef.shaderStage); 226e5c31af7Sopenharmony_ci#else 227e5c31af7Sopenharmony_ci const bool spirv14required = false; 228e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 229e5c31af7Sopenharmony_ci const SpirvVersion spirvVersion = spirv14required ? SPIRV_VERSION_1_4 : SPIRV_VERSION_1_3; 230e5c31af7Sopenharmony_ci const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, spirvVersion, 0u); 231e5c31af7Sopenharmony_ci const bool arbFunctions = caseDef.opType > OPTYPE_LAST_NON_ARB; 232e5c31af7Sopenharmony_ci const string extensions = getExtensions(arbFunctions) + subgroups::getAdditionalExtensionForFormat(caseDef.format); 233e5c31af7Sopenharmony_ci 234e5c31af7Sopenharmony_ci DE_ASSERT(VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage); 235e5c31af7Sopenharmony_ci 236e5c31af7Sopenharmony_ci { 237e5c31af7Sopenharmony_ci const string vertex = 238e5c31af7Sopenharmony_ci "#version 450\n" 239e5c31af7Sopenharmony_ci "void main (void)\n" 240e5c31af7Sopenharmony_ci "{\n" 241e5c31af7Sopenharmony_ci " vec2 uv = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n" 242e5c31af7Sopenharmony_ci " gl_Position = vec4(uv * 4.0f -2.0f, 0.0f, 1.0f);\n" 243e5c31af7Sopenharmony_ci " gl_PointSize = 1.0f;\n" 244e5c31af7Sopenharmony_ci "}\n"; 245e5c31af7Sopenharmony_ci 246e5c31af7Sopenharmony_ci programCollection.glslSources.add("vert") << glu::VertexSource(vertex) << buildOptions; 247e5c31af7Sopenharmony_ci } 248e5c31af7Sopenharmony_ci 249e5c31af7Sopenharmony_ci { 250e5c31af7Sopenharmony_ci ostringstream fragmentSource; 251e5c31af7Sopenharmony_ci 252e5c31af7Sopenharmony_ci fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n" 253e5c31af7Sopenharmony_ci << extensions 254e5c31af7Sopenharmony_ci << "layout(location = 0) out uint out_color;\n" 255e5c31af7Sopenharmony_ci << "layout(set = 0, binding = 0) uniform Buffer1\n" 256e5c31af7Sopenharmony_ci << "{\n" 257e5c31af7Sopenharmony_ci << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n" 258e5c31af7Sopenharmony_ci << "};\n" 259e5c31af7Sopenharmony_ci << "" 260e5c31af7Sopenharmony_ci << "void main()\n" 261e5c31af7Sopenharmony_ci << "{\n" 262e5c31af7Sopenharmony_ci << " uint tempRes = 0u;\n" 263e5c31af7Sopenharmony_ci << " if (dFdx(gl_SubgroupInvocationID * gl_FragCoord.x * gl_FragCoord.y) - dFdy(gl_SubgroupInvocationID * gl_FragCoord.x * gl_FragCoord.y) > 0.0f)\n" 264e5c31af7Sopenharmony_ci << " {\n" 265e5c31af7Sopenharmony_ci << " tempRes |= 0x20;\n" // to be sure that compiler doesn't remove dFdx and dFdy executions 266e5c31af7Sopenharmony_ci << " }\n" 267e5c31af7Sopenharmony_ci << (arbFunctions ? 268e5c31af7Sopenharmony_ci " bool helper = anyInvocationARB(gl_HelperInvocation);\n" : 269e5c31af7Sopenharmony_ci " bool helper = subgroupAny(gl_HelperInvocation);\n") 270e5c31af7Sopenharmony_ci << " if (helper)\n" 271e5c31af7Sopenharmony_ci << " {\n" 272e5c31af7Sopenharmony_ci << " tempRes |= 0x40;\n" 273e5c31af7Sopenharmony_ci << " }\n" 274e5c31af7Sopenharmony_ci << getStageTestSourceFrag(caseDef) 275e5c31af7Sopenharmony_ci << " out_color = tempRes;\n" 276e5c31af7Sopenharmony_ci << "}\n"; 277e5c31af7Sopenharmony_ci 278e5c31af7Sopenharmony_ci programCollection.glslSources.add("fragment") << glu::FragmentSource(fragmentSource.str())<< buildOptions; 279e5c31af7Sopenharmony_ci } 280e5c31af7Sopenharmony_ci} 281e5c31af7Sopenharmony_ci 282e5c31af7Sopenharmony_civoid initPrograms (SourceCollections& programCollection, CaseDefinition caseDef) 283e5c31af7Sopenharmony_ci{ 284e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 285e5c31af7Sopenharmony_ci const bool spirv14required = (isAllRayTracingStages(caseDef.shaderStage) || isAllMeshShadingStages(caseDef.shaderStage)); 286e5c31af7Sopenharmony_ci#else 287e5c31af7Sopenharmony_ci const bool spirv14required = false; 288e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 289e5c31af7Sopenharmony_ci const SpirvVersion spirvVersion = spirv14required ? SPIRV_VERSION_1_4 : SPIRV_VERSION_1_3; 290e5c31af7Sopenharmony_ci const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, spirvVersion, 0u, spirv14required); 291e5c31af7Sopenharmony_ci const bool arbFunctions = caseDef.opType > OPTYPE_LAST_NON_ARB; 292e5c31af7Sopenharmony_ci const string extensions = getExtensions(arbFunctions) + subgroups::getAdditionalExtensionForFormat(caseDef.format); 293e5c31af7Sopenharmony_ci const bool pointSize = *caseDef.geometryPointSizeSupported; 294e5c31af7Sopenharmony_ci 295e5c31af7Sopenharmony_ci subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, pointSize, extensions, getStageTestSource(caseDef), ""); 296e5c31af7Sopenharmony_ci} 297e5c31af7Sopenharmony_ci 298e5c31af7Sopenharmony_civoid supportedCheck (Context& context, CaseDefinition caseDef) 299e5c31af7Sopenharmony_ci{ 300e5c31af7Sopenharmony_ci if (!subgroups::isSubgroupSupported(context)) 301e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Subgroup operations are not supported"); 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ci if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_VOTE_BIT)) 304e5c31af7Sopenharmony_ci { 305e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support subgroup vote operations"); 306e5c31af7Sopenharmony_ci } 307e5c31af7Sopenharmony_ci 308e5c31af7Sopenharmony_ci if (!subgroups::isFormatSupportedForDevice(context, caseDef.format)) 309e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support the specified format in subgroup operations"); 310e5c31af7Sopenharmony_ci 311e5c31af7Sopenharmony_ci if (caseDef.requires16BitUniformBuffer) 312e5c31af7Sopenharmony_ci { 313e5c31af7Sopenharmony_ci if (!subgroups::is16BitUBOStorageSupported(context)) 314e5c31af7Sopenharmony_ci { 315e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support the specified format in subgroup operations"); 316e5c31af7Sopenharmony_ci } 317e5c31af7Sopenharmony_ci } 318e5c31af7Sopenharmony_ci 319e5c31af7Sopenharmony_ci if (caseDef.requires8BitUniformBuffer) 320e5c31af7Sopenharmony_ci { 321e5c31af7Sopenharmony_ci if (!subgroups::is8BitUBOStorageSupported(context)) 322e5c31af7Sopenharmony_ci { 323e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support the specified format in subgroup operations"); 324e5c31af7Sopenharmony_ci } 325e5c31af7Sopenharmony_ci } 326e5c31af7Sopenharmony_ci 327e5c31af7Sopenharmony_ci if (caseDef.opType > OPTYPE_LAST_NON_ARB) 328e5c31af7Sopenharmony_ci { 329e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_EXT_shader_subgroup_vote"); 330e5c31af7Sopenharmony_ci } 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_ci if (caseDef.requiredSubgroupSize) 333e5c31af7Sopenharmony_ci { 334e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_EXT_subgroup_size_control"); 335e5c31af7Sopenharmony_ci 336e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 337e5c31af7Sopenharmony_ci const VkPhysicalDeviceSubgroupSizeControlFeatures& subgroupSizeControlFeatures = context.getSubgroupSizeControlFeatures(); 338e5c31af7Sopenharmony_ci const VkPhysicalDeviceSubgroupSizeControlProperties& subgroupSizeControlProperties = context.getSubgroupSizeControlProperties(); 339e5c31af7Sopenharmony_ci#else 340e5c31af7Sopenharmony_ci const VkPhysicalDeviceSubgroupSizeControlFeaturesEXT& subgroupSizeControlFeatures = context.getSubgroupSizeControlFeaturesEXT(); 341e5c31af7Sopenharmony_ci const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& subgroupSizeControlProperties = context.getSubgroupSizeControlPropertiesEXT(); 342e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 343e5c31af7Sopenharmony_ci 344e5c31af7Sopenharmony_ci if (subgroupSizeControlFeatures.subgroupSizeControl == DE_FALSE) 345e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support varying subgroup sizes nor required subgroup size"); 346e5c31af7Sopenharmony_ci 347e5c31af7Sopenharmony_ci if (subgroupSizeControlFeatures.computeFullSubgroups == DE_FALSE) 348e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support full subgroups in compute shaders"); 349e5c31af7Sopenharmony_ci 350e5c31af7Sopenharmony_ci if ((subgroupSizeControlProperties.requiredSubgroupSizeStages & caseDef.shaderStage) != caseDef.shaderStage) 351e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Required subgroup size is not supported for shader stage"); 352e5c31af7Sopenharmony_ci } 353e5c31af7Sopenharmony_ci 354e5c31af7Sopenharmony_ci *caseDef.geometryPointSizeSupported = subgroups::isTessellationAndGeometryPointSizeSupported(context); 355e5c31af7Sopenharmony_ci 356e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 357e5c31af7Sopenharmony_ci if (isAllRayTracingStages(caseDef.shaderStage)) 358e5c31af7Sopenharmony_ci { 359e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline"); 360e5c31af7Sopenharmony_ci } 361e5c31af7Sopenharmony_ci else if (isAllMeshShadingStages(caseDef.shaderStage)) 362e5c31af7Sopenharmony_ci { 363e5c31af7Sopenharmony_ci context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS); 364e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_EXT_mesh_shader"); 365e5c31af7Sopenharmony_ci 366e5c31af7Sopenharmony_ci if ((caseDef.shaderStage & VK_SHADER_STAGE_TASK_BIT_EXT) != 0u) 367e5c31af7Sopenharmony_ci { 368e5c31af7Sopenharmony_ci const auto& features = context.getMeshShaderFeaturesEXT(); 369e5c31af7Sopenharmony_ci if (!features.taskShader) 370e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Task shaders not supported"); 371e5c31af7Sopenharmony_ci } 372e5c31af7Sopenharmony_ci } 373e5c31af7Sopenharmony_ci 374e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 375e5c31af7Sopenharmony_ci 376e5c31af7Sopenharmony_ci subgroups::supportedCheckShader(context, caseDef.shaderStage); 377e5c31af7Sopenharmony_ci} 378e5c31af7Sopenharmony_ci 379e5c31af7Sopenharmony_ciTestStatus noSSBOtest (Context& context, const CaseDefinition caseDef) 380e5c31af7Sopenharmony_ci{ 381e5c31af7Sopenharmony_ci if (caseDef.opType > OPTYPE_LAST_NON_ARB) 382e5c31af7Sopenharmony_ci { 383e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_EXT_shader_subgroup_vote"); 384e5c31af7Sopenharmony_ci } 385e5c31af7Sopenharmony_ci 386e5c31af7Sopenharmony_ci const subgroups::SSBOData::InputDataInitializeType initializeType = (OPTYPE_ALLEQUAL == caseDef.opType || OPTYPE_ALLEQUAL_ARB == caseDef.opType) 387e5c31af7Sopenharmony_ci ? subgroups::SSBOData::InitializeZero 388e5c31af7Sopenharmony_ci : subgroups::SSBOData::InitializeNonZero; 389e5c31af7Sopenharmony_ci const subgroups::SSBOData inputData 390e5c31af7Sopenharmony_ci { 391e5c31af7Sopenharmony_ci initializeType, // InputDataInitializeType initializeType; 392e5c31af7Sopenharmony_ci subgroups::SSBOData::LayoutStd140, // InputDataLayoutType layout; 393e5c31af7Sopenharmony_ci caseDef.format, // vk::VkFormat format; 394e5c31af7Sopenharmony_ci subgroups::maxSupportedSubgroupSize(), // vk::VkDeviceSize numElements; 395e5c31af7Sopenharmony_ci subgroups::SSBOData::BindingUBO, // BindingType bindingType; 396e5c31af7Sopenharmony_ci }; 397e5c31af7Sopenharmony_ci 398e5c31af7Sopenharmony_ci switch (caseDef.shaderStage) 399e5c31af7Sopenharmony_ci { 400e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_VERTEX_BIT: return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages); 401e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_GEOMETRY_BIT: return subgroups::makeGeometryFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages); 402e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, caseDef.shaderStage); 403e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, caseDef.shaderStage); 404e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_FRAGMENT_BIT: return subgroups::makeFragmentFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkFragmentPipelineStages); 405e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Unhandled shader stage"); 406e5c31af7Sopenharmony_ci } 407e5c31af7Sopenharmony_ci} 408e5c31af7Sopenharmony_ci 409e5c31af7Sopenharmony_ciTestStatus test (Context& context, const CaseDefinition caseDef) 410e5c31af7Sopenharmony_ci{ 411e5c31af7Sopenharmony_ci const subgroups::SSBOData::InputDataInitializeType initializeType = (OPTYPE_ALLEQUAL == caseDef.opType || OPTYPE_ALLEQUAL_ARB == caseDef.opType) 412e5c31af7Sopenharmony_ci ? subgroups::SSBOData::InitializeZero 413e5c31af7Sopenharmony_ci : subgroups::SSBOData::InitializeNonZero; 414e5c31af7Sopenharmony_ci 415e5c31af7Sopenharmony_ci const bool isCompute = isAllComputeStages(caseDef.shaderStage); 416e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 417e5c31af7Sopenharmony_ci const bool isMesh = isAllMeshShadingStages(caseDef.shaderStage); 418e5c31af7Sopenharmony_ci#else 419e5c31af7Sopenharmony_ci const bool isMesh = false; 420e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 421e5c31af7Sopenharmony_ci DE_ASSERT(!(isCompute && isMesh)); 422e5c31af7Sopenharmony_ci 423e5c31af7Sopenharmony_ci if (isCompute || isMesh) 424e5c31af7Sopenharmony_ci { 425e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 426e5c31af7Sopenharmony_ci const VkPhysicalDeviceSubgroupSizeControlProperties& subgroupSizeControlProperties = context.getSubgroupSizeControlProperties(); 427e5c31af7Sopenharmony_ci#else 428e5c31af7Sopenharmony_ci const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& subgroupSizeControlProperties = context.getSubgroupSizeControlPropertiesEXT(); 429e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 430e5c31af7Sopenharmony_ci TestLog& log = context.getTestContext().getLog(); 431e5c31af7Sopenharmony_ci const subgroups::SSBOData inputData 432e5c31af7Sopenharmony_ci { 433e5c31af7Sopenharmony_ci initializeType, // InputDataInitializeType initializeType; 434e5c31af7Sopenharmony_ci subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout; 435e5c31af7Sopenharmony_ci caseDef.format, // vk::VkFormat format; 436e5c31af7Sopenharmony_ci subgroups::maxSupportedSubgroupSize(), // vk::VkDeviceSize numElements; 437e5c31af7Sopenharmony_ci }; 438e5c31af7Sopenharmony_ci 439e5c31af7Sopenharmony_ci if (caseDef.requiredSubgroupSize == DE_FALSE) 440e5c31af7Sopenharmony_ci { 441e5c31af7Sopenharmony_ci if (isCompute) 442e5c31af7Sopenharmony_ci return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkComputeOrMesh); 443e5c31af7Sopenharmony_ci else 444e5c31af7Sopenharmony_ci return subgroups::makeMeshTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkComputeOrMesh); 445e5c31af7Sopenharmony_ci } 446e5c31af7Sopenharmony_ci 447e5c31af7Sopenharmony_ci log << TestLog::Message << "Testing required subgroup size range [" << subgroupSizeControlProperties.minSubgroupSize << ", " 448e5c31af7Sopenharmony_ci << subgroupSizeControlProperties.maxSubgroupSize << "]" << TestLog::EndMessage; 449e5c31af7Sopenharmony_ci 450e5c31af7Sopenharmony_ci // According to the spec, requiredSubgroupSize must be a power-of-two integer. 451e5c31af7Sopenharmony_ci for (deUint32 size = subgroupSizeControlProperties.minSubgroupSize; size <= subgroupSizeControlProperties.maxSubgroupSize; size *= 2) 452e5c31af7Sopenharmony_ci { 453e5c31af7Sopenharmony_ci TestStatus result (QP_TEST_RESULT_INTERNAL_ERROR, "Internal Error"); 454e5c31af7Sopenharmony_ci 455e5c31af7Sopenharmony_ci if (isCompute) 456e5c31af7Sopenharmony_ci result = subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkComputeOrMesh, size); 457e5c31af7Sopenharmony_ci else 458e5c31af7Sopenharmony_ci result = subgroups::makeMeshTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkComputeOrMesh, size); 459e5c31af7Sopenharmony_ci 460e5c31af7Sopenharmony_ci if (result.getCode() != QP_TEST_RESULT_PASS) 461e5c31af7Sopenharmony_ci { 462e5c31af7Sopenharmony_ci log << TestLog::Message << "subgroupSize " << size << " failed" << TestLog::EndMessage; 463e5c31af7Sopenharmony_ci return result; 464e5c31af7Sopenharmony_ci } 465e5c31af7Sopenharmony_ci } 466e5c31af7Sopenharmony_ci 467e5c31af7Sopenharmony_ci return TestStatus::pass("OK"); 468e5c31af7Sopenharmony_ci } 469e5c31af7Sopenharmony_ci else if (isAllGraphicsStages(caseDef.shaderStage)) 470e5c31af7Sopenharmony_ci { 471e5c31af7Sopenharmony_ci const VkShaderStageFlags stages = subgroups::getPossibleGraphicsSubgroupStages(context, caseDef.shaderStage); 472e5c31af7Sopenharmony_ci const subgroups::SSBOData inputData = 473e5c31af7Sopenharmony_ci { 474e5c31af7Sopenharmony_ci initializeType, // InputDataInitializeType initializeType; 475e5c31af7Sopenharmony_ci subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout; 476e5c31af7Sopenharmony_ci caseDef.format, // vk::VkFormat format; 477e5c31af7Sopenharmony_ci subgroups::maxSupportedSubgroupSize(), // vk::VkDeviceSize numElements; 478e5c31af7Sopenharmony_ci subgroups::SSBOData::BindingSSBO, // bool isImage; 479e5c31af7Sopenharmony_ci 4u, // deUint32 binding; 480e5c31af7Sopenharmony_ci stages, // vk::VkShaderStageFlags stages; 481e5c31af7Sopenharmony_ci }; 482e5c31af7Sopenharmony_ci 483e5c31af7Sopenharmony_ci return subgroups::allStages(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, stages); 484e5c31af7Sopenharmony_ci } 485e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 486e5c31af7Sopenharmony_ci else if (isAllRayTracingStages(caseDef.shaderStage)) 487e5c31af7Sopenharmony_ci { 488e5c31af7Sopenharmony_ci const VkShaderStageFlags stages = subgroups::getPossibleRayTracingSubgroupStages(context, caseDef.shaderStage); 489e5c31af7Sopenharmony_ci const subgroups::SSBOData inputData = 490e5c31af7Sopenharmony_ci { 491e5c31af7Sopenharmony_ci initializeType, // InputDataInitializeType initializeType; 492e5c31af7Sopenharmony_ci subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout; 493e5c31af7Sopenharmony_ci caseDef.format, // vk::VkFormat format; 494e5c31af7Sopenharmony_ci subgroups::maxSupportedSubgroupSize(), // vk::VkDeviceSize numElements; 495e5c31af7Sopenharmony_ci subgroups::SSBOData::BindingSSBO, // bool isImage; 496e5c31af7Sopenharmony_ci 6u, // deUint32 binding; 497e5c31af7Sopenharmony_ci stages, // vk::VkShaderStageFlags stages; 498e5c31af7Sopenharmony_ci }; 499e5c31af7Sopenharmony_ci 500e5c31af7Sopenharmony_ci return subgroups::allRayTracingStages(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, stages); 501e5c31af7Sopenharmony_ci } 502e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 503e5c31af7Sopenharmony_ci else 504e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Unknown stage or invalid stage set"); 505e5c31af7Sopenharmony_ci} 506e5c31af7Sopenharmony_ci} 507e5c31af7Sopenharmony_ci 508e5c31af7Sopenharmony_cinamespace vkt 509e5c31af7Sopenharmony_ci{ 510e5c31af7Sopenharmony_cinamespace subgroups 511e5c31af7Sopenharmony_ci{ 512e5c31af7Sopenharmony_ciTestCaseGroup* createSubgroupsVoteTests (TestContext& testCtx) 513e5c31af7Sopenharmony_ci{ 514e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> group (new TestCaseGroup(testCtx, "vote", "Subgroup vote category tests")); 515e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> graphicGroup (new TestCaseGroup(testCtx, "graphics", "Subgroup vote category tests: graphics")); 516e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> computeGroup (new TestCaseGroup(testCtx, "compute", "Subgroup vote category tests: compute")); 517e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> framebufferGroup (new TestCaseGroup(testCtx, "framebuffer", "Subgroup vote category tests: framebuffer")); 518e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> fragHelperGroup (new TestCaseGroup(testCtx, "frag_helper", "Subgroup vote category tests: fragment helper invocation")); 519e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 520e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> raytracingGroup (new TestCaseGroup(testCtx, "ray_tracing", "Subgroup vote category tests: raytracing")); 521e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> meshGroup (new TestCaseGroup(testCtx, "mesh", "Subgroup vote category tests: mesh shading")); 522e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> meshGroupARB (new TestCaseGroup(testCtx, "mesh", "Subgroup vote category tests: mesh shading")); 523e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 524e5c31af7Sopenharmony_ci 525e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> groupARB (new TestCaseGroup(testCtx, "ext_shader_subgroup_vote", "VK_EXT_shader_subgroup_vote category tests")); 526e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> graphicGroupARB (new TestCaseGroup(testCtx, "graphics", "Subgroup vote category tests: graphics")); 527e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> computeGroupARB (new TestCaseGroup(testCtx, "compute", "Subgroup vote category tests: compute")); 528e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> framebufferGroupARB (new TestCaseGroup(testCtx, "framebuffer", "Subgroup vote category tests: framebuffer")); 529e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> fragHelperGroupARB (new TestCaseGroup(testCtx, "frag_helper", "Subgroup vote category tests: fragment helper invocation")); 530e5c31af7Sopenharmony_ci const deBool boolValues[] = 531e5c31af7Sopenharmony_ci { 532e5c31af7Sopenharmony_ci DE_FALSE, 533e5c31af7Sopenharmony_ci DE_TRUE 534e5c31af7Sopenharmony_ci }; 535e5c31af7Sopenharmony_ci 536e5c31af7Sopenharmony_ci { 537e5c31af7Sopenharmony_ci const VkShaderStageFlags fbStages[] = 538e5c31af7Sopenharmony_ci { 539e5c31af7Sopenharmony_ci VK_SHADER_STAGE_VERTEX_BIT, 540e5c31af7Sopenharmony_ci VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 541e5c31af7Sopenharmony_ci VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 542e5c31af7Sopenharmony_ci VK_SHADER_STAGE_GEOMETRY_BIT, 543e5c31af7Sopenharmony_ci }; 544e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 545e5c31af7Sopenharmony_ci const VkShaderStageFlags meshStages[] = 546e5c31af7Sopenharmony_ci { 547e5c31af7Sopenharmony_ci VK_SHADER_STAGE_MESH_BIT_EXT, 548e5c31af7Sopenharmony_ci VK_SHADER_STAGE_TASK_BIT_EXT, 549e5c31af7Sopenharmony_ci }; 550e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 551e5c31af7Sopenharmony_ci const vector<VkFormat> formats = subgroups::getAllFormats(); 552e5c31af7Sopenharmony_ci 553e5c31af7Sopenharmony_ci for (size_t formatIndex = 0; formatIndex < formats.size(); ++formatIndex) 554e5c31af7Sopenharmony_ci { 555e5c31af7Sopenharmony_ci const VkFormat format = formats[formatIndex]; 556e5c31af7Sopenharmony_ci const bool needs8BitUBOStorage = isFormat8bitTy(format); 557e5c31af7Sopenharmony_ci const bool needs16BitUBOStorage = isFormat16BitTy(format); 558e5c31af7Sopenharmony_ci const deBool formatIsNotVector = format == VK_FORMAT_R8_USCALED 559e5c31af7Sopenharmony_ci || format == VK_FORMAT_R32_UINT 560e5c31af7Sopenharmony_ci || format == VK_FORMAT_R32_SINT 561e5c31af7Sopenharmony_ci || format == VK_FORMAT_R32_SFLOAT 562e5c31af7Sopenharmony_ci || format == VK_FORMAT_R64_SFLOAT; 563e5c31af7Sopenharmony_ci 564e5c31af7Sopenharmony_ci for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex) 565e5c31af7Sopenharmony_ci { 566e5c31af7Sopenharmony_ci const OpType opType = static_cast<OpType>(opTypeIndex); 567e5c31af7Sopenharmony_ci 568e5c31af7Sopenharmony_ci // Skip OPTYPE_LAST_NON_ARB because it is not a real op type. 569e5c31af7Sopenharmony_ci if (opType == OPTYPE_LAST_NON_ARB) 570e5c31af7Sopenharmony_ci continue; 571e5c31af7Sopenharmony_ci 572e5c31af7Sopenharmony_ci // Skip the non-nonvector tests because VK_EXT_shader_subgroup_vote functions only supports boolean scalar arguments. 573e5c31af7Sopenharmony_ci if (opType > OPTYPE_LAST_NON_ARB && !formatIsNotVector) 574e5c31af7Sopenharmony_ci continue; 575e5c31af7Sopenharmony_ci 576e5c31af7Sopenharmony_ci // Skip non-boolean formats when testing allInvocationsEqualARB(bool value), because it requires a boolean 577e5c31af7Sopenharmony_ci // argument that should have the same value for all invocations. For the rest of formats, it won't be a boolean argument, 578e5c31af7Sopenharmony_ci // so it may give wrong results when converting to bool. 579e5c31af7Sopenharmony_ci if (opType == OPTYPE_ALLEQUAL_ARB && format != VK_FORMAT_R8_USCALED) 580e5c31af7Sopenharmony_ci continue; 581e5c31af7Sopenharmony_ci 582e5c31af7Sopenharmony_ci // Skip the typed tests for all but subgroupAllEqual() and allInvocationsEqualARB() 583e5c31af7Sopenharmony_ci if ((VK_FORMAT_R32_UINT != format) && (OPTYPE_ALLEQUAL != opType) && (OPTYPE_ALLEQUAL_ARB != opType)) 584e5c31af7Sopenharmony_ci { 585e5c31af7Sopenharmony_ci continue; 586e5c31af7Sopenharmony_ci } 587e5c31af7Sopenharmony_ci 588e5c31af7Sopenharmony_ci const string op = de::toLower(getOpTypeName(opType)); 589e5c31af7Sopenharmony_ci const string name = op + "_" + subgroups::getFormatNameForGLSL(format); 590e5c31af7Sopenharmony_ci const bool opNonARB = (opType < OPTYPE_LAST_NON_ARB); 591e5c31af7Sopenharmony_ci TestCaseGroup* computeGroupPtr = opNonARB ? computeGroup.get() : computeGroupARB.get(); 592e5c31af7Sopenharmony_ci TestCaseGroup* graphicGroupPtr = opNonARB ? graphicGroup.get() : graphicGroupARB.get(); 593e5c31af7Sopenharmony_ci TestCaseGroup* framebufferGroupPtr = opNonARB ? framebufferGroup.get() : framebufferGroupARB.get(); 594e5c31af7Sopenharmony_ci TestCaseGroup* fragHelperGroupPtr = opNonARB ? fragHelperGroup.get() : fragHelperGroupARB.get(); 595e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 596e5c31af7Sopenharmony_ci TestCaseGroup* meshGroupPtr = opNonARB ? meshGroup.get() : meshGroupARB.get(); 597e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 598e5c31af7Sopenharmony_ci 599e5c31af7Sopenharmony_ci for (size_t groupSizeNdx = 0; groupSizeNdx < DE_LENGTH_OF_ARRAY(boolValues); ++groupSizeNdx) 600e5c31af7Sopenharmony_ci { 601e5c31af7Sopenharmony_ci const deBool requiredSubgroupSize = boolValues[groupSizeNdx]; 602e5c31af7Sopenharmony_ci const string testName = name + (requiredSubgroupSize ? "_requiredsubgroupsize" : ""); 603e5c31af7Sopenharmony_ci const CaseDefinition caseDef = 604e5c31af7Sopenharmony_ci { 605e5c31af7Sopenharmony_ci opType, // OpType opType; 606e5c31af7Sopenharmony_ci VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags shaderStage; 607e5c31af7Sopenharmony_ci format, // VkFormat format; 608e5c31af7Sopenharmony_ci de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported; 609e5c31af7Sopenharmony_ci requiredSubgroupSize, // deBool requiredSubgroupSize; 610e5c31af7Sopenharmony_ci deBool(false), // deBool requires8BitUniformBuffer; 611e5c31af7Sopenharmony_ci deBool(false) // deBool requires16BitUniformBuffer; 612e5c31af7Sopenharmony_ci }; 613e5c31af7Sopenharmony_ci 614e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms(computeGroupPtr, testName, supportedCheck, initPrograms, test, caseDef); 615e5c31af7Sopenharmony_ci } 616e5c31af7Sopenharmony_ci 617e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 618e5c31af7Sopenharmony_ci for (size_t groupSizeNdx = 0; groupSizeNdx < DE_LENGTH_OF_ARRAY(boolValues); ++groupSizeNdx) 619e5c31af7Sopenharmony_ci { 620e5c31af7Sopenharmony_ci for (const auto& stage : meshStages) 621e5c31af7Sopenharmony_ci { 622e5c31af7Sopenharmony_ci const deBool requiredSubgroupSize = boolValues[groupSizeNdx]; 623e5c31af7Sopenharmony_ci const string testName = name + (requiredSubgroupSize ? "_requiredsubgroupsize" : "") + "_" + getShaderStageName(stage); 624e5c31af7Sopenharmony_ci const CaseDefinition caseDef = 625e5c31af7Sopenharmony_ci { 626e5c31af7Sopenharmony_ci opType, // OpType opType; 627e5c31af7Sopenharmony_ci stage, // VkShaderStageFlags shaderStage; 628e5c31af7Sopenharmony_ci format, // VkFormat format; 629e5c31af7Sopenharmony_ci de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported; 630e5c31af7Sopenharmony_ci requiredSubgroupSize, // deBool requiredSubgroupSize; 631e5c31af7Sopenharmony_ci deBool(false), // deBool requires8BitUniformBuffer; 632e5c31af7Sopenharmony_ci deBool(false) // deBool requires16BitUniformBuffer; 633e5c31af7Sopenharmony_ci }; 634e5c31af7Sopenharmony_ci 635e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms(meshGroupPtr, testName, supportedCheck, initPrograms, test, caseDef); 636e5c31af7Sopenharmony_ci } 637e5c31af7Sopenharmony_ci } 638e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 639e5c31af7Sopenharmony_ci 640e5c31af7Sopenharmony_ci { 641e5c31af7Sopenharmony_ci const CaseDefinition caseDef = 642e5c31af7Sopenharmony_ci { 643e5c31af7Sopenharmony_ci opType, // OpType opType; 644e5c31af7Sopenharmony_ci VK_SHADER_STAGE_ALL_GRAPHICS, // VkShaderStageFlags shaderStage; 645e5c31af7Sopenharmony_ci format, // VkFormat format; 646e5c31af7Sopenharmony_ci de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported; 647e5c31af7Sopenharmony_ci DE_FALSE, // deBool requiredSubgroupSize; 648e5c31af7Sopenharmony_ci deBool(false), // deBool requires8BitUniformBuffer; 649e5c31af7Sopenharmony_ci deBool(false) // deBool requires16BitUniformBuffer; 650e5c31af7Sopenharmony_ci }; 651e5c31af7Sopenharmony_ci 652e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms(graphicGroupPtr, name, supportedCheck, initPrograms, test, caseDef); 653e5c31af7Sopenharmony_ci } 654e5c31af7Sopenharmony_ci 655e5c31af7Sopenharmony_ci for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(fbStages); ++stageIndex) 656e5c31af7Sopenharmony_ci { 657e5c31af7Sopenharmony_ci const CaseDefinition caseDef = 658e5c31af7Sopenharmony_ci { 659e5c31af7Sopenharmony_ci opType, // OpType opType; 660e5c31af7Sopenharmony_ci fbStages[stageIndex], // VkShaderStageFlags shaderStage; 661e5c31af7Sopenharmony_ci format, // VkFormat format; 662e5c31af7Sopenharmony_ci de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported; 663e5c31af7Sopenharmony_ci DE_FALSE, // deBool requiredSubgroupSize; 664e5c31af7Sopenharmony_ci deBool(needs8BitUBOStorage), // deBool requires8BitUniformBuffer; 665e5c31af7Sopenharmony_ci deBool(needs16BitUBOStorage) // deBool requires16BitUniformBuffer; 666e5c31af7Sopenharmony_ci }; 667e5c31af7Sopenharmony_ci const string testName = name + "_" + getShaderStageName(caseDef.shaderStage); 668e5c31af7Sopenharmony_ci 669e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms(framebufferGroupPtr, testName, supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef); 670e5c31af7Sopenharmony_ci } 671e5c31af7Sopenharmony_ci 672e5c31af7Sopenharmony_ci { 673e5c31af7Sopenharmony_ci const CaseDefinition caseDef = 674e5c31af7Sopenharmony_ci { 675e5c31af7Sopenharmony_ci opType, // OpType opType; 676e5c31af7Sopenharmony_ci VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags shaderStage; 677e5c31af7Sopenharmony_ci format, // VkFormat format; 678e5c31af7Sopenharmony_ci de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported; 679e5c31af7Sopenharmony_ci DE_FALSE, // deBool requiredSubgroupSize; 680e5c31af7Sopenharmony_ci deBool(needs8BitUBOStorage), // deBool requires8BitUniformBuffer; 681e5c31af7Sopenharmony_ci deBool(needs16BitUBOStorage) // deBool requires16BitUniformBuffer; 682e5c31af7Sopenharmony_ci }; 683e5c31af7Sopenharmony_ci const string testName = name + "_" + getShaderStageName(caseDef.shaderStage); 684e5c31af7Sopenharmony_ci 685e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms(fragHelperGroupPtr, testName, supportedCheck, initFrameBufferProgramsFrag, noSSBOtest, caseDef); 686e5c31af7Sopenharmony_ci } 687e5c31af7Sopenharmony_ci } 688e5c31af7Sopenharmony_ci } 689e5c31af7Sopenharmony_ci } 690e5c31af7Sopenharmony_ci 691e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 692e5c31af7Sopenharmony_ci { 693e5c31af7Sopenharmony_ci const vector<VkFormat> formats = subgroups::getAllRayTracingFormats(); 694e5c31af7Sopenharmony_ci 695e5c31af7Sopenharmony_ci for (size_t formatIndex = 0; formatIndex < formats.size(); ++formatIndex) 696e5c31af7Sopenharmony_ci { 697e5c31af7Sopenharmony_ci const VkFormat format = formats[formatIndex]; 698e5c31af7Sopenharmony_ci 699e5c31af7Sopenharmony_ci for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST_NON_ARB; ++opTypeIndex) 700e5c31af7Sopenharmony_ci { 701e5c31af7Sopenharmony_ci const OpType opType = static_cast<OpType>(opTypeIndex); 702e5c31af7Sopenharmony_ci 703e5c31af7Sopenharmony_ci // Skip the typed tests for all but subgroupAllEqual() 704e5c31af7Sopenharmony_ci if ((VK_FORMAT_R32_UINT != format) && (OPTYPE_ALLEQUAL != opType)) 705e5c31af7Sopenharmony_ci { 706e5c31af7Sopenharmony_ci continue; 707e5c31af7Sopenharmony_ci } 708e5c31af7Sopenharmony_ci 709e5c31af7Sopenharmony_ci const string op = de::toLower(getOpTypeName(opType)); 710e5c31af7Sopenharmony_ci const string name = op + "_" + subgroups::getFormatNameForGLSL(format); 711e5c31af7Sopenharmony_ci const CaseDefinition caseDef = 712e5c31af7Sopenharmony_ci { 713e5c31af7Sopenharmony_ci opType, // OpType opType; 714e5c31af7Sopenharmony_ci SHADER_STAGE_ALL_RAY_TRACING, // VkShaderStageFlags shaderStage; 715e5c31af7Sopenharmony_ci format, // VkFormat format; 716e5c31af7Sopenharmony_ci de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported; 717e5c31af7Sopenharmony_ci DE_FALSE, // deBool requiredSubgroupSize; 718e5c31af7Sopenharmony_ci DE_FALSE, // deBool requires8BitUniformBuffer; 719e5c31af7Sopenharmony_ci DE_FALSE // deBool requires16BitUniformBuffer; 720e5c31af7Sopenharmony_ci }; 721e5c31af7Sopenharmony_ci 722e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms(raytracingGroup.get(), name, supportedCheck, initPrograms, test, caseDef); 723e5c31af7Sopenharmony_ci } 724e5c31af7Sopenharmony_ci } 725e5c31af7Sopenharmony_ci } 726e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 727e5c31af7Sopenharmony_ci 728e5c31af7Sopenharmony_ci groupARB->addChild(graphicGroupARB.release()); 729e5c31af7Sopenharmony_ci groupARB->addChild(computeGroupARB.release()); 730e5c31af7Sopenharmony_ci groupARB->addChild(framebufferGroupARB.release()); 731e5c31af7Sopenharmony_ci groupARB->addChild(fragHelperGroupARB.release()); 732e5c31af7Sopenharmony_ci 733e5c31af7Sopenharmony_ci group->addChild(graphicGroup.release()); 734e5c31af7Sopenharmony_ci group->addChild(computeGroup.release()); 735e5c31af7Sopenharmony_ci group->addChild(framebufferGroup.release()); 736e5c31af7Sopenharmony_ci group->addChild(fragHelperGroup.release()); 737e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 738e5c31af7Sopenharmony_ci group->addChild(raytracingGroup.release()); 739e5c31af7Sopenharmony_ci group->addChild(meshGroup.release()); 740e5c31af7Sopenharmony_ci groupARB->addChild(meshGroupARB.release()); 741e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 742e5c31af7Sopenharmony_ci 743e5c31af7Sopenharmony_ci group->addChild(groupARB.release()); 744e5c31af7Sopenharmony_ci 745e5c31af7Sopenharmony_ci return group.release(); 746e5c31af7Sopenharmony_ci} 747e5c31af7Sopenharmony_ci 748e5c31af7Sopenharmony_ci} // subgroups 749e5c31af7Sopenharmony_ci} // vkt 750