From 42aca84704a36a6a9c52552c4dde77ef4c528a69 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Wed, 27 Apr 2022 16:03:52 -0500 Subject: [PATCH] panvk: Add a buffer to each descriptor set Later in the series, we will map descriptor sets to driver-internal buffers bound as UBOs. These buffers will contain various internal data, like buffer and texture sizes. Resource access will be lowered to pull from this UBO in the shader. To prepare, create a backing buffer when creating descriptor set and emit a UBO record so we can bind it. Reviewed-by: Alyssa Rosenzweig Part-of: --- src/panfrost/vulkan/panvk_descriptor_set.c | 2 ++ src/panfrost/vulkan/panvk_private.h | 14 ++++++++++ src/panfrost/vulkan/panvk_vX_descriptor_set.c | 26 +++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/src/panfrost/vulkan/panvk_descriptor_set.c b/src/panfrost/vulkan/panvk_descriptor_set.c index a152bd5e7e8..0d1494e6c0d 100644 --- a/src/panfrost/vulkan/panvk_descriptor_set.c +++ b/src/panfrost/vulkan/panvk_descriptor_set.c @@ -357,6 +357,8 @@ panvk_descriptor_set_destroy(struct panvk_device *device, vk_free(&device->vk.alloc, set->img_fmts); vk_free(&device->vk.alloc, set->img_attrib_bufs); vk_free(&device->vk.alloc, set->descs); + if (set->desc_bo) + panfrost_bo_unreference(set->desc_bo); vk_object_free(&device->vk, NULL, set); } diff --git a/src/panfrost/vulkan/panvk_private.h b/src/panfrost/vulkan/panvk_private.h index 8595c9dbedf..6b2d4755494 100644 --- a/src/panfrost/vulkan/panvk_private.h +++ b/src/panfrost/vulkan/panvk_private.h @@ -349,6 +349,8 @@ struct panvk_descriptor_set { void *textures; void *img_attrib_bufs; uint32_t *img_fmts; + + struct panfrost_bo *desc_bo; }; #define MAX_SETS 4 @@ -375,6 +377,12 @@ struct panvk_descriptor_set_binding_layout { unsigned dyn_ubo_idx; }; + /* Offset into the descriptor UBO where this binding starts */ + uint32_t desc_ubo_offset; + + /* Stride between descriptors in this binding in the UBO */ + uint16_t desc_ubo_stride; + /* Shader stages affected by this set+binding */ uint16_t shader_stages; @@ -400,6 +408,12 @@ struct panvk_descriptor_set_layout { unsigned num_dyn_ssbos; unsigned num_imgs; + /* Size of the descriptor UBO */ + uint32_t desc_ubo_size; + + /* Index of the descriptor UBO */ + unsigned desc_ubo_index; + /* Number of bindings in this descriptor set */ uint32_t binding_count; diff --git a/src/panfrost/vulkan/panvk_vX_descriptor_set.c b/src/panfrost/vulkan/panvk_vX_descriptor_set.c index f11f8dd040a..fa8d50bf5fa 100644 --- a/src/panfrost/vulkan/panvk_vX_descriptor_set.c +++ b/src/panfrost/vulkan/panvk_vX_descriptor_set.c @@ -92,6 +92,7 @@ panvk_per_arch(CreateDescriptorSetLayout)(VkDevice _device, unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0, ssbo_idx = 0; unsigned dyn_ubo_idx = 0, dyn_ssbo_idx = 0, desc_idx = 0, img_idx = 0; + uint32_t desc_ubo_size = 0; for (unsigned i = 0; i < pCreateInfo->bindingCount; i++) { const VkDescriptorSetLayoutBinding *binding = &bindings[i]; @@ -101,6 +102,7 @@ panvk_per_arch(CreateDescriptorSetLayout)(VkDevice _device, binding_layout->type = binding->descriptorType; binding_layout->array_size = binding->descriptorCount; binding_layout->shader_stages = binding->stageFlags; + binding_layout->desc_ubo_stride = 0; if (binding->pImmutableSamplers) { binding_layout->immutable_samplers = immutable_samplers; immutable_samplers += binding_layout->array_size; @@ -159,8 +161,16 @@ panvk_per_arch(CreateDescriptorSetLayout)(VkDevice _device, default: unreachable("Invalid descriptor type"); } + + binding_layout->desc_ubo_offset = desc_ubo_size; + desc_ubo_size += binding_layout->desc_ubo_stride * + binding_layout->array_size; } + set_layout->desc_ubo_size = desc_ubo_size; + if (desc_ubo_size > 0) + set_layout->desc_ubo_index = ubo_idx++; + set_layout->num_descs = desc_idx; set_layout->num_samplers = sampler_idx; set_layout->num_textures = tex_idx; @@ -278,6 +288,20 @@ panvk_per_arch(descriptor_set_create)(struct panvk_device *device, } } + if (layout->desc_ubo_size) { + set->desc_bo = panfrost_bo_create(&device->physical_device->pdev, + layout->desc_ubo_size, + 0, "Descriptor set"); + if (!set->desc_bo) + goto err_free_set; + + struct mali_uniform_buffer_packed *ubos = set->ubos; + + panvk_per_arch(emit_ubo)(set->desc_bo->ptr.gpu, + layout->desc_ubo_size, + &ubos[layout->desc_ubo_index]); + } + *out_set = set; return VK_SUCCESS; @@ -291,6 +315,8 @@ err_free_set: vk_free(&device->vk.alloc, set->img_fmts); vk_free(&device->vk.alloc, set->img_attrib_bufs); vk_free(&device->vk.alloc, set->descs); + if (set->desc_bo) + panfrost_bo_unreference(set->desc_bo); vk_object_free(&device->vk, NULL, set); return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); }