Module: Mesa Branch: main Commit: 288ce1b033faf1123b76688d9a02323484f21810 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=288ce1b033faf1123b76688d9a02323484f21810
Author: Yiwei Zhang <[email protected]> Date: Fri Aug 20 21:50:14 2021 +0000 venus: check descriptor allocations against pool resource Only kick in when async_set_allocation is enabled. Signed-off-by: Yiwei Zhang <[email protected]> Reviewed-by: Chia-I Wu <[email protected]> Reviewed-by: Ryan Neph <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12501> --- src/virtio/vulkan/vn_descriptor_set.c | 80 +++++++++++++++++++++++++++++++++++ src/virtio/vulkan/vn_descriptor_set.h | 1 + 2 files changed, 81 insertions(+) diff --git a/src/virtio/vulkan/vn_descriptor_set.c b/src/virtio/vulkan/vn_descriptor_set.c index dbf9a879996..b6a1da54a01 100644 --- a/src/virtio/vulkan/vn_descriptor_set.c +++ b/src/virtio/vulkan/vn_descriptor_set.c @@ -277,6 +277,73 @@ vn_DestroyDescriptorPool(VkDevice device, vk_free(alloc, pool); } +static bool +vn_descriptor_pool_alloc_descriptors( + struct vn_descriptor_pool *pool, + const struct vn_descriptor_set_layout *layout, + uint32_t last_binding_descriptor_count) +{ + struct vn_descriptor_pool_state recovery; + + if (!pool->async_set_allocation) + return true; + + if (pool->used.set_count == pool->max.set_count) + return false; + + /* backup current pool state to recovery */ + recovery = pool->used; + + ++pool->used.set_count; + + for (uint32_t i = 0; i <= layout->last_binding; i++) { + const VkDescriptorType type = layout->bindings[i].type; + const uint32_t count = i == layout->last_binding + ? last_binding_descriptor_count + : layout->bindings[i].count; + + pool->used.descriptor_counts[type] += count; + + if (pool->used.descriptor_counts[type] > + pool->max.descriptor_counts[type]) { + /* restore pool state before this allocation */ + pool->used = recovery; + return false; + } + } + + return true; +} + +static void +vn_descriptor_pool_free_descriptors( + struct vn_descriptor_pool *pool, + const struct vn_descriptor_set_layout *layout, + uint32_t last_binding_descriptor_count) +{ + if (!pool->async_set_allocation) + return; + + for (uint32_t i = 0; i <= layout->last_binding; i++) { + const uint32_t count = i == layout->last_binding + ? last_binding_descriptor_count + : layout->bindings[i].count; + + pool->used.descriptor_counts[layout->bindings[i].type] -= count; + } + + --pool->used.set_count; +} + +static void +vn_descriptor_pool_reset_descriptors(struct vn_descriptor_pool *pool) +{ + if (!pool->async_set_allocation) + return; + + memset(&pool->used, 0, sizeof(pool->used)); +} + VkResult vn_ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, @@ -298,6 +365,8 @@ vn_ResetDescriptorPool(VkDevice device, vk_free(alloc, set); } + vn_descriptor_pool_reset_descriptors(pool); + return VK_SUCCESS; } @@ -347,9 +416,18 @@ vn_AllocateDescriptorSets(VkDevice device, last_binding_descriptor_count = variable_info->pDescriptorCounts[i]; } + if (!vn_descriptor_pool_alloc_descriptors( + pool, layout, last_binding_descriptor_count)) { + pDescriptorSets[i] = VK_NULL_HANDLE; + result = VK_ERROR_OUT_OF_POOL_MEMORY; + goto fail; + } + set = vk_zalloc(alloc, sizeof(*set), VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (!set) { + vn_descriptor_pool_free_descriptors(pool, layout, + last_binding_descriptor_count); pDescriptorSets[i] = VK_NULL_HANDLE; result = VK_ERROR_OUT_OF_HOST_MEMORY; goto fail; @@ -380,6 +458,8 @@ fail: if (!set) break; + vn_descriptor_pool_free_descriptors(pool, set->layout, + set->last_binding_descriptor_count); list_del(&set->head); vn_object_base_fini(&set->base); vk_free(alloc, set); diff --git a/src/virtio/vulkan/vn_descriptor_set.h b/src/virtio/vulkan/vn_descriptor_set.h index 9eb100755aa..5f6afc44fb3 100644 --- a/src/virtio/vulkan/vn_descriptor_set.h +++ b/src/virtio/vulkan/vn_descriptor_set.h @@ -50,6 +50,7 @@ struct vn_descriptor_pool { VkAllocationCallbacks allocator; bool async_set_allocation; struct vn_descriptor_pool_state max; + struct vn_descriptor_pool_state used; struct list_head descriptor_sets; };
