From ba3c4ce3852af72697d199dee1187f31dc7d92e8 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 13 May 2021 14:54:43 -0400 Subject: [PATCH] zink: add mechanism for generating VkBuffers for rebinding Reviewed-by: Dave Airlie Part-of: --- src/gallium/drivers/zink/zink_resource.c | 41 ++++++++++++++++++------ src/gallium/drivers/zink/zink_resource.h | 7 ++-- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index 3101a5a283e..7802a595358 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -138,13 +138,14 @@ void zink_destroy_resource_object(struct zink_screen *screen, struct zink_resource_object *obj) { if (obj->is_buffer) { - if (obj->sbuffer) - vkDestroyBuffer(screen->dev, obj->sbuffer, NULL); + util_dynarray_foreach(&obj->tmp, VkBuffer, buffer) + vkDestroyBuffer(screen->dev, *buffer, NULL); vkDestroyBuffer(screen->dev, obj->buffer, NULL); } else { vkDestroyImage(screen->dev, obj->image, NULL); } + util_dynarray_fini(&obj->tmp); zink_descriptor_set_refs_clear(&obj->desc_set_refs, obj); cache_or_free_mem(screen, obj); FREE(obj); @@ -515,6 +516,7 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t bool shared = (templ->bind & (PIPE_BIND_SHARED | PIPE_BIND_LINEAR)) == (PIPE_BIND_SHARED | PIPE_BIND_LINEAR); pipe_reference_init(&obj->reference, 1); + util_dynarray_init(&obj->tmp, NULL); util_dynarray_init(&obj->desc_set_refs.refs, NULL); if (templ->target == PIPE_BUFFER) { VkBufferCreateInfo bci = create_bci(screen, templ, templ->bind); @@ -638,6 +640,7 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t else flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; } + obj->alignment = reqs.alignment; if (templ->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT || templ->usage == PIPE_USAGE_DYNAMIC) flags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; @@ -1509,6 +1512,28 @@ zink_resource_get_separate_stencil(struct pipe_resource *pres) } +VkBuffer +zink_resource_tmp_buffer(struct zink_screen *screen, struct zink_resource *res, unsigned offset_add, unsigned add_binds, unsigned *offset_out) +{ + VkBufferCreateInfo bci = create_bci(screen, &res->base.b, res->base.b.bind | add_binds); + VkDeviceSize size = bci.size - offset_add; + VkDeviceSize offset = offset_add; + if (offset_add) { + assert(bci.size > offset_add); + + align_offset_size(res->obj->alignment, &offset, &size, bci.size); + } + bci.size = size; + + VkBuffer buffer; + if (vkCreateBuffer(screen->dev, &bci, NULL, &buffer) != VK_SUCCESS) + return VK_NULL_HANDLE; + vkBindBufferMemory(screen->dev, buffer, res->obj->mem, res->obj->offset + offset); + if (offset_out) + *offset_out = offset_add - offset; + return buffer; +} + bool zink_resource_object_init_storage(struct zink_context *ctx, struct zink_resource *res) { @@ -1517,17 +1542,15 @@ zink_resource_object_init_storage(struct zink_context *ctx, struct zink_resource if (res->base.b.bind & PIPE_BIND_SHADER_IMAGE) return true; if (res->obj->is_buffer) { - if (res->obj->sbuffer) + if (res->base.b.bind & PIPE_BIND_SHADER_IMAGE) return true; - VkBufferCreateInfo bci = create_bci(screen, &res->base.b, res->base.b.bind | PIPE_BIND_SHADER_IMAGE); - bci.size = res->obj->size; - VkBuffer buffer; - if (vkCreateBuffer(screen->dev, &bci, NULL, &buffer) != VK_SUCCESS) + VkBuffer buffer = zink_resource_tmp_buffer(screen, res, 0, PIPE_BIND_SHADER_IMAGE, NULL); + if (!buffer) return false; - vkBindBufferMemory(screen->dev, buffer, res->obj->mem, res->obj->offset); - res->obj->sbuffer = res->obj->buffer; + util_dynarray_append(&res->obj->tmp, VkBuffer, res->obj->buffer); res->obj->buffer = buffer; + res->base.b.bind |= PIPE_BIND_SHADER_IMAGE; } else { zink_fb_clears_apply_region(ctx, &res->base.b, (struct u_rect){0, res->base.b.width0, 0, res->base.b.height0}); zink_resource_image_barrier(ctx, NULL, res, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 0, 0); diff --git a/src/gallium/drivers/zink/zink_resource.h b/src/gallium/drivers/zink/zink_resource.h index 62e65ae4222..406b7d70b81 100644 --- a/src/gallium/drivers/zink/zink_resource.h +++ b/src/gallium/drivers/zink/zink_resource.h @@ -65,7 +65,7 @@ struct zink_resource_object { VkImage image; }; - VkBuffer sbuffer; + struct util_dynarray tmp; bool storage_init; //layout was set for image bool transfer_dst; VkImageAspectFlags modifier_aspect; @@ -73,7 +73,7 @@ struct zink_resource_object { VkDeviceMemory mem; uint32_t mem_hash; struct mem_key mkey; - VkDeviceSize offset, size; + VkDeviceSize offset, size, alignment; VkSampleLocationsInfoEXT zs_evaluate; bool needs_zs_evaluate; @@ -183,6 +183,9 @@ zink_resource_object_reference(struct zink_screen *screen, if (dst) *dst = src; } +VkBuffer +zink_resource_tmp_buffer(struct zink_screen *screen, struct zink_resource *res, unsigned offset_add, unsigned add_binds, unsigned *offset); + bool zink_resource_object_init_storage(struct zink_context *ctx, struct zink_resource *res); #endif