From 2ec6527c70a04c27dca36ffab7e9e2ddb317eb18 Mon Sep 17 00:00:00 2001 From: Christoph Pillmayer Date: Tue, 3 Jun 2025 09:57:50 +0000 Subject: [PATCH] panvk: Implement VK_EXT_inline_uniform_block Inline uniforms blocks are implemented as a buffer descriptor followed by the actual inlined data. Reviewed-by: Boris Brezillon Part-of: --- src/panfrost/vulkan/panvk_vX_descriptor_set.c | 81 +++++++++++++++++++ .../vulkan/panvk_vX_descriptor_set_layout.c | 10 ++- .../vulkan/panvk_vX_nir_lower_descriptors.c | 2 + 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/panfrost/vulkan/panvk_vX_descriptor_set.c b/src/panfrost/vulkan/panvk_vX_descriptor_set.c index 932839e0102..cc00848a4d0 100644 --- a/src/panfrost/vulkan/panvk_vX_descriptor_set.c +++ b/src/panfrost/vulkan/panvk_vX_descriptor_set.c @@ -192,6 +192,22 @@ write_buffer_view_desc(struct panvk_descriptor_set *set, } } +static void +write_iub(struct panvk_descriptor_set *set, uint32_t binding, + uint32_t dst_offset, uint32_t count, const void *data) +{ + const struct panvk_descriptor_set_binding_layout *binding_layout = + &set->layout->bindings[binding]; + + /* First slot is the actual buffer descriptor. */ + uint32_t iub_data_offset = + panvk_get_desc_index(binding_layout, 1, NO_SUBDESC) * + PANVK_DESCRIPTOR_SIZE; + + void *iub_data_host = set->descs.host + iub_data_offset; + memcpy(iub_data_host + dst_offset, data, count); +} + static void panvk_desc_pool_free_set(struct panvk_descriptor_pool *pool, struct panvk_descriptor_set *set) @@ -334,6 +350,42 @@ desc_set_write_immutable_samplers(struct panvk_descriptor_set *set, } } +static void +panvk_init_iub(struct panvk_descriptor_set *set, uint32_t binding) +{ + const struct panvk_descriptor_set_binding_layout *binding_layout = + &set->layout->bindings[binding]; + + /* The first element is the buffer descriptor. */ + uint32_t iub_data_offset = + panvk_get_desc_index(binding_layout, 1, NO_SUBDESC) * + PANVK_DESCRIPTOR_SIZE; + uint64_t iub_data_dev = set->descs.dev + iub_data_offset; + uint32_t iub_size_dev = + (binding_layout->desc_count - 1) * PANVK_DESCRIPTOR_SIZE; + +#if PAN_ARCH <= 7 + struct { + struct mali_uniform_buffer_packed ubo; + uint32_t pad[6]; + } padded_desc = {0}; + + pan_pack(&padded_desc.ubo, UNIFORM_BUFFER, cfg) { + cfg.pointer = iub_data_dev; + cfg.entries = iub_size_dev; + } + write_desc(set, binding, 0, &padded_desc, NO_SUBDESC); +#else + struct mali_buffer_packed desc; + + pan_pack(&desc, BUFFER, cfg) { + cfg.address = iub_data_dev; + cfg.size = iub_size_dev; + } + write_desc(set, binding, 0, &desc, NO_SUBDESC); +#endif +} + static VkResult panvk_desc_pool_allocate_set(struct panvk_descriptor_pool *pool, struct panvk_descriptor_set_layout *layout, @@ -384,6 +436,11 @@ panvk_desc_pool_allocate_set(struct panvk_descriptor_pool *pool, desc_set_write_immutable_samplers(set, variable_count); BITSET_CLEAR(pool->free_sets, first_free_set - 1); + for (uint32_t b = 0; b < layout->binding_count; ++b) { + if (layout->bindings[b].type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) + panvk_init_iub(set, b); + } + *out = set; return VK_SUCCESS; } @@ -516,6 +573,15 @@ panvk_per_arch(descriptor_set_write)(struct panvk_descriptor_set *set, } break; + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: { + const VkWriteDescriptorSetInlineUniformBlock *inline_info = + vk_find_struct_const(write->pNext, + WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK); + write_iub(set, write->dstBinding, write->dstArrayElement, + write->descriptorCount, inline_info->pData); + break; + } + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: for (uint32_t j = 0; j < write->descriptorCount; j++) { @@ -582,6 +648,15 @@ panvk_descriptor_set_copy(const VkCopyDescriptorSet *copy) break; } + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: { + const void *src = + get_desc_slot_ptr(src_set, copy->srcBinding, 0, NO_SUBDESC); + src += PANVK_DESCRIPTOR_SIZE + copy->srcArrayElement; + write_iub(dst_set, copy->dstBinding, copy->dstArrayElement, + copy->descriptorCount, src); + break; + } + default: unreachable("Unsupported descriptor type"); } @@ -682,6 +757,12 @@ panvk_per_arch(descriptor_set_write_template)( entry->array_element + j); } break; + + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: + write_iub(set, entry->binding, entry->array_element, + entry->array_count, data + entry->offset); + break; + default: unreachable("Unsupported descriptor type"); } diff --git a/src/panfrost/vulkan/panvk_vX_descriptor_set_layout.c b/src/panfrost/vulkan/panvk_vX_descriptor_set_layout.c index 9d2783917bc..f46d26eb330 100644 --- a/src/panfrost/vulkan/panvk_vX_descriptor_set_layout.c +++ b/src/panfrost/vulkan/panvk_vX_descriptor_set_layout.c @@ -9,6 +9,7 @@ #include #include +#include "util/macros.h" #include "util/mesa-blake3.h" #include "vk_descriptor_update_template.h" @@ -156,7 +157,14 @@ panvk_per_arch(CreateDescriptorSetLayout)( binding_layout->flags = binding_flags_info->pBindingFlags[i]; } - binding_layout->desc_count = binding->descriptorCount; + if (binding_layout->type & VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) { + /* One extra descriptor at the start to use as a buffer descriptor. */ + binding_layout->desc_count = + DIV_ROUND_UP(binding->descriptorCount, PANVK_DESCRIPTOR_SIZE) + 1; + } else { + binding_layout->desc_count = binding->descriptorCount; + } + if (is_texture(binding_layout->type)) binding_layout->textures_per_desc = 1; diff --git a/src/panfrost/vulkan/panvk_vX_nir_lower_descriptors.c b/src/panfrost/vulkan/panvk_vX_nir_lower_descriptors.c index 1cdc7f0c0dc..dbeef47fdbf 100644 --- a/src/panfrost/vulkan/panvk_vX_nir_lower_descriptors.c +++ b/src/panfrost/vulkan/panvk_vX_nir_lower_descriptors.c @@ -140,6 +140,7 @@ desc_type_to_table_type( case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: return PANVK_BIFROST_DESC_TABLE_IMG; case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: return PANVK_BIFROST_DESC_TABLE_UBO; default: return PANVK_BIFROST_DESC_TABLE_INVALID; @@ -219,6 +220,7 @@ addr_format_for_type(VkDescriptorType type, const struct lower_desc_ctx *ctx) switch (type) { case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: return ctx->ubo_addr_format; case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: