From 2f729ff6aaedcc3f4584830c2f88da2402b76ce7 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Tue, 13 Jun 2023 13:43:13 -0700 Subject: [PATCH] venus: suballocate feedback slot with feedback buffer alignment Venus sync feedback design relies on concurrent host device resource access. To avoid device flush overwriting host writes, we must suballocate the slots with a minimum size of the buffer alignment. Cc: mesa-stable Signed-off-by: Yiwei Zhang Part-of: --- src/virtio/vulkan/vn_feedback.c | 19 +++++++++++++++---- src/virtio/vulkan/vn_feedback.h | 2 ++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/virtio/vulkan/vn_feedback.c b/src/virtio/vulkan/vn_feedback.c index 97c1a233222..330ff4e27ef 100644 --- a/src/virtio/vulkan/vn_feedback.c +++ b/src/virtio/vulkan/vn_feedback.c @@ -141,6 +141,13 @@ vn_feedback_buffer_destroy(struct vn_device *dev, vk_free(alloc, feedback_buf); } +static inline uint32_t +vn_get_feedback_buffer_alignment(struct vn_feedback_buffer *feedback_buf) +{ + struct vn_buffer *buf = vn_buffer_from_handle(feedback_buf->buffer); + return buf->requirements.memory.memoryRequirements.alignment; +} + static VkResult vn_feedback_pool_grow_locked(struct vn_feedback_pool *pool) { @@ -154,6 +161,7 @@ vn_feedback_pool_grow_locked(struct vn_feedback_pool *pool) return result; pool->used = 0; + pool->alignment = vn_get_feedback_buffer_alignment(feedback_buf); list_add(&feedback_buf->head, &pool->feedback_buffers); @@ -172,6 +180,7 @@ vn_feedback_pool_init(struct vn_device *dev, pool->alloc = alloc; pool->size = size; pool->used = size; + pool->alignment = 1; list_inithead(&pool->feedback_buffers); list_inithead(&pool->free_slots); @@ -198,18 +207,20 @@ vn_feedback_pool_alloc_locked(struct vn_feedback_pool *pool, uint32_t *out_offset) { VN_TRACE_FUNC(); - const uint32_t aligned_size = align(size, 4); - if (unlikely(aligned_size > pool->size - pool->used)) { + /* Default values of pool->used and pool->alignment are used to trigger the + * initial pool grow, and will be properly initialized after that. + */ + if (unlikely(align(size, pool->alignment) > pool->size - pool->used)) { VkResult result = vn_feedback_pool_grow_locked(pool); if (result != VK_SUCCESS) return NULL; - assert(aligned_size <= pool->size - pool->used); + assert(align(size, pool->alignment) <= pool->size - pool->used); } *out_offset = pool->used; - pool->used += aligned_size; + pool->used += align(size, pool->alignment); return list_first_entry(&pool->feedback_buffers, struct vn_feedback_buffer, head); diff --git a/src/virtio/vulkan/vn_feedback.h b/src/virtio/vulkan/vn_feedback.h index d1a0947c228..097b7b74102 100644 --- a/src/virtio/vulkan/vn_feedback.h +++ b/src/virtio/vulkan/vn_feedback.h @@ -19,6 +19,8 @@ struct vn_feedback_pool { uint32_t size; /* size in bytes used of the active feedback buffer */ uint32_t used; + /* alignment in bytes for slot suballocation from the feedback buffer */ + uint32_t alignment; /* first entry is the active feedback buffer */ struct list_head feedback_buffers;