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 "vktSubgroupsQuadTests.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_QUAD_BROADCAST = 0, 42e5c31af7Sopenharmony_ci OPTYPE_QUAD_BROADCAST_NONCONST, 43e5c31af7Sopenharmony_ci OPTYPE_QUAD_SWAP_HORIZONTAL, 44e5c31af7Sopenharmony_ci OPTYPE_QUAD_SWAP_VERTICAL, 45e5c31af7Sopenharmony_ci OPTYPE_QUAD_SWAP_DIAGONAL, 46e5c31af7Sopenharmony_ci OPTYPE_LAST 47e5c31af7Sopenharmony_ci}; 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_cistruct CaseDefinition 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_ci OpType opType; 52e5c31af7Sopenharmony_ci VkShaderStageFlags shaderStage; 53e5c31af7Sopenharmony_ci VkFormat format; 54e5c31af7Sopenharmony_ci de::SharedPtr<bool> geometryPointSizeSupported; 55e5c31af7Sopenharmony_ci deBool requiredSubgroupSize; 56e5c31af7Sopenharmony_ci deBool requires8BitUniformBuffer; 57e5c31af7Sopenharmony_ci deBool requires16BitUniformBuffer; 58e5c31af7Sopenharmony_ci}; 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_cistatic bool checkVertexPipelineStages (const void* internalData, 61e5c31af7Sopenharmony_ci vector<const void*> datas, 62e5c31af7Sopenharmony_ci deUint32 width, 63e5c31af7Sopenharmony_ci deUint32) 64e5c31af7Sopenharmony_ci{ 65e5c31af7Sopenharmony_ci DE_UNREF(internalData); 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_ci return subgroups::check(datas, width, 1); 68e5c31af7Sopenharmony_ci} 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_cistatic bool checkComputeOrMesh (const void* internalData, 71e5c31af7Sopenharmony_ci vector<const void*> datas, 72e5c31af7Sopenharmony_ci const deUint32 numWorkgroups[3], 73e5c31af7Sopenharmony_ci const deUint32 localSize[3], 74e5c31af7Sopenharmony_ci deUint32) 75e5c31af7Sopenharmony_ci{ 76e5c31af7Sopenharmony_ci DE_UNREF(internalData); 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_ci return subgroups::checkComputeOrMesh(datas, numWorkgroups, localSize, 1); 79e5c31af7Sopenharmony_ci} 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_cistring getOpTypeName (OpType opType) 82e5c31af7Sopenharmony_ci{ 83e5c31af7Sopenharmony_ci switch (opType) 84e5c31af7Sopenharmony_ci { 85e5c31af7Sopenharmony_ci case OPTYPE_QUAD_BROADCAST: return "subgroupQuadBroadcast"; 86e5c31af7Sopenharmony_ci case OPTYPE_QUAD_BROADCAST_NONCONST: return "subgroupQuadBroadcast"; 87e5c31af7Sopenharmony_ci case OPTYPE_QUAD_SWAP_HORIZONTAL: return "subgroupQuadSwapHorizontal"; 88e5c31af7Sopenharmony_ci case OPTYPE_QUAD_SWAP_VERTICAL: return "subgroupQuadSwapVertical"; 89e5c31af7Sopenharmony_ci case OPTYPE_QUAD_SWAP_DIAGONAL: return "subgroupQuadSwapDiagonal"; 90e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Unsupported op type"); 91e5c31af7Sopenharmony_ci } 92e5c31af7Sopenharmony_ci} 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_cistring getOpTypeCaseName (OpType opType) 95e5c31af7Sopenharmony_ci{ 96e5c31af7Sopenharmony_ci switch (opType) 97e5c31af7Sopenharmony_ci { 98e5c31af7Sopenharmony_ci case OPTYPE_QUAD_BROADCAST: return "subgroupquadbroadcast"; 99e5c31af7Sopenharmony_ci case OPTYPE_QUAD_BROADCAST_NONCONST: return "subgroupquadbroadcast_nonconst"; 100e5c31af7Sopenharmony_ci case OPTYPE_QUAD_SWAP_HORIZONTAL: return "subgroupquadswaphorizontal"; 101e5c31af7Sopenharmony_ci case OPTYPE_QUAD_SWAP_VERTICAL: return "subgroupquadswapvertical"; 102e5c31af7Sopenharmony_ci case OPTYPE_QUAD_SWAP_DIAGONAL: return "subgroupquadswapdiagonal"; 103e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Unsupported op type"); 104e5c31af7Sopenharmony_ci } 105e5c31af7Sopenharmony_ci} 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_cistring getExtHeader (VkFormat format) 108e5c31af7Sopenharmony_ci{ 109e5c31af7Sopenharmony_ci return "#extension GL_KHR_shader_subgroup_quad: enable\n" 110e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" + 111e5c31af7Sopenharmony_ci subgroups::getAdditionalExtensionForFormat(format); 112e5c31af7Sopenharmony_ci} 113e5c31af7Sopenharmony_ci 114e5c31af7Sopenharmony_cistring getTestSrc (const CaseDefinition &caseDef) 115e5c31af7Sopenharmony_ci{ 116e5c31af7Sopenharmony_ci const string swapTable[OPTYPE_LAST] = 117e5c31af7Sopenharmony_ci { 118e5c31af7Sopenharmony_ci "", 119e5c31af7Sopenharmony_ci "", 120e5c31af7Sopenharmony_ci " const uint swapTable[4] = {1, 0, 3, 2};\n", 121e5c31af7Sopenharmony_ci " const uint swapTable[4] = {2, 3, 0, 1};\n", 122e5c31af7Sopenharmony_ci " const uint swapTable[4] = {3, 2, 1, 0};\n", 123e5c31af7Sopenharmony_ci }; 124e5c31af7Sopenharmony_ci const string validate = 125e5c31af7Sopenharmony_ci " if (subgroupBallotBitExtract(mask, otherID) && op !=data[otherID])\n" 126e5c31af7Sopenharmony_ci " tempRes = 0;\n"; 127e5c31af7Sopenharmony_ci const string fmt = subgroups::getFormatNameForGLSL(caseDef.format); 128e5c31af7Sopenharmony_ci const string op = getOpTypeName(caseDef.opType); 129e5c31af7Sopenharmony_ci ostringstream testSrc; 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_ci testSrc << " uvec4 mask = subgroupBallot(true);\n" 132e5c31af7Sopenharmony_ci << swapTable[caseDef.opType] 133e5c31af7Sopenharmony_ci << " tempRes = 1;\n"; 134e5c31af7Sopenharmony_ci 135e5c31af7Sopenharmony_ci if (caseDef.opType == OPTYPE_QUAD_BROADCAST) 136e5c31af7Sopenharmony_ci { 137e5c31af7Sopenharmony_ci for (int i=0; i<4; i++) 138e5c31af7Sopenharmony_ci { 139e5c31af7Sopenharmony_ci testSrc << " {\n" 140e5c31af7Sopenharmony_ci << " " << fmt << " op = " << op << "(data[gl_SubgroupInvocationID], " << i << ");\n" 141e5c31af7Sopenharmony_ci << " uint otherID = (gl_SubgroupInvocationID & ~0x3) + " << i << ";\n" 142e5c31af7Sopenharmony_ci << validate 143e5c31af7Sopenharmony_ci << " }\n"; 144e5c31af7Sopenharmony_ci } 145e5c31af7Sopenharmony_ci } 146e5c31af7Sopenharmony_ci else if (caseDef.opType == OPTYPE_QUAD_BROADCAST_NONCONST) 147e5c31af7Sopenharmony_ci { 148e5c31af7Sopenharmony_ci testSrc << " for (int i=0; i<4; i++)" 149e5c31af7Sopenharmony_ci << " {\n" 150e5c31af7Sopenharmony_ci << " " << fmt << " op = " << op << "(data[gl_SubgroupInvocationID], i);\n" 151e5c31af7Sopenharmony_ci << " uint otherID = (gl_SubgroupInvocationID & ~0x3) + i;\n" 152e5c31af7Sopenharmony_ci << validate 153e5c31af7Sopenharmony_ci << " }\n" 154e5c31af7Sopenharmony_ci << " uint quadID = gl_SubgroupInvocationID >> 2;\n" 155e5c31af7Sopenharmony_ci << " uint quadInvocation = gl_SubgroupInvocationID & 0x3;\n" 156e5c31af7Sopenharmony_ci << " // Test lane ID that is only uniform in active lanes\n" 157e5c31af7Sopenharmony_ci << " if (quadInvocation >= 2)\n" 158e5c31af7Sopenharmony_ci << " {\n" 159e5c31af7Sopenharmony_ci << " uint id = quadInvocation & ~1;\n" 160e5c31af7Sopenharmony_ci << " " << fmt << " op = " << op << "(data[gl_SubgroupInvocationID], id);\n" 161e5c31af7Sopenharmony_ci << " uint otherID = 4*quadID + id;\n" 162e5c31af7Sopenharmony_ci << validate 163e5c31af7Sopenharmony_ci << " }\n" 164e5c31af7Sopenharmony_ci << " // Test lane ID that is only quad uniform, not subgroup uniform\n" 165e5c31af7Sopenharmony_ci << " {\n" 166e5c31af7Sopenharmony_ci << " uint id = quadID & 0x3;\n" 167e5c31af7Sopenharmony_ci << " " << fmt << " op = " << op << "(data[gl_SubgroupInvocationID], id);\n" 168e5c31af7Sopenharmony_ci << " uint otherID = 4*quadID + id;\n" 169e5c31af7Sopenharmony_ci << validate 170e5c31af7Sopenharmony_ci << " }\n"; 171e5c31af7Sopenharmony_ci } 172e5c31af7Sopenharmony_ci else 173e5c31af7Sopenharmony_ci { 174e5c31af7Sopenharmony_ci testSrc << " " << fmt << " op = " << op << "(data[gl_SubgroupInvocationID]);\n" 175e5c31af7Sopenharmony_ci << " uint otherID = (gl_SubgroupInvocationID & ~0x3) + swapTable[gl_SubgroupInvocationID & 0x3];\n" 176e5c31af7Sopenharmony_ci << validate; 177e5c31af7Sopenharmony_ci } 178e5c31af7Sopenharmony_ci 179e5c31af7Sopenharmony_ci return testSrc.str(); 180e5c31af7Sopenharmony_ci} 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_civoid initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef) 183e5c31af7Sopenharmony_ci{ 184e5c31af7Sopenharmony_ci const SpirvVersion spirvVersion = (caseDef.opType == OPTYPE_QUAD_BROADCAST_NONCONST) ? SPIRV_VERSION_1_5 : SPIRV_VERSION_1_3; 185e5c31af7Sopenharmony_ci const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, spirvVersion, 0u); 186e5c31af7Sopenharmony_ci 187e5c31af7Sopenharmony_ci subgroups::initStdFrameBufferPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, getExtHeader(caseDef.format), getTestSrc(caseDef), ""); 188e5c31af7Sopenharmony_ci} 189e5c31af7Sopenharmony_ci 190e5c31af7Sopenharmony_civoid initPrograms (SourceCollections& programCollection, CaseDefinition caseDef) 191e5c31af7Sopenharmony_ci{ 192e5c31af7Sopenharmony_ci const bool spirv15required = caseDef.opType == OPTYPE_QUAD_BROADCAST_NONCONST; 193e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 194e5c31af7Sopenharmony_ci const bool spirv14required = (isAllRayTracingStages(caseDef.shaderStage) || isAllMeshShadingStages(caseDef.shaderStage)); 195e5c31af7Sopenharmony_ci#else 196e5c31af7Sopenharmony_ci const bool spirv14required = false; 197e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 198e5c31af7Sopenharmony_ci const SpirvVersion spirvVersion = spirv15required ? SPIRV_VERSION_1_5 199e5c31af7Sopenharmony_ci : spirv14required ? SPIRV_VERSION_1_4 200e5c31af7Sopenharmony_ci : SPIRV_VERSION_1_3; 201e5c31af7Sopenharmony_ci const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, spirvVersion, 0u, (spirv14required && !spirv15required)); 202e5c31af7Sopenharmony_ci const string extHeader = getExtHeader(caseDef.format); 203e5c31af7Sopenharmony_ci const string testSrc = getTestSrc(caseDef); 204e5c31af7Sopenharmony_ci 205e5c31af7Sopenharmony_ci subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, caseDef.format, *caseDef.geometryPointSizeSupported, extHeader, testSrc, ""); 206e5c31af7Sopenharmony_ci} 207e5c31af7Sopenharmony_ci 208e5c31af7Sopenharmony_civoid supportedCheck (Context& context, CaseDefinition caseDef) 209e5c31af7Sopenharmony_ci{ 210e5c31af7Sopenharmony_ci if (!subgroups::isSubgroupSupported(context)) 211e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Subgroup operations are not supported"); 212e5c31af7Sopenharmony_ci 213e5c31af7Sopenharmony_ci if (!subgroups::areQuadOperationsSupportedForStages(context, caseDef.shaderStage)) 214e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support subgroup quad operations in this shader stage"); 215e5c31af7Sopenharmony_ci 216e5c31af7Sopenharmony_ci if (!subgroups::isFormatSupportedForDevice(context, caseDef.format)) 217e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support the specified format in subgroup operations"); 218e5c31af7Sopenharmony_ci 219e5c31af7Sopenharmony_ci if (caseDef.requires16BitUniformBuffer) 220e5c31af7Sopenharmony_ci { 221e5c31af7Sopenharmony_ci if (!subgroups::is16BitUBOStorageSupported(context)) 222e5c31af7Sopenharmony_ci { 223e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support the specified format in subgroup operations"); 224e5c31af7Sopenharmony_ci } 225e5c31af7Sopenharmony_ci } 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ci if (caseDef.requires8BitUniformBuffer) 228e5c31af7Sopenharmony_ci { 229e5c31af7Sopenharmony_ci if (!subgroups::is8BitUBOStorageSupported(context)) 230e5c31af7Sopenharmony_ci { 231e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support the specified format in subgroup operations"); 232e5c31af7Sopenharmony_ci } 233e5c31af7Sopenharmony_ci } 234e5c31af7Sopenharmony_ci 235e5c31af7Sopenharmony_ci if ((caseDef.opType == OPTYPE_QUAD_BROADCAST_NONCONST) && !subgroups::isSubgroupBroadcastDynamicIdSupported(context)) 236e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support SubgroupBroadcastDynamicId"); 237e5c31af7Sopenharmony_ci 238e5c31af7Sopenharmony_ci if (caseDef.requiredSubgroupSize) 239e5c31af7Sopenharmony_ci { 240e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_EXT_subgroup_size_control"); 241e5c31af7Sopenharmony_ci 242e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 243e5c31af7Sopenharmony_ci const VkPhysicalDeviceSubgroupSizeControlFeatures& subgroupSizeControlFeatures = context.getSubgroupSizeControlFeatures(); 244e5c31af7Sopenharmony_ci const VkPhysicalDeviceSubgroupSizeControlProperties& subgroupSizeControlProperties = context.getSubgroupSizeControlProperties(); 245e5c31af7Sopenharmony_ci#else 246e5c31af7Sopenharmony_ci const VkPhysicalDeviceSubgroupSizeControlFeaturesEXT& subgroupSizeControlFeatures = context.getSubgroupSizeControlFeaturesEXT(); 247e5c31af7Sopenharmony_ci const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& subgroupSizeControlProperties = context.getSubgroupSizeControlPropertiesEXT(); 248e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 249e5c31af7Sopenharmony_ci 250e5c31af7Sopenharmony_ci if (subgroupSizeControlFeatures.subgroupSizeControl == DE_FALSE) 251e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support varying subgroup sizes nor required subgroup size"); 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci if (subgroupSizeControlFeatures.computeFullSubgroups == DE_FALSE) 254e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support full subgroups in compute shaders"); 255e5c31af7Sopenharmony_ci 256e5c31af7Sopenharmony_ci if ((subgroupSizeControlProperties.requiredSubgroupSizeStages & caseDef.shaderStage) != caseDef.shaderStage) 257e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Required subgroup size is not supported for shader stage"); 258e5c31af7Sopenharmony_ci } 259e5c31af7Sopenharmony_ci 260e5c31af7Sopenharmony_ci *caseDef.geometryPointSizeSupported = subgroups::isTessellationAndGeometryPointSizeSupported(context); 261e5c31af7Sopenharmony_ci 262e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 263e5c31af7Sopenharmony_ci if (isAllRayTracingStages(caseDef.shaderStage)) 264e5c31af7Sopenharmony_ci { 265e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline"); 266e5c31af7Sopenharmony_ci } 267e5c31af7Sopenharmony_ci else if (isAllMeshShadingStages(caseDef.shaderStage)) 268e5c31af7Sopenharmony_ci { 269e5c31af7Sopenharmony_ci context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS); 270e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_EXT_mesh_shader"); 271e5c31af7Sopenharmony_ci 272e5c31af7Sopenharmony_ci if ((caseDef.shaderStage & VK_SHADER_STAGE_TASK_BIT_EXT) != 0u) 273e5c31af7Sopenharmony_ci { 274e5c31af7Sopenharmony_ci const auto& features = context.getMeshShaderFeaturesEXT(); 275e5c31af7Sopenharmony_ci if (!features.taskShader) 276e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Task shaders not supported"); 277e5c31af7Sopenharmony_ci } 278e5c31af7Sopenharmony_ci } 279e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 280e5c31af7Sopenharmony_ci 281e5c31af7Sopenharmony_ci subgroups::supportedCheckShader(context, caseDef.shaderStage); 282e5c31af7Sopenharmony_ci} 283e5c31af7Sopenharmony_ci 284e5c31af7Sopenharmony_ciTestStatus noSSBOtest (Context& context, const CaseDefinition caseDef) 285e5c31af7Sopenharmony_ci{ 286e5c31af7Sopenharmony_ci subgroups::SSBOData inputData; 287e5c31af7Sopenharmony_ci inputData.format = caseDef.format; 288e5c31af7Sopenharmony_ci inputData.layout = subgroups::SSBOData::LayoutStd140; 289e5c31af7Sopenharmony_ci inputData.numElements = subgroups::maxSupportedSubgroupSize(); 290e5c31af7Sopenharmony_ci inputData.initializeType = subgroups::SSBOData::InitializeNonZero; 291e5c31af7Sopenharmony_ci inputData.bindingType = subgroups::SSBOData::BindingUBO; 292e5c31af7Sopenharmony_ci 293e5c31af7Sopenharmony_ci switch (caseDef.shaderStage) 294e5c31af7Sopenharmony_ci { 295e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_VERTEX_BIT: return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages); 296e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_GEOMETRY_BIT: return subgroups::makeGeometryFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages); 297e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, caseDef.shaderStage); 298e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, caseDef.shaderStage); 299e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Unhandled shader stage"); 300e5c31af7Sopenharmony_ci } 301e5c31af7Sopenharmony_ci} 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ciTestStatus test (Context& context, const CaseDefinition caseDef) 304e5c31af7Sopenharmony_ci{ 305e5c31af7Sopenharmony_ci const bool isCompute = isAllComputeStages(caseDef.shaderStage); 306e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 307e5c31af7Sopenharmony_ci const bool isMesh = isAllMeshShadingStages(caseDef.shaderStage); 308e5c31af7Sopenharmony_ci#else 309e5c31af7Sopenharmony_ci const bool isMesh = false; 310e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 311e5c31af7Sopenharmony_ci DE_ASSERT(!(isCompute && isMesh)); 312e5c31af7Sopenharmony_ci 313e5c31af7Sopenharmony_ci if (isCompute || isMesh) 314e5c31af7Sopenharmony_ci { 315e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 316e5c31af7Sopenharmony_ci const VkPhysicalDeviceSubgroupSizeControlProperties& subgroupSizeControlProperties = context.getSubgroupSizeControlProperties(); 317e5c31af7Sopenharmony_ci#else 318e5c31af7Sopenharmony_ci const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& subgroupSizeControlProperties = context.getSubgroupSizeControlPropertiesEXT(); 319e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 320e5c31af7Sopenharmony_ci TestLog& log = context.getTestContext().getLog(); 321e5c31af7Sopenharmony_ci const subgroups::SSBOData inputData 322e5c31af7Sopenharmony_ci { 323e5c31af7Sopenharmony_ci subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType; 324e5c31af7Sopenharmony_ci subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout; 325e5c31af7Sopenharmony_ci caseDef.format, // vk::VkFormat format; 326e5c31af7Sopenharmony_ci subgroups::maxSupportedSubgroupSize(), // vk::VkDeviceSize numElements; 327e5c31af7Sopenharmony_ci }; 328e5c31af7Sopenharmony_ci 329e5c31af7Sopenharmony_ci if (caseDef.requiredSubgroupSize == DE_FALSE) 330e5c31af7Sopenharmony_ci { 331e5c31af7Sopenharmony_ci if (isCompute) 332e5c31af7Sopenharmony_ci return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkComputeOrMesh); 333e5c31af7Sopenharmony_ci else 334e5c31af7Sopenharmony_ci return subgroups::makeMeshTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkComputeOrMesh); 335e5c31af7Sopenharmony_ci } 336e5c31af7Sopenharmony_ci 337e5c31af7Sopenharmony_ci log << TestLog::Message << "Testing required subgroup size range [" << subgroupSizeControlProperties.minSubgroupSize << ", " 338e5c31af7Sopenharmony_ci << subgroupSizeControlProperties.maxSubgroupSize << "]" << TestLog::EndMessage; 339e5c31af7Sopenharmony_ci 340e5c31af7Sopenharmony_ci // According to the spec, requiredSubgroupSize must be a power-of-two integer. 341e5c31af7Sopenharmony_ci for (deUint32 size = subgroupSizeControlProperties.minSubgroupSize; size <= subgroupSizeControlProperties.maxSubgroupSize; size *= 2) 342e5c31af7Sopenharmony_ci { 343e5c31af7Sopenharmony_ci TestStatus result (QP_TEST_RESULT_INTERNAL_ERROR, "Internal Error"); 344e5c31af7Sopenharmony_ci 345e5c31af7Sopenharmony_ci if (isCompute) 346e5c31af7Sopenharmony_ci result = subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkComputeOrMesh, size); 347e5c31af7Sopenharmony_ci else 348e5c31af7Sopenharmony_ci result = subgroups::makeMeshTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkComputeOrMesh, size); 349e5c31af7Sopenharmony_ci 350e5c31af7Sopenharmony_ci if (result.getCode() != QP_TEST_RESULT_PASS) 351e5c31af7Sopenharmony_ci { 352e5c31af7Sopenharmony_ci log << TestLog::Message << "subgroupSize " << size << " failed" << TestLog::EndMessage; 353e5c31af7Sopenharmony_ci return result; 354e5c31af7Sopenharmony_ci } 355e5c31af7Sopenharmony_ci } 356e5c31af7Sopenharmony_ci 357e5c31af7Sopenharmony_ci return TestStatus::pass("OK"); 358e5c31af7Sopenharmony_ci } 359e5c31af7Sopenharmony_ci else if (isAllGraphicsStages(caseDef.shaderStage)) 360e5c31af7Sopenharmony_ci { 361e5c31af7Sopenharmony_ci const VkShaderStageFlags stages = subgroups::getPossibleGraphicsSubgroupStages(context, caseDef.shaderStage); 362e5c31af7Sopenharmony_ci subgroups::SSBOData inputData; 363e5c31af7Sopenharmony_ci 364e5c31af7Sopenharmony_ci inputData.format = caseDef.format; 365e5c31af7Sopenharmony_ci inputData.layout = subgroups::SSBOData::LayoutStd430; 366e5c31af7Sopenharmony_ci inputData.numElements = subgroups::maxSupportedSubgroupSize(); 367e5c31af7Sopenharmony_ci inputData.initializeType = subgroups::SSBOData::InitializeNonZero; 368e5c31af7Sopenharmony_ci inputData.binding = 4u; 369e5c31af7Sopenharmony_ci inputData.stages = stages; 370e5c31af7Sopenharmony_ci 371e5c31af7Sopenharmony_ci return subgroups::allStages(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, stages); 372e5c31af7Sopenharmony_ci } 373e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 374e5c31af7Sopenharmony_ci else if (isAllRayTracingStages(caseDef.shaderStage)) 375e5c31af7Sopenharmony_ci { 376e5c31af7Sopenharmony_ci const VkShaderStageFlags stages = subgroups::getPossibleRayTracingSubgroupStages(context, caseDef.shaderStage); 377e5c31af7Sopenharmony_ci const subgroups::SSBOData inputData = 378e5c31af7Sopenharmony_ci { 379e5c31af7Sopenharmony_ci subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType; 380e5c31af7Sopenharmony_ci subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout; 381e5c31af7Sopenharmony_ci caseDef.format, // vk::VkFormat format; 382e5c31af7Sopenharmony_ci subgroups::maxSupportedSubgroupSize(), // vk::VkDeviceSize numElements; 383e5c31af7Sopenharmony_ci subgroups::SSBOData::BindingSSBO, // bool isImage; 384e5c31af7Sopenharmony_ci 6u, // deUint32 binding; 385e5c31af7Sopenharmony_ci stages, // vk::VkShaderStageFlags stages; 386e5c31af7Sopenharmony_ci }; 387e5c31af7Sopenharmony_ci 388e5c31af7Sopenharmony_ci return subgroups::allRayTracingStages(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, stages); 389e5c31af7Sopenharmony_ci } 390e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 391e5c31af7Sopenharmony_ci else 392e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Unknown stage or invalid stage set"); 393e5c31af7Sopenharmony_ci} 394e5c31af7Sopenharmony_ci} 395e5c31af7Sopenharmony_ci 396e5c31af7Sopenharmony_cinamespace vkt 397e5c31af7Sopenharmony_ci{ 398e5c31af7Sopenharmony_cinamespace subgroups 399e5c31af7Sopenharmony_ci{ 400e5c31af7Sopenharmony_ciTestCaseGroup* createSubgroupsQuadTests (TestContext& testCtx) 401e5c31af7Sopenharmony_ci{ 402e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> group (new TestCaseGroup(testCtx, "quad", "Subgroup quad category tests")); 403e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> graphicGroup (new TestCaseGroup(testCtx, "graphics", "Subgroup arithmetic category tests: graphics")); 404e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> computeGroup (new TestCaseGroup(testCtx, "compute", "Subgroup arithmetic category tests: compute")); 405e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> framebufferGroup (new TestCaseGroup(testCtx, "framebuffer", "Subgroup arithmetic category tests: framebuffer")); 406e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 407e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> raytracingGroup (new TestCaseGroup(testCtx, "ray_tracing", "Subgroup arithmetic category tests: ray tracing")); 408e5c31af7Sopenharmony_ci de::MovePtr<TestCaseGroup> meshGroup (new TestCaseGroup(testCtx, "mesh", "Subgroup arithmetic category tests: mesh shading")); 409e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 410e5c31af7Sopenharmony_ci const VkShaderStageFlags fbStages[] = 411e5c31af7Sopenharmony_ci { 412e5c31af7Sopenharmony_ci VK_SHADER_STAGE_VERTEX_BIT, 413e5c31af7Sopenharmony_ci VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 414e5c31af7Sopenharmony_ci VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 415e5c31af7Sopenharmony_ci VK_SHADER_STAGE_GEOMETRY_BIT, 416e5c31af7Sopenharmony_ci }; 417e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 418e5c31af7Sopenharmony_ci const VkShaderStageFlags meshStages[] = 419e5c31af7Sopenharmony_ci { 420e5c31af7Sopenharmony_ci VK_SHADER_STAGE_MESH_BIT_EXT, 421e5c31af7Sopenharmony_ci VK_SHADER_STAGE_TASK_BIT_EXT, 422e5c31af7Sopenharmony_ci }; 423e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 424e5c31af7Sopenharmony_ci const deBool boolValues[] = 425e5c31af7Sopenharmony_ci { 426e5c31af7Sopenharmony_ci DE_FALSE, 427e5c31af7Sopenharmony_ci DE_TRUE 428e5c31af7Sopenharmony_ci }; 429e5c31af7Sopenharmony_ci 430e5c31af7Sopenharmony_ci { 431e5c31af7Sopenharmony_ci const vector<VkFormat> formats = subgroups::getAllFormats(); 432e5c31af7Sopenharmony_ci 433e5c31af7Sopenharmony_ci for (size_t formatIndex = 0; formatIndex < formats.size(); ++formatIndex) 434e5c31af7Sopenharmony_ci { 435e5c31af7Sopenharmony_ci const VkFormat format = formats[formatIndex]; 436e5c31af7Sopenharmony_ci const string formatName = subgroups::getFormatNameForGLSL(format); 437e5c31af7Sopenharmony_ci const bool needs8BitUBOStorage = isFormat8bitTy(format); 438e5c31af7Sopenharmony_ci const bool needs16BitUBOStorage = isFormat16BitTy(format); 439e5c31af7Sopenharmony_ci 440e5c31af7Sopenharmony_ci for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex) 441e5c31af7Sopenharmony_ci { 442e5c31af7Sopenharmony_ci const OpType opType = static_cast<OpType>(opTypeIndex); 443e5c31af7Sopenharmony_ci const string name = getOpTypeCaseName(opType) + "_" + formatName; 444e5c31af7Sopenharmony_ci 445e5c31af7Sopenharmony_ci for (size_t groupSizeNdx = 0; groupSizeNdx < DE_LENGTH_OF_ARRAY(boolValues); ++groupSizeNdx) 446e5c31af7Sopenharmony_ci { 447e5c31af7Sopenharmony_ci const deBool requiredSubgroupSize = boolValues[groupSizeNdx]; 448e5c31af7Sopenharmony_ci const string testNameSuffix = requiredSubgroupSize ? "_requiredsubgroupsize" : ""; 449e5c31af7Sopenharmony_ci const string testName = name + testNameSuffix; 450e5c31af7Sopenharmony_ci const CaseDefinition caseDef = 451e5c31af7Sopenharmony_ci { 452e5c31af7Sopenharmony_ci opType, // OpType opType; 453e5c31af7Sopenharmony_ci VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags shaderStage; 454e5c31af7Sopenharmony_ci format, // VkFormat format; 455e5c31af7Sopenharmony_ci de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported; 456e5c31af7Sopenharmony_ci requiredSubgroupSize, // deBool requiredSubgroupSize; 457e5c31af7Sopenharmony_ci DE_FALSE, // deBool requires8BitUniformBuffer; 458e5c31af7Sopenharmony_ci DE_FALSE // deBool requires16BitUniformBuffer; 459e5c31af7Sopenharmony_ci }; 460e5c31af7Sopenharmony_ci 461e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms(computeGroup.get(), testName,supportedCheck, initPrograms, test, caseDef); 462e5c31af7Sopenharmony_ci } 463e5c31af7Sopenharmony_ci 464e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 465e5c31af7Sopenharmony_ci for (size_t groupSizeNdx = 0; groupSizeNdx < DE_LENGTH_OF_ARRAY(boolValues); ++groupSizeNdx) 466e5c31af7Sopenharmony_ci { 467e5c31af7Sopenharmony_ci for (const auto& stage : meshStages) 468e5c31af7Sopenharmony_ci { 469e5c31af7Sopenharmony_ci const deBool requiredSubgroupSize = boolValues[groupSizeNdx]; 470e5c31af7Sopenharmony_ci const string testNameSuffix = requiredSubgroupSize ? "_requiredsubgroupsize" : ""; 471e5c31af7Sopenharmony_ci const string testName = name + testNameSuffix + "_" + getShaderStageName(stage); 472e5c31af7Sopenharmony_ci const CaseDefinition caseDef = 473e5c31af7Sopenharmony_ci { 474e5c31af7Sopenharmony_ci opType, // OpType opType; 475e5c31af7Sopenharmony_ci stage, // VkShaderStageFlags shaderStage; 476e5c31af7Sopenharmony_ci format, // VkFormat format; 477e5c31af7Sopenharmony_ci de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported; 478e5c31af7Sopenharmony_ci requiredSubgroupSize, // deBool requiredSubgroupSize; 479e5c31af7Sopenharmony_ci DE_FALSE, // deBool requires8BitUniformBuffer; 480e5c31af7Sopenharmony_ci DE_FALSE // deBool requires16BitUniformBuffer; 481e5c31af7Sopenharmony_ci }; 482e5c31af7Sopenharmony_ci 483e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms(meshGroup.get(), testName,supportedCheck, initPrograms, test, caseDef); 484e5c31af7Sopenharmony_ci } 485e5c31af7Sopenharmony_ci } 486e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 487e5c31af7Sopenharmony_ci 488e5c31af7Sopenharmony_ci { 489e5c31af7Sopenharmony_ci const CaseDefinition caseDef = 490e5c31af7Sopenharmony_ci { 491e5c31af7Sopenharmony_ci opType, // OpType opType; 492e5c31af7Sopenharmony_ci VK_SHADER_STAGE_ALL_GRAPHICS, // VkShaderStageFlags shaderStage; 493e5c31af7Sopenharmony_ci format, // VkFormat format; 494e5c31af7Sopenharmony_ci de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported; 495e5c31af7Sopenharmony_ci DE_FALSE, // deBool requiredSubgroupSize; 496e5c31af7Sopenharmony_ci DE_FALSE, // deBool requires8BitUniformBuffer; 497e5c31af7Sopenharmony_ci DE_FALSE // deBool requires16BitUniformBuffer; 498e5c31af7Sopenharmony_ci }; 499e5c31af7Sopenharmony_ci 500e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms(graphicGroup.get(), name, supportedCheck, initPrograms, test, caseDef); 501e5c31af7Sopenharmony_ci } 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_ci for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(fbStages); ++stageIndex) 504e5c31af7Sopenharmony_ci { 505e5c31af7Sopenharmony_ci const CaseDefinition caseDef = 506e5c31af7Sopenharmony_ci { 507e5c31af7Sopenharmony_ci opType, // OpType opType; 508e5c31af7Sopenharmony_ci fbStages[stageIndex], // VkShaderStageFlags shaderStage; 509e5c31af7Sopenharmony_ci format, // VkFormat format; 510e5c31af7Sopenharmony_ci de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported; 511e5c31af7Sopenharmony_ci DE_FALSE, // deBool requiredSubgroupSize; 512e5c31af7Sopenharmony_ci deBool(needs8BitUBOStorage), // deBool requires8BitUniformBuffer; 513e5c31af7Sopenharmony_ci deBool(needs16BitUBOStorage) // deBool requires16BitUniformBuffer; 514e5c31af7Sopenharmony_ci }; 515e5c31af7Sopenharmony_ci const string testName = name + "_" + getShaderStageName(caseDef.shaderStage); 516e5c31af7Sopenharmony_ci 517e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms(framebufferGroup.get(), testName,supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef); 518e5c31af7Sopenharmony_ci } 519e5c31af7Sopenharmony_ci } 520e5c31af7Sopenharmony_ci } 521e5c31af7Sopenharmony_ci } 522e5c31af7Sopenharmony_ci 523e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 524e5c31af7Sopenharmony_ci { 525e5c31af7Sopenharmony_ci const vector<VkFormat> formats = subgroups::getAllRayTracingFormats(); 526e5c31af7Sopenharmony_ci 527e5c31af7Sopenharmony_ci for (size_t formatIndex = 0; formatIndex < formats.size(); ++formatIndex) 528e5c31af7Sopenharmony_ci { 529e5c31af7Sopenharmony_ci const VkFormat format = formats[formatIndex]; 530e5c31af7Sopenharmony_ci const string formatName = subgroups::getFormatNameForGLSL(format); 531e5c31af7Sopenharmony_ci 532e5c31af7Sopenharmony_ci for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex) 533e5c31af7Sopenharmony_ci { 534e5c31af7Sopenharmony_ci const OpType opType = static_cast<OpType>(opTypeIndex); 535e5c31af7Sopenharmony_ci const string testName = getOpTypeCaseName(opType) + "_" + formatName; 536e5c31af7Sopenharmony_ci const CaseDefinition caseDef = 537e5c31af7Sopenharmony_ci { 538e5c31af7Sopenharmony_ci opType, // OpType opType; 539e5c31af7Sopenharmony_ci SHADER_STAGE_ALL_RAY_TRACING, // VkShaderStageFlags shaderStage; 540e5c31af7Sopenharmony_ci format, // VkFormat format; 541e5c31af7Sopenharmony_ci de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported; 542e5c31af7Sopenharmony_ci DE_FALSE, // deBool requiredSubgroupSize; 543e5c31af7Sopenharmony_ci DE_FALSE, // deBool requires8BitUniformBuffer; 544e5c31af7Sopenharmony_ci DE_FALSE // deBool requires16BitUniformBuffer; 545e5c31af7Sopenharmony_ci }; 546e5c31af7Sopenharmony_ci 547e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms(raytracingGroup.get(), testName,supportedCheck, initPrograms, test, caseDef); 548e5c31af7Sopenharmony_ci } 549e5c31af7Sopenharmony_ci } 550e5c31af7Sopenharmony_ci } 551e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 552e5c31af7Sopenharmony_ci 553e5c31af7Sopenharmony_ci group->addChild(graphicGroup.release()); 554e5c31af7Sopenharmony_ci group->addChild(computeGroup.release()); 555e5c31af7Sopenharmony_ci group->addChild(framebufferGroup.release()); 556e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 557e5c31af7Sopenharmony_ci group->addChild(raytracingGroup.release()); 558e5c31af7Sopenharmony_ci group->addChild(meshGroup.release()); 559e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 560e5c31af7Sopenharmony_ci 561e5c31af7Sopenharmony_ci return group.release(); 562e5c31af7Sopenharmony_ci} 563e5c31af7Sopenharmony_ci} // subgroups 564e5c31af7Sopenharmony_ci} // vkt 565