diff --git a/src/panfrost/vulkan/panvk_vX_descriptor_set.c b/src/panfrost/vulkan/panvk_vX_descriptor_set.c index 7bd8a6ebd72..0ba8ac8c00e 100644 --- a/src/panfrost/vulkan/panvk_vX_descriptor_set.c +++ b/src/panfrost/vulkan/panvk_vX_descriptor_set.c @@ -1,5 +1,6 @@ /* * Copyright © 2024 Collabora Ltd. + * Copyright © 2025 Arm Ltd. * SPDX-License-Identifier: MIT */ @@ -674,7 +675,9 @@ panvk_descriptor_set_copy(const VkCopyDescriptorSet *copy) const struct panvk_descriptor_set_binding_layout *src_binding_layout = &src_set->layout->bindings[copy->srcBinding]; - assert(dst_binding_layout->type == src_binding_layout->type); + const bool src_mutable = src_binding_layout->type == VK_DESCRIPTOR_TYPE_MUTABLE_EXT; + const bool dst_mutable = dst_binding_layout->type == VK_DESCRIPTOR_TYPE_MUTABLE_EXT; + assert(dst_binding_layout->type == src_binding_layout->type || src_mutable || dst_mutable); switch (src_binding_layout->type) { case VK_DESCRIPTOR_TYPE_SAMPLER: @@ -686,6 +689,7 @@ panvk_descriptor_set_copy(const VkCopyDescriptorSet *copy) case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_MUTABLE_EXT: for (uint32_t i = 0; i < copy->descriptorCount; i++) { void *dst = get_desc_slot_ptr(dst_set, copy->dstBinding, copy->dstArrayElement + i, diff --git a/src/panfrost/vulkan/panvk_vX_descriptor_set_layout.c b/src/panfrost/vulkan/panvk_vX_descriptor_set_layout.c index 940b983d5fb..759c7292dba 100644 --- a/src/panfrost/vulkan/panvk_vX_descriptor_set_layout.c +++ b/src/panfrost/vulkan/panvk_vX_descriptor_set_layout.c @@ -1,5 +1,6 @@ /* * Copyright © 2024 Collabora Ltd. + * Copyright © 2025 Arm Ltd. * SPDX-License-Identifier: MIT */ @@ -237,6 +238,32 @@ panvk_per_arch(CreateDescriptorSetLayout)( return VK_SUCCESS; } +static bool +is_supported_mutable_type(VkDescriptorType t) +{ + switch (t) { + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + return true; + default: + return false; + } +} + +static bool +is_mutable_type_list_supported(const VkMutableDescriptorTypeListEXT *const lst) +{ + for (uint32_t i = 0; i < lst->descriptorTypeCount; i++) { + if (!is_supported_mutable_type(lst->pDescriptorTypes[i])) + return false; + } + return true; +} + void panvk_per_arch(GetDescriptorSetLayoutSupport)( VkDevice _device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, @@ -249,6 +276,9 @@ panvk_per_arch(GetDescriptorSetLayoutSupport)( vk_find_struct(pSupport->pNext, DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT); + const VkMutableDescriptorTypeCreateInfoEXT *mut_info = vk_find_struct_const( + pCreateInfo->pNext, MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT); + pSupport->supported = false; unsigned desc_count = 0, dyn_buf_count = 0, non_variable_count = 0, @@ -266,6 +296,16 @@ panvk_per_arch(GetDescriptorSetLayoutSupport)( continue; } + if (binding->descriptorType == VK_DESCRIPTOR_TYPE_MUTABLE_EXT) { + /* VUID-VkDescriptorSetLayoutCreateInfo-pBindings-07303 */ + assert(mut_info->mutableDescriptorTypeListCount > i); + if (!is_mutable_type_list_supported( + &mut_info->pMutableDescriptorTypeLists[i])) { + pSupport->supported = false; + return; + } + } + unsigned textures_per_desc = is_texture(type) ? 1 : 0; unsigned samplers_per_desc = is_sampler(type) ? 1 : 0; if (binding_has_immutable_samplers(binding)) { diff --git a/src/panfrost/vulkan/panvk_vX_nir_lower_descriptors.c b/src/panfrost/vulkan/panvk_vX_nir_lower_descriptors.c index f689b565a37..2c7cc5f99d0 100644 --- a/src/panfrost/vulkan/panvk_vX_nir_lower_descriptors.c +++ b/src/panfrost/vulkan/panvk_vX_nir_lower_descriptors.c @@ -218,10 +218,14 @@ shader_desc_idx(uint32_t set, uint32_t binding, static nir_address_format addr_format_for_type(VkDescriptorType type, const struct lower_desc_ctx *ctx) { + /* Mutable must imply that both formats are the same. */ + assert(type != VK_DESCRIPTOR_TYPE_MUTABLE_EXT || ctx->ubo_addr_format == ctx->ssbo_addr_format); + switch (type) { case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: + case VK_DESCRIPTOR_TYPE_MUTABLE_EXT: return ctx->ubo_addr_format; case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: @@ -858,7 +862,8 @@ get_img_index(nir_builder *b, nir_deref_instr *deref, get_binding_layout(set, binding, ctx); assert(bind_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || bind_layout->type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || - bind_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER); + bind_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER || + bind_layout->type == VK_DESCRIPTOR_TYPE_MUTABLE_EXT); unsigned img_offset = shader_desc_idx(set, binding, NO_SUBDESC, ctx);