Mesa (main): venus: add vn_feedback_pool backed by coherent buffer (part 2)
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Jun 16 19:06:12 UTC 2022
Module: Mesa
Branch: main
Commit: e52da323b03c1f6a419f647f5a6ddfb25903b272
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=e52da323b03c1f6a419f647f5a6ddfb25903b272
Author: Yiwei Zhang <zzyiwei at chromium.org>
Date: Fri May 20 06:38:09 2022 +0000
venus: add vn_feedback_pool backed by coherent buffer (part 2)
Implemented:
- vn_feedback_pool_alloc
- vn_feedback_pool_free
Signed-off-by: Yiwei Zhang <zzyiwei at chromium.org>
Reviewed-by: Ryan Neph <ryanneph at google.com>
Reviewed-by: Chad Versace <chadversary at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16731>
---
src/virtio/vulkan/vn_feedback.c | 92 ++++++++++++++++++++++++++++++++++++++++-
src/virtio/vulkan/vn_feedback.h | 34 +++++++++++++++
2 files changed, 124 insertions(+), 2 deletions(-)
diff --git a/src/virtio/vulkan/vn_feedback.c b/src/virtio/vulkan/vn_feedback.c
index bb7d6927a10..cdfdca9db3b 100644
--- a/src/virtio/vulkan/vn_feedback.c
+++ b/src/virtio/vulkan/vn_feedback.c
@@ -135,7 +135,7 @@ vn_feedback_buffer_destroy(struct vn_device *dev,
}
static VkResult
-vn_feedback_pool_grow(struct vn_feedback_pool *pool)
+vn_feedback_pool_grow_locked(struct vn_feedback_pool *pool)
{
VN_TRACE_FUNC();
struct vn_feedback_buffer *feedback_buf = NULL;
@@ -159,19 +159,107 @@ vn_feedback_pool_init(struct vn_device *dev,
uint32_t size,
const VkAllocationCallbacks *alloc)
{
+ simple_mtx_init(&pool->mutex, mtx_plain);
+
pool->device = dev;
pool->alloc = alloc;
pool->size = size;
pool->used = size;
list_inithead(&pool->feedback_buffers);
+ list_inithead(&pool->free_slots);
- return vn_feedback_pool_grow(pool);
+ /* no lock needed upon init */
+ return vn_feedback_pool_grow_locked(pool);
}
void
vn_feedback_pool_fini(struct vn_feedback_pool *pool)
{
+ list_for_each_entry_safe(struct vn_feedback_slot, slot, &pool->free_slots,
+ head)
+ vk_free(pool->alloc, slot);
+
list_for_each_entry_safe(struct vn_feedback_buffer, feedback_buf,
&pool->feedback_buffers, head)
vn_feedback_buffer_destroy(pool->device, feedback_buf, pool->alloc);
+
+ simple_mtx_destroy(&pool->mutex);
+}
+
+static struct vn_feedback_buffer *
+vn_feedback_pool_alloc_locked(struct vn_feedback_pool *pool,
+ uint32_t size,
+ uint32_t *out_offset)
+{
+ VN_TRACE_FUNC();
+ const uint32_t aligned_size = align(size, 4);
+
+ if (unlikely(aligned_size > 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);
+ }
+
+ *out_offset = pool->used;
+ pool->used += aligned_size;
+
+ return list_first_entry(&pool->feedback_buffers, struct vn_feedback_buffer,
+ head);
+}
+
+struct vn_feedback_slot *
+vn_feedback_pool_alloc(struct vn_feedback_pool *pool,
+ enum vn_feedback_type type)
+{
+ /* TODO Make slot size variable for VkQueryPool feedback. Currently it's
+ * MAX2(sizeof(VkResult), sizeof(uint64_t)).
+ */
+ static const uint32_t slot_size = 8;
+ struct vn_feedback_buffer *feedback_buf;
+ uint32_t offset;
+ struct vn_feedback_slot *slot;
+
+ simple_mtx_lock(&pool->mutex);
+ if (!list_is_empty(&pool->free_slots)) {
+ slot =
+ list_first_entry(&pool->free_slots, struct vn_feedback_slot, head);
+ list_del(&slot->head);
+ simple_mtx_unlock(&pool->mutex);
+
+ slot->type = type;
+ return slot;
+ }
+
+ slot = vk_alloc(pool->alloc, sizeof(*slot), VN_DEFAULT_ALIGN,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (!slot) {
+ simple_mtx_unlock(&pool->mutex);
+ return NULL;
+ }
+
+ feedback_buf = vn_feedback_pool_alloc_locked(pool, slot_size, &offset);
+ simple_mtx_unlock(&pool->mutex);
+
+ if (!feedback_buf) {
+ vk_free(pool->alloc, slot);
+ return NULL;
+ }
+
+ slot->type = type;
+ slot->offset = offset;
+ slot->buffer = feedback_buf->buffer;
+ slot->data = feedback_buf->data + offset;
+
+ return slot;
+}
+
+void
+vn_feedback_pool_free(struct vn_feedback_pool *pool,
+ struct vn_feedback_slot *slot)
+{
+ simple_mtx_lock(&pool->mutex);
+ list_add(&slot->head, &pool->free_slots);
+ simple_mtx_unlock(&pool->mutex);
}
diff --git a/src/virtio/vulkan/vn_feedback.h b/src/virtio/vulkan/vn_feedback.h
index 1120a7e5195..865f4e784f8 100644
--- a/src/virtio/vulkan/vn_feedback.h
+++ b/src/virtio/vulkan/vn_feedback.h
@@ -9,6 +9,9 @@
#include "vn_common.h"
struct vn_feedback_pool {
+ /* single lock for simplicity though free_slots can use another */
+ simple_mtx_t mutex;
+
struct vn_device *device;
const VkAllocationCallbacks *alloc;
@@ -19,6 +22,29 @@ struct vn_feedback_pool {
/* first entry is the active feedback buffer */
struct list_head feedback_buffers;
+
+ /* cache for returned feedback slots */
+ struct list_head free_slots;
+};
+
+enum vn_feedback_type {
+ VN_FEEDBACK_TYPE_FENCE,
+ VN_FEEDBACK_TYPE_TIMELINE_SEMAPHORE,
+ VN_FEEDBACK_TYPE_EVENT,
+};
+
+struct vn_feedback_slot {
+ enum vn_feedback_type type;
+ uint32_t offset;
+ VkBuffer buffer;
+
+ union {
+ void *data;
+ VkResult *status;
+ uint64_t *counter;
+ };
+
+ struct list_head head;
};
VkResult
@@ -30,4 +56,12 @@ vn_feedback_pool_init(struct vn_device *dev,
void
vn_feedback_pool_fini(struct vn_feedback_pool *pool);
+struct vn_feedback_slot *
+vn_feedback_pool_alloc(struct vn_feedback_pool *pool,
+ enum vn_feedback_type type);
+
+void
+vn_feedback_pool_free(struct vn_feedback_pool *pool,
+ struct vn_feedback_slot *slot);
+
#endif /* VN_FEEDBACK_H */
More information about the mesa-commit
mailing list