From 35c430e75a10c5ffcd6bce99dc657b196c7766f7 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 8 Dec 2021 15:32:19 -0800 Subject: [PATCH] venus: add vn_renderer_shmem_pool It provides shmem suballocations. It is designed to be used with short-lived shmems. A long-lived shmem can hold on to some large allocation while only using a likely small region of the large allocation. v2: cleanups suggested by Yiwei Signed-off-by: Chia-I Wu Reviewed-by: Ryan Neph (v1) Reviewed-by: Yiwei Zhang Part-of: --- src/virtio/vulkan/vn_renderer_util.c | 68 ++++++++++++++++++++++++++++ src/virtio/vulkan/vn_renderer_util.h | 24 ++++++++++ 2 files changed, 92 insertions(+) diff --git a/src/virtio/vulkan/vn_renderer_util.c b/src/virtio/vulkan/vn_renderer_util.c index 2eae0e697d5..656c0c1bcf3 100644 --- a/src/virtio/vulkan/vn_renderer_util.c +++ b/src/virtio/vulkan/vn_renderer_util.c @@ -43,3 +43,71 @@ vn_renderer_submit_simple_sync(struct vn_renderer *renderer, return result; } + +void +vn_renderer_shmem_pool_init(UNUSED struct vn_renderer *renderer, + struct vn_renderer_shmem_pool *pool, + size_t min_alloc_size) +{ + *pool = (struct vn_renderer_shmem_pool){ + /* power-of-two to hit shmem cache */ + .min_alloc_size = util_next_power_of_two(min_alloc_size), + }; +} + +void +vn_renderer_shmem_pool_fini(struct vn_renderer *renderer, + struct vn_renderer_shmem_pool *pool) +{ + if (pool->shmem) + vn_renderer_shmem_unref(renderer, pool->shmem); +} + +static bool +vn_renderer_shmem_pool_grow(struct vn_renderer *renderer, + struct vn_renderer_shmem_pool *pool, + size_t size) +{ + /* power-of-two to hit shmem cache */ + size_t alloc_size = pool->min_alloc_size; + while (alloc_size < size) { + alloc_size <<= 1; + if (!alloc_size) + return false; + } + + struct vn_renderer_shmem *shmem = + vn_renderer_shmem_create(renderer, alloc_size); + if (!shmem) + return false; + + if (pool->shmem) + vn_renderer_shmem_unref(renderer, pool->shmem); + + pool->shmem = shmem; + pool->size = alloc_size; + pool->used = 0; + + return true; +} + +struct vn_renderer_shmem * +vn_renderer_shmem_pool_alloc(struct vn_renderer *renderer, + struct vn_renderer_shmem_pool *pool, + size_t size, + size_t *out_offset) +{ + if (unlikely(size > pool->size - pool->used)) { + if (!vn_renderer_shmem_pool_grow(renderer, pool, size)) + return NULL; + + assert(size <= pool->size - pool->used); + } + + struct vn_renderer_shmem *shmem = + vn_renderer_shmem_ref(renderer, pool->shmem); + *out_offset = pool->used; + pool->used += size; + + return shmem; +} diff --git a/src/virtio/vulkan/vn_renderer_util.h b/src/virtio/vulkan/vn_renderer_util.h index cefe4bfc5e9..a5797907ac3 100644 --- a/src/virtio/vulkan/vn_renderer_util.h +++ b/src/virtio/vulkan/vn_renderer_util.h @@ -8,6 +8,15 @@ #include "vn_renderer.h" +/* for suballocations of short-lived shmems, not thread-safe */ +struct vn_renderer_shmem_pool { + size_t min_alloc_size; + + struct vn_renderer_shmem *shmem; + size_t size; + size_t used; +}; + static inline VkResult vn_renderer_submit_simple(struct vn_renderer *renderer, const void *cs_data, @@ -29,4 +38,19 @@ vn_renderer_submit_simple_sync(struct vn_renderer *renderer, const void *cs_data, size_t cs_size); +void +vn_renderer_shmem_pool_init(struct vn_renderer *renderer, + struct vn_renderer_shmem_pool *pool, + size_t min_alloc_size); + +void +vn_renderer_shmem_pool_fini(struct vn_renderer *renderer, + struct vn_renderer_shmem_pool *pool); + +struct vn_renderer_shmem * +vn_renderer_shmem_pool_alloc(struct vn_renderer *renderer, + struct vn_renderer_shmem_pool *pool, + size_t size, + size_t *out_offset); + #endif /* VN_RENDERER_UTIL_H */