From b05ffc9feca72de7ae3e4ea74c8cdee400e39084 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 23 Sep 2021 15:13:21 +0200 Subject: [PATCH] panvk: Add support for storage buffers Signed-off-by: Boris Brezillon Reviewed-by: Jason Ekstrand Part-of: --- src/panfrost/vulkan/panvk_cmd_buffer.c | 5 ++- src/panfrost/vulkan/panvk_descriptor_set.c | 1 + src/panfrost/vulkan/panvk_private.h | 11 ++++- src/panfrost/vulkan/panvk_vX_cmd_buffer.c | 45 ++++++++++++++++--- src/panfrost/vulkan/panvk_vX_descriptor_set.c | 25 +++++++++++ src/panfrost/vulkan/panvk_vX_pipeline.c | 3 ++ 6 files changed, 83 insertions(+), 7 deletions(-) diff --git a/src/panfrost/vulkan/panvk_cmd_buffer.c b/src/panfrost/vulkan/panvk_cmd_buffer.c index e985eb05028..0f432ff2595 100644 --- a/src/panfrost/vulkan/panvk_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_cmd_buffer.c @@ -100,7 +100,10 @@ panvk_CmdBindDescriptorSets(VkCommandBuffer commandBuffer, pDynamicOffsets += set->layout->num_dynoffsets; } - if (set->layout->num_ubos || set->layout->num_dynoffsets) + if (set->layout->num_ssbos) + descriptors_state->dirty |= PANVK_DYNAMIC_SSBO; + + if (set->layout->num_ubos || set->layout->num_ssbos || set->layout->num_dynoffsets) descriptors_state->ubos = 0; if (set->layout->num_textures) diff --git a/src/panfrost/vulkan/panvk_descriptor_set.c b/src/panfrost/vulkan/panvk_descriptor_set.c index 614ad20e40b..f8c182ea1d0 100644 --- a/src/panfrost/vulkan/panvk_descriptor_set.c +++ b/src/panfrost/vulkan/panvk_descriptor_set.c @@ -436,6 +436,7 @@ panvk_descriptor_set_destroy(struct panvk_device *device, vk_free(&device->vk.alloc, set->textures); vk_free(&device->vk.alloc, set->samplers); vk_free(&device->vk.alloc, set->ubos); + vk_free(&device->vk.alloc, set->ssbos); vk_free(&device->vk.alloc, set->descs); vk_object_free(&device->vk, NULL, set); } diff --git a/src/panfrost/vulkan/panvk_private.h b/src/panfrost/vulkan/panvk_private.h index e87889bc15c..38510f16915 100644 --- a/src/panfrost/vulkan/panvk_private.h +++ b/src/panfrost/vulkan/panvk_private.h @@ -345,11 +345,18 @@ struct panvk_descriptor { }; }; +struct panvk_buffer_desc { + struct panvk_buffer *buffer; + VkDeviceSize offset; + VkDeviceSize size; +}; + struct panvk_descriptor_set { struct vk_object_base base; struct panvk_descriptor_pool *pool; const struct panvk_descriptor_set_layout *layout; struct panvk_descriptor *descs; + struct panvk_buffer_desc *ssbos; void *ubos; void *samplers; void *textures; @@ -478,10 +485,12 @@ enum panvk_dynamic_state_bits { PANVK_DYNAMIC_STENCIL_WRITE_MASK = 1 << 7, PANVK_DYNAMIC_STENCIL_REFERENCE = 1 << 8, PANVK_DYNAMIC_DISCARD_RECTANGLE = 1 << 9, - PANVK_DYNAMIC_ALL = (1 << 10) - 1, + PANVK_DYNAMIC_SSBO = 1 << 10, + PANVK_DYNAMIC_ALL = (1 << 11) - 1, }; struct panvk_descriptor_state { + uint32_t dirty; struct { const struct panvk_descriptor_set *set; struct panfrost_ptr dynoffsets; diff --git a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c index 799df94e5e7..2e50a897b0a 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c @@ -293,9 +293,35 @@ panvk_per_arch(cmd_alloc_tls_desc)(struct panvk_cmd_buffer *cmdbuf, bool gfx) } } +static void +panvk_sysval_upload_ssbo_info(struct panvk_cmd_buffer *cmdbuf, + unsigned ssbo_id, + struct panvk_cmd_bind_point_state *bind_point_state, + union panvk_sysval_data *data) +{ + const struct panvk_pipeline *pipeline = bind_point_state->pipeline; + const struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state; + + for (unsigned s = 0; s < pipeline->layout->num_sets; s++) { + unsigned ssbo_offset = pipeline->layout->sets[s].ssbo_offset; + unsigned num_ssbos = pipeline->layout->sets[s].layout->num_ssbos; + const struct panvk_buffer_desc *ssbo = NULL; + + if (ssbo_id >= ssbo_offset && ssbo_id < (ssbo_offset + num_ssbos)) + ssbo = &desc_state->sets[s].set->ssbos[ssbo_id - ssbo_offset]; + + if (ssbo) { + data->u64[0] = ssbo->buffer->bo->ptr.gpu + ssbo->offset; + data->u32[2] = ssbo->size == VK_WHOLE_SIZE ? ssbo->buffer->size - ssbo->offset : ssbo->size; + } + } +} + static void panvk_cmd_upload_sysval(struct panvk_cmd_buffer *cmdbuf, - unsigned id, union panvk_sysval_data *data) + unsigned id, + struct panvk_cmd_bind_point_state *bind_point_state, + union panvk_sysval_data *data) { switch (PAN_SYSVAL_TYPE(id)) { case PAN_SYSVAL_VIEWPORT_SCALE: @@ -311,6 +337,14 @@ panvk_cmd_upload_sysval(struct panvk_cmd_buffer *cmdbuf, case PAN_SYSVAL_BLEND_CONSTANTS: memcpy(data->f32, cmdbuf->state.blend.constants, sizeof(data->f32)); break; + case PAN_SYSVAL_SSBO: + /* This won't work with dynamic SSBO indexing. We might want to + * consider storing SSBO mappings in a separate UBO if we need to + * support + * VkPhysicalDeviceVulkan12Features.shaderStorageBufferArrayNonUniformIndexing. + */ + panvk_sysval_upload_ssbo_info(cmdbuf, PAN_SYSVAL_ID(id), bind_point_state, data); + break; default: unreachable("Invalid static sysval"); } @@ -326,11 +360,12 @@ panvk_cmd_prepare_sysvals(struct panvk_cmd_buffer *cmdbuf, if (!pipeline->num_sysvals) return; + uint32_t dirty = cmdbuf->state.dirty | desc_state->dirty; + for (unsigned i = 0; i < ARRAY_SIZE(desc_state->sysvals); i++) { unsigned sysval_count = pipeline->sysvals[i].ids.sysval_count; if (!sysval_count || pipeline->sysvals[i].ubo || - (desc_state->sysvals[i] && - !(cmdbuf->state.dirty & pipeline->sysvals[i].dirty_mask))) + (desc_state->sysvals[i] && !(dirty & pipeline->sysvals[i].dirty_mask))) continue; struct panfrost_ptr sysvals = @@ -339,7 +374,7 @@ panvk_cmd_prepare_sysvals(struct panvk_cmd_buffer *cmdbuf, for (unsigned s = 0; s < pipeline->sysvals[i].ids.sysval_count; s++) { panvk_cmd_upload_sysval(cmdbuf, pipeline->sysvals[i].ids.sysvals[s], - &data[s]); + bind_point_state, &data[s]); } desc_state->sysvals[i] = sysvals.gpu; @@ -782,7 +817,7 @@ panvk_per_arch(CmdDraw)(VkCommandBuffer commandBuffer, } /* Clear the dirty flags all at once */ - cmdbuf->state.dirty = 0; + desc_state->dirty = cmdbuf->state.dirty = 0; } VkResult diff --git a/src/panfrost/vulkan/panvk_vX_descriptor_set.c b/src/panfrost/vulkan/panvk_vX_descriptor_set.c index ad17175c667..ea816aa4867 100644 --- a/src/panfrost/vulkan/panvk_vX_descriptor_set.c +++ b/src/panfrost/vulkan/panvk_vX_descriptor_set.c @@ -72,6 +72,14 @@ panvk_per_arch(descriptor_set_create)(struct panvk_device *device, goto err_free_set; } + if (layout->num_ssbos) { + set->ssbos = vk_zalloc(&device->vk.alloc, + sizeof(*set->ssbos) * layout->num_ssbos, 8, + VK_OBJECT_TYPE_DESCRIPTOR_SET); + if (!set->ssbos) + goto err_free_set; + } + if (layout->num_samplers) { set->samplers = vk_zalloc(&device->vk.alloc, pan_size(SAMPLER) * layout->num_samplers, 8, @@ -106,6 +114,7 @@ panvk_per_arch(descriptor_set_create)(struct panvk_device *device, err_free_set: vk_free(&device->vk.alloc, set->textures); vk_free(&device->vk.alloc, set->samplers); + vk_free(&device->vk.alloc, set->ssbos); vk_free(&device->vk.alloc, set->ubos); vk_free(&device->vk.alloc, set->descs); vk_object_free(&device->vk, NULL, set); @@ -173,6 +182,17 @@ panvk_set_buffer_info_desc(struct panvk_descriptor *desc, desc->buffer_info.range = pBufferInfo->range; } +static void +panvk_set_buffer_desc(struct panvk_buffer_desc *bdesc, + const VkDescriptorBufferInfo *pBufferInfo) +{ + VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer); + + bdesc->buffer = buffer; + bdesc->offset = pBufferInfo->offset; + bdesc->size = pBufferInfo->range; +} + static void panvk_per_arch(set_ubo_desc)(void *ubo, const VkDescriptorBufferInfo *pBufferInfo) @@ -284,6 +304,11 @@ panvk_per_arch(write_descriptor_set)(struct panvk_device *dev, break; case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + for (unsigned i = 0; i < ndescs; i++) { + unsigned ssbo = binding_layout->ssbo_idx + dest_offset + i; + panvk_set_buffer_desc(&set->ssbos[ssbo], &pDescriptorWrite->pBufferInfo[src_offset + i]); + } + break; case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: for (unsigned i = 0; i < ndescs; i++) panvk_set_buffer_info_desc(&descs[i], &pDescriptorWrite->pBufferInfo[src_offset + i]); diff --git a/src/panfrost/vulkan/panvk_vX_pipeline.c b/src/panfrost/vulkan/panvk_vX_pipeline.c index 844cbb7ce62..089de93f1aa 100644 --- a/src/panfrost/vulkan/panvk_vX_pipeline.c +++ b/src/panfrost/vulkan/panvk_vX_pipeline.c @@ -230,6 +230,9 @@ panvk_pipeline_builder_alloc_static_state_bo(struct panvk_pipeline_builder *buil case PAN_SYSVAL_VIEWPORT_OFFSET: pipeline->sysvals[i].dirty_mask |= PANVK_DYNAMIC_VIEWPORT; break; + case PAN_SYSVAL_SSBO: + pipeline->sysvals[i].dirty_mask |= PANVK_DYNAMIC_SSBO; + break; default: break; }