radv: Use host memory pool for non-freeable descriptors.
v2: Handle out of pool memory error. v3: Actually use VK_ERROR_OUT_OF_POOL_MEMORY_KHR for the error condition. Signed-off-by: Bas Nieuwenhuizen <basni@google.com> Reviewed-by: Bas Nieuwenhuizen <basni@google.com>
This commit is contained in:
@@ -265,11 +265,20 @@ radv_descriptor_set_create(struct radv_device *device,
|
|||||||
sizeof(struct radeon_winsys_bo *) * layout->buffer_count;
|
sizeof(struct radeon_winsys_bo *) * layout->buffer_count;
|
||||||
unsigned mem_size = range_offset +
|
unsigned mem_size = range_offset +
|
||||||
sizeof(struct radv_descriptor_range) * layout->dynamic_offset_count;
|
sizeof(struct radv_descriptor_range) * layout->dynamic_offset_count;
|
||||||
set = vk_alloc2(&device->alloc, NULL, mem_size, 8,
|
|
||||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
||||||
|
|
||||||
if (!set)
|
if (pool->host_memory_base) {
|
||||||
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
if (pool->host_memory_end - pool->host_memory_ptr < mem_size)
|
||||||
|
return vk_error(VK_ERROR_OUT_OF_POOL_MEMORY_KHR);
|
||||||
|
|
||||||
|
set = (struct radv_descriptor_set*)pool->host_memory_ptr;
|
||||||
|
pool->host_memory_ptr += mem_size;
|
||||||
|
} else {
|
||||||
|
set = vk_alloc2(&device->alloc, NULL, mem_size, 8,
|
||||||
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||||
|
|
||||||
|
if (!set)
|
||||||
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
memset(set, 0, mem_size);
|
memset(set, 0, mem_size);
|
||||||
|
|
||||||
@@ -295,6 +304,8 @@ radv_descriptor_set_create(struct radv_device *device,
|
|||||||
uint64_t offset = 0;
|
uint64_t offset = 0;
|
||||||
struct list_head *prev = &pool->vram_list;
|
struct list_head *prev = &pool->vram_list;
|
||||||
struct radv_descriptor_set *cur;
|
struct radv_descriptor_set *cur;
|
||||||
|
|
||||||
|
assert(!pool->host_memory_base);
|
||||||
LIST_FOR_EACH_ENTRY(cur, &pool->vram_list, vram_list) {
|
LIST_FOR_EACH_ENTRY(cur, &pool->vram_list, vram_list) {
|
||||||
uint64_t start = (uint8_t*)cur->mapped_ptr - pool->mapped_ptr;
|
uint64_t start = (uint8_t*)cur->mapped_ptr - pool->mapped_ptr;
|
||||||
if (start - offset >= layout_size)
|
if (start - offset >= layout_size)
|
||||||
@@ -342,6 +353,8 @@ radv_descriptor_set_destroy(struct radv_device *device,
|
|||||||
struct radv_descriptor_set *set,
|
struct radv_descriptor_set *set,
|
||||||
bool free_bo)
|
bool free_bo)
|
||||||
{
|
{
|
||||||
|
assert(!pool->host_memory_base);
|
||||||
|
|
||||||
if (free_bo && set->size)
|
if (free_bo && set->size)
|
||||||
list_del(&set->vram_list);
|
list_del(&set->vram_list);
|
||||||
vk_free2(&device->alloc, NULL, set);
|
vk_free2(&device->alloc, NULL, set);
|
||||||
@@ -356,18 +369,17 @@ VkResult radv_CreateDescriptorPool(
|
|||||||
RADV_FROM_HANDLE(radv_device, device, _device);
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
||||||
struct radv_descriptor_pool *pool;
|
struct radv_descriptor_pool *pool;
|
||||||
int size = sizeof(struct radv_descriptor_pool);
|
int size = sizeof(struct radv_descriptor_pool);
|
||||||
uint64_t bo_size = 0;
|
uint64_t bo_size = 0, bo_count = 0, range_count = 0;
|
||||||
pool = vk_alloc2(&device->alloc, pAllocator, size, 8,
|
|
||||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
||||||
if (!pool)
|
|
||||||
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
||||||
|
|
||||||
memset(pool, 0, sizeof(*pool));
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < pCreateInfo->poolSizeCount; ++i) {
|
for (unsigned i = 0; i < pCreateInfo->poolSizeCount; ++i) {
|
||||||
|
if (pCreateInfo->pPoolSizes[i].type != VK_DESCRIPTOR_TYPE_SAMPLER)
|
||||||
|
bo_count += pCreateInfo->pPoolSizes[i].descriptorCount;
|
||||||
|
|
||||||
switch(pCreateInfo->pPoolSizes[i].type) {
|
switch(pCreateInfo->pPoolSizes[i].type) {
|
||||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
||||||
|
range_count += pCreateInfo->pPoolSizes[i].descriptorCount;
|
||||||
break;
|
break;
|
||||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||||
@@ -391,6 +403,26 @@ VkResult radv_CreateDescriptorPool(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT)) {
|
||||||
|
uint64_t host_size = pCreateInfo->maxSets * sizeof(struct radv_descriptor_set);
|
||||||
|
host_size += sizeof(struct radeon_winsys_bo*) * bo_count;
|
||||||
|
host_size += sizeof(struct radv_descriptor_range) * range_count;
|
||||||
|
size += host_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
pool = vk_alloc2(&device->alloc, pAllocator, size, 8,
|
||||||
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||||
|
if (!pool)
|
||||||
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||||
|
|
||||||
|
memset(pool, 0, sizeof(*pool));
|
||||||
|
|
||||||
|
if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT)) {
|
||||||
|
pool->host_memory_base = (uint8_t*)pool + sizeof(struct radv_descriptor_pool);
|
||||||
|
pool->host_memory_ptr = pool->host_memory_base;
|
||||||
|
pool->host_memory_end = (uint8_t*)pool + size;
|
||||||
|
}
|
||||||
|
|
||||||
if (bo_size) {
|
if (bo_size) {
|
||||||
pool->bo = device->ws->buffer_create(device->ws, bo_size,
|
pool->bo = device->ws->buffer_create(device->ws, bo_size,
|
||||||
32, RADEON_DOMAIN_VRAM, 0);
|
32, RADEON_DOMAIN_VRAM, 0);
|
||||||
@@ -414,9 +446,11 @@ void radv_DestroyDescriptorPool(
|
|||||||
if (!pool)
|
if (!pool)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
list_for_each_entry_safe(struct radv_descriptor_set, set,
|
if (!pool->host_memory_base) {
|
||||||
&pool->vram_list, vram_list) {
|
list_for_each_entry_safe(struct radv_descriptor_set, set,
|
||||||
radv_descriptor_set_destroy(device, pool, set, false);
|
&pool->vram_list, vram_list) {
|
||||||
|
radv_descriptor_set_destroy(device, pool, set, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pool->bo)
|
if (pool->bo)
|
||||||
@@ -432,14 +466,17 @@ VkResult radv_ResetDescriptorPool(
|
|||||||
RADV_FROM_HANDLE(radv_device, device, _device);
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
||||||
RADV_FROM_HANDLE(radv_descriptor_pool, pool, descriptorPool);
|
RADV_FROM_HANDLE(radv_descriptor_pool, pool, descriptorPool);
|
||||||
|
|
||||||
list_for_each_entry_safe(struct radv_descriptor_set, set,
|
if (!pool->host_memory_base) {
|
||||||
&pool->vram_list, vram_list) {
|
list_for_each_entry_safe(struct radv_descriptor_set, set,
|
||||||
radv_descriptor_set_destroy(device, pool, set, false);
|
&pool->vram_list, vram_list) {
|
||||||
|
radv_descriptor_set_destroy(device, pool, set, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list_inithead(&pool->vram_list);
|
list_inithead(&pool->vram_list);
|
||||||
|
|
||||||
pool->current_offset = 0;
|
pool->current_offset = 0;
|
||||||
|
pool->host_memory_ptr = pool->host_memory_base;
|
||||||
|
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@@ -570,6 +570,10 @@ struct radv_descriptor_pool {
|
|||||||
uint64_t size;
|
uint64_t size;
|
||||||
|
|
||||||
struct list_head vram_list;
|
struct list_head vram_list;
|
||||||
|
|
||||||
|
uint8_t *host_memory_base;
|
||||||
|
uint8_t *host_memory_ptr;
|
||||||
|
uint8_t *host_memory_end;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct radv_descriptor_update_template_entry {
|
struct radv_descriptor_update_template_entry {
|
||||||
|
Reference in New Issue
Block a user