diff --git a/src/intel/vulkan/anv_allocator.c b/src/intel/vulkan/anv_allocator.c index f8d6ef21eb2..22af7f0ed1b 100644 --- a/src/intel/vulkan/anv_allocator.c +++ b/src/intel/vulkan/anv_allocator.c @@ -1107,6 +1107,100 @@ anv_state_reserved_pool_free(struct anv_state_reserved_pool *pool, anv_free_list_push(&pool->reserved_blocks, &pool->pool->table, state.idx, 1); } +VkResult +anv_state_reserved_array_pool_init(struct anv_state_reserved_array_pool *pool, + struct anv_state_pool *parent, + uint32_t count, uint32_t size, uint32_t alignment) +{ + pool->pool = parent; + pool->count = count; + pool->size = size; + pool->stride = align(size, alignment); + pool->states = vk_zalloc(&pool->pool->block_pool.device->vk.alloc, + sizeof(BITSET_WORD) * BITSET_WORDS(pool->count), 8, + VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); + if (pool->states == NULL) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + BITSET_SET_RANGE(pool->states, 0, pool->count - 1); + simple_mtx_init(&pool->mutex, mtx_plain); + + pool->state = anv_state_pool_alloc(pool->pool, pool->stride * count, alignment); + + return VK_SUCCESS; +} + +void +anv_state_reserved_array_pool_finish(struct anv_state_reserved_array_pool *pool) +{ + anv_state_pool_free(pool->pool, pool->state); + vk_free(&pool->pool->block_pool.device->vk.alloc, pool->states); + simple_mtx_destroy(&pool->mutex); +} + +struct anv_state +anv_state_reserved_array_pool_alloc(struct anv_state_reserved_array_pool *pool, + bool alloc_back) +{ + simple_mtx_lock(&pool->mutex); + int idx = alloc_back ? + __bitset_last_bit(pool->states, BITSET_WORDS(pool->count)) : + __bitset_ffs(pool->states, BITSET_WORDS(pool->count)); + if (idx != 0) + BITSET_CLEAR(pool->states, idx - 1); + simple_mtx_unlock(&pool->mutex); + + if (idx == 0) + return ANV_STATE_NULL; + + idx--; + + struct anv_state state = pool->state; + state.offset += idx * pool->stride; + state.map += idx * pool->stride; + state.alloc_size = pool->size; + + return state; +} + +struct anv_state +anv_state_reserved_array_pool_alloc_index(struct anv_state_reserved_array_pool *pool, + uint32_t idx) +{ + simple_mtx_lock(&pool->mutex); + bool already_allocated = !BITSET_TEST(pool->states, idx); + if (!already_allocated) + BITSET_CLEAR(pool->states, idx); + simple_mtx_unlock(&pool->mutex); + + if (already_allocated) + return ANV_STATE_NULL; + + struct anv_state state = pool->state; + state.offset += idx * pool->stride; + state.map += idx * pool->stride; + state.alloc_size = pool->size; + + return state; +} + +uint32_t +anv_state_reserved_array_pool_state_index(struct anv_state_reserved_array_pool *pool, + struct anv_state state) +{ + return (state.offset - pool->state.offset) / pool->stride; +} + +void +anv_state_reserved_array_pool_free(struct anv_state_reserved_array_pool *pool, + struct anv_state state) +{ + unsigned idx = (state.offset - pool->state.offset) / pool->stride; + simple_mtx_lock(&pool->mutex); + BITSET_SET(pool->states, idx); + simple_mtx_unlock(&pool->mutex); + } + void anv_bo_pool_init(struct anv_bo_pool *pool, struct anv_device *device, const char *name, enum anv_bo_alloc_flags alloc_flags) diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 69ea621674d..6d349d8e8cf 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -752,6 +752,21 @@ struct anv_state_reserved_pool { uint32_t count; }; +struct anv_state_reserved_array_pool { + struct anv_state_pool *pool; + simple_mtx_t mutex; + /* Bitfield of usable elements */ + BITSET_WORD *states; + /* Backing store */ + struct anv_state state; + /* Number of elements */ + uint32_t count; + /* Stride between each element */ + uint32_t stride; + /* Size of each element */ + uint32_t size; +}; + struct anv_state_stream { struct anv_state_pool *state_pool; @@ -871,6 +886,20 @@ struct anv_state anv_state_reserved_pool_alloc(struct anv_state_reserved_pool *p void anv_state_reserved_pool_free(struct anv_state_reserved_pool *pool, struct anv_state state); +VkResult anv_state_reserved_array_pool_init(struct anv_state_reserved_array_pool *pool, + struct anv_state_pool *parent, + uint32_t count, uint32_t size, + uint32_t alignment); +void anv_state_reserved_array_pool_finish(struct anv_state_reserved_array_pool *pool); +struct anv_state anv_state_reserved_array_pool_alloc(struct anv_state_reserved_array_pool *pool, + bool alloc_back); +struct anv_state anv_state_reserved_array_pool_alloc_index(struct anv_state_reserved_array_pool *pool, + unsigned idx); +uint32_t anv_state_reserved_array_pool_state_index(struct anv_state_reserved_array_pool *pool, + struct anv_state state); +void anv_state_reserved_array_pool_free(struct anv_state_reserved_array_pool *pool, + struct anv_state state); + VkResult anv_state_table_init(struct anv_state_table *table, struct anv_device *device, uint32_t initial_entries);