From 498d58a5f838ef15af297fea1eba05da0a4cfce2 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Tue, 2 Jan 2024 11:55:53 -0600 Subject: [PATCH] vulkan: Add a vk_get_subgroup_size() helper No reason to duplicate this logic between pipelines and shader objects. Reviewed-by: Alyssa Rosenzweig Part-of: --- src/vulkan/runtime/vk_pipeline.c | 48 ++++++++++++++++++++------------ src/vulkan/runtime/vk_pipeline.h | 7 +++++ 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/vulkan/runtime/vk_pipeline.c b/src/vulkan/runtime/vk_pipeline.c index 50a87e13a3c..a1fa7745fde 100644 --- a/src/vulkan/runtime/vk_pipeline.c +++ b/src/vulkan/runtime/vk_pipeline.c @@ -76,14 +76,37 @@ get_builtin_nir(const VkPipelineShaderStageCreateInfo *info) } static uint32_t -get_required_subgroup_size(const VkPipelineShaderStageCreateInfo *info) +get_required_subgroup_size(const void *info_pNext) { const VkPipelineShaderStageRequiredSubgroupSizeCreateInfo *rss_info = - vk_find_struct_const(info->pNext, + vk_find_struct_const(info_pNext, PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO); return rss_info != NULL ? rss_info->requiredSubgroupSize : 0; } +enum gl_subgroup_size +vk_get_subgroup_size(uint32_t spirv_version, + gl_shader_stage stage, + const void *info_pNext, + bool allow_varying, + bool require_full) +{ + uint32_t req_subgroup_size = get_required_subgroup_size(info_pNext); + if (req_subgroup_size > 0) { + assert(util_is_power_of_two_nonzero(req_subgroup_size)); + assert(req_subgroup_size >= 8 && req_subgroup_size <= 128); + return req_subgroup_size; + } else if (allow_varying || spirv_version >= 0x10600) { + /* Starting with SPIR-V 1.6, varying subgroup size the default */ + return SUBGROUP_SIZE_VARYING; + } else if (require_full) { + assert(stage == MESA_SHADER_COMPUTE); + return SUBGROUP_SIZE_FULL_SUBGROUPS; + } else { + return SUBGROUP_SIZE_API_CONSTANT; + } +} + VkResult vk_pipeline_shader_stage_to_nir(struct vk_device *device, const VkPipelineShaderStageCreateInfo *info, @@ -127,22 +150,11 @@ vk_pipeline_shader_stage_to_nir(struct vk_device *device, spirv_size = minfo->codeSize; } - enum gl_subgroup_size subgroup_size; - uint32_t req_subgroup_size = get_required_subgroup_size(info); - if (req_subgroup_size > 0) { - assert(util_is_power_of_two_nonzero(req_subgroup_size)); - assert(req_subgroup_size >= 8 && req_subgroup_size <= 128); - subgroup_size = req_subgroup_size; - } else if (info->flags & VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT || - vk_spirv_version(spirv_data, spirv_size) >= 0x10600) { - /* Starting with SPIR-V 1.6, varying subgroup size the default */ - subgroup_size = SUBGROUP_SIZE_VARYING; - } else if (info->flags & VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT) { - assert(stage == MESA_SHADER_COMPUTE); - subgroup_size = SUBGROUP_SIZE_FULL_SUBGROUPS; - } else { - subgroup_size = SUBGROUP_SIZE_API_CONSTANT; - } + enum gl_subgroup_size subgroup_size = vk_get_subgroup_size( + vk_spirv_version(spirv_data, spirv_size), + stage, info->pNext, + info->flags & VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT, + info->flags & VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT); nir_shader *nir = vk_spirv_to_nir(device, spirv_data, spirv_size, stage, info->pName, subgroup_size, diff --git a/src/vulkan/runtime/vk_pipeline.h b/src/vulkan/runtime/vk_pipeline.h index 1ca32a1428e..b003e414426 100644 --- a/src/vulkan/runtime/vk_pipeline.h +++ b/src/vulkan/runtime/vk_pipeline.h @@ -60,6 +60,13 @@ vk_pipeline_shader_stage_to_nir(struct vk_device *device, const struct nir_shader_compiler_options *nir_options, void *mem_ctx, struct nir_shader **nir_out); +enum gl_subgroup_size +vk_get_subgroup_size(uint32_t spirv_version, + gl_shader_stage stage, + const void *info_pNext, + bool allow_varying, + bool require_full); + struct vk_pipeline_robustness_state { VkPipelineRobustnessBufferBehaviorEXT storage_buffers; VkPipelineRobustnessBufferBehaviorEXT uniform_buffers;