From 86644b84b94910ddb78b7a1117b8bcf55bb76265 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Mon, 7 Dec 2020 13:41:26 +0100 Subject: [PATCH] radv: Implement VK_VALVE_mutable_descriptor_type. Reviewed-by: Samuel Pitoiset Part-of: --- docs/relnotes/new_features.txt | 1 + src/amd/vulkan/radv_descriptor_set.c | 123 ++++++++++++++++++++++++++++++----- src/amd/vulkan/radv_device.c | 6 ++ src/amd/vulkan/radv_extensions.py | 1 + src/amd/vulkan/radv_private.h | 1 + 5 files changed, 115 insertions(+), 17 deletions(-) diff --git a/docs/relnotes/new_features.txt b/docs/relnotes/new_features.txt index ac33eea..ec0b4af 100644 --- a/docs/relnotes/new_features.txt +++ b/docs/relnotes/new_features.txt @@ -2,3 +2,4 @@ GL_EXT_demote_to_helper_invocation on radeonsi EGL_MESA_platform_xcb driconf: remove glx_disable_oml_sync_control, glx_disable_sgi_video_sync, and glx_disable_ext_buffer_age Removed support for loading DRI drivers older than Mesa 8.0, including all DRI1 support +Add support for VK_VALVE_mutable_descriptor_type on RADV diff --git a/src/amd/vulkan/radv_descriptor_set.c b/src/amd/vulkan/radv_descriptor_set.c index 9dd491a..5643cd8 100644 --- a/src/amd/vulkan/radv_descriptor_set.c +++ b/src/amd/vulkan/radv_descriptor_set.c @@ -69,6 +69,42 @@ create_sorted_bindings(const VkDescriptorSetLayoutBinding *bindings, unsigned co return sorted_bindings; } +static bool radv_mutable_descriptor_type_size_alignment(const VkMutableDescriptorTypeListVALVE *list, + uint64_t *out_size, uint64_t *out_align) +{ + uint32_t max_size = 0; + uint32_t max_align = 0; + + for (uint32_t i = 0; i < list->descriptorTypeCount; i++) { + uint32_t size = 0; + uint32_t align = 0; + + switch (list->pDescriptorTypes[i]) { + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + size = 16; + align = 16; + break; + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + size = 64; + align = 32; + break; + default: + return false; + } + + max_size = MAX2(max_size, size); + max_align = MAX2(max_align, align); + } + + *out_size = max_size; + *out_align = max_align; + return true; +} + VkResult radv_CreateDescriptorSetLayout( VkDevice _device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, @@ -81,6 +117,8 @@ VkResult radv_CreateDescriptorSetLayout( assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO); const VkDescriptorSetLayoutBindingFlagsCreateInfo *variable_flags = vk_find_struct_const(pCreateInfo->pNext, DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO); + const VkMutableDescriptorTypeCreateInfoVALVE *mutable_info = + vk_find_struct_const(pCreateInfo->pNext, MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE); uint32_t num_bindings = 0; uint32_t immutable_sampler_count = 0; @@ -217,6 +255,15 @@ VkResult radv_CreateDescriptorSetLayout( set_layout->binding[b].size = 16; alignment = 16; break; + case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE: { + uint64_t mutable_size = 0, mutable_align = 0; + radv_mutable_descriptor_type_size_alignment(&mutable_info->pMutableDescriptorTypeLists[j], + &mutable_size, &mutable_align); + assert(mutable_size && mutable_align); + set_layout->binding[b].size = mutable_size; + alignment = mutable_align; + break; + } case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: alignment = 16; set_layout->binding[b].size = descriptor_count; @@ -323,6 +370,8 @@ void radv_GetDescriptorSetLayoutSupport(VkDevice device, vk_find_struct_const(pCreateInfo->pNext, DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO); VkDescriptorSetVariableDescriptorCountLayoutSupport *variable_count = vk_find_struct((void*)pCreateInfo->pNext, DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT); + const VkMutableDescriptorTypeCreateInfoVALVE *mutable_info = + vk_find_struct_const(pCreateInfo->pNext, MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE); if (variable_count) { variable_count->maxVariableDescriptorCount = 0; } @@ -371,6 +420,12 @@ void radv_GetDescriptorSetLayoutSupport(VkDevice device, descriptor_size = descriptor_count; descriptor_count = 1; break; + case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE: + if (!radv_mutable_descriptor_type_size_alignment(&mutable_info->pMutableDescriptorTypeLists[i], + &descriptor_size, &descriptor_alignment)) { + supported = false; + } + break; default: break; } @@ -560,7 +615,7 @@ radv_descriptor_set_create(struct radv_device *device, if (pool->current_offset + layout_size <= pool->size) { set->bo = pool->bo; set->mapped_ptr = (uint32_t*)(pool->mapped_ptr + pool->current_offset); - set->va = radv_buffer_get_va(set->bo) + pool->current_offset; + set->va = set->bo ? (radv_buffer_get_va(set->bo) + pool->current_offset) : 0; if (!pool->host_memory_base) { pool->entries[pool->entry_count].offset = pool->current_offset; pool->entries[pool->entry_count].size = layout_size; @@ -584,7 +639,7 @@ radv_descriptor_set_create(struct radv_device *device, } set->bo = pool->bo; set->mapped_ptr = (uint32_t*)(pool->mapped_ptr + offset); - set->va = radv_buffer_get_va(set->bo) + offset; + set->va = set->bo ? (radv_buffer_get_va(set->bo) + offset) : 0; memmove(&pool->entries[index + 1], &pool->entries[index], sizeof(pool->entries[0]) * (pool->entry_count - index)); pool->entries[index].offset = offset; @@ -652,6 +707,8 @@ static void radv_destroy_descriptor_pool(struct radv_device *device, if (pool->bo) device->ws->buffer_destroy(pool->bo); + if (pool->host_bo) + vk_free2(&device->vk.alloc, pAllocator, pool->host_bo); vk_object_base_finish(&pool->base); vk_free2(&device->vk.alloc, pAllocator, pool); @@ -668,6 +725,9 @@ VkResult radv_CreateDescriptorPool( uint64_t size = sizeof(struct radv_descriptor_pool); uint64_t bo_size = 0, bo_count = 0, range_count = 0; + const VkMutableDescriptorTypeCreateInfoVALVE *mutable_info = + vk_find_struct_const(pCreateInfo->pNext, MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE); + vk_foreach_struct(ext, pCreateInfo->pNext) { switch (ext->sType) { case VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT: { @@ -706,6 +766,21 @@ VkResult radv_CreateDescriptorPool( case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: bo_size += 64 * pCreateInfo->pPoolSizes[i].descriptorCount; break; + case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE: + /* Per spec, if a mutable descriptor type list is provided for the pool entry, we + * allocate enough memory to hold any subset of that list. + * If there is no mutable descriptor type list available, + * we must allocate enough for any supported mutable descriptor type, i.e. 64 bytes. */ + if (mutable_info && i < mutable_info->mutableDescriptorTypeListCount) { + uint64_t mutable_size, mutable_alignment; + if (radv_mutable_descriptor_type_size_alignment(&mutable_info->pMutableDescriptorTypeLists[i], + &mutable_size, &mutable_alignment)) { + bo_size += mutable_size * pCreateInfo->pPoolSizes[i].descriptorCount; + } + } else { + bo_size += 64 * pCreateInfo->pPoolSizes[i].descriptorCount; + } + break; case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: bo_size += 96 * pCreateInfo->pPoolSizes[i].descriptorCount; break; @@ -743,20 +818,30 @@ VkResult radv_CreateDescriptorPool( } if (bo_size) { - pool->bo = device->ws->buffer_create(device->ws, bo_size, 32, - RADEON_DOMAIN_VRAM, - RADEON_FLAG_NO_INTERPROCESS_SHARING | - RADEON_FLAG_READ_ONLY | - RADEON_FLAG_32BIT, - RADV_BO_PRIORITY_DESCRIPTOR); - if (!pool->bo) { - radv_destroy_descriptor_pool(device, pAllocator, pool); - return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY); - } - pool->mapped_ptr = (uint8_t*)device->ws->buffer_map(pool->bo); - if (!pool->mapped_ptr) { - radv_destroy_descriptor_pool(device, pAllocator, pool); - return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY); + if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE)) { + pool->bo = device->ws->buffer_create(device->ws, bo_size, 32, + RADEON_DOMAIN_VRAM, + RADEON_FLAG_NO_INTERPROCESS_SHARING | + RADEON_FLAG_READ_ONLY | + RADEON_FLAG_32BIT, + RADV_BO_PRIORITY_DESCRIPTOR); + if (!pool->bo) { + radv_destroy_descriptor_pool(device, pAllocator, pool); + return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY); + } + pool->mapped_ptr = (uint8_t*)device->ws->buffer_map(pool->bo); + if (!pool->mapped_ptr) { + radv_destroy_descriptor_pool(device, pAllocator, pool); + return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY); + } + } else { + pool->host_bo = vk_alloc2(&device->vk.alloc, pAllocator, bo_size, 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!pool->host_bo) { + radv_destroy_descriptor_pool(device, pAllocator, pool); + return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + } + pool->mapped_ptr = pool->host_bo; } } pool->size = bo_size; @@ -1174,6 +1259,10 @@ void radv_update_descriptor_sets( dst_buffer_list += dst_binding_layout->buffer_offset; dst_buffer_list += copyset->dstArrayElement; + /* In case of copies between mutable descriptor types + * and non-mutable descriptor types. */ + size_t copy_size = MIN2(src_binding_layout->size, dst_binding_layout->size); + for (j = 0; j < copyset->descriptorCount; ++j) { switch (src_binding_layout->type) { case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: @@ -1190,7 +1279,7 @@ void radv_update_descriptor_sets( break; } default: - memcpy(dst_ptr, src_ptr, src_binding_layout->size); + memcpy(dst_ptr, src_ptr, copy_size); } src_ptr += src_binding_layout->size / 4; dst_ptr += dst_binding_layout->size / 4; diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index fe0ddb7..33d3b1d 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -1460,6 +1460,12 @@ void radv_GetPhysicalDeviceFeatures2( features->sparseImageInt64Atomics = false; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE: { + VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE *features = + (VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE *)ext; + features->mutableDescriptorType = true; + break; + } default: break; } diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py index 03056b2..fd4b5f9 100644 --- a/src/amd/vulkan/radv_extensions.py +++ b/src/amd/vulkan/radv_extensions.py @@ -191,6 +191,7 @@ EXTENSIONS = [ Extension('VK_GOOGLE_user_type', 1, True), Extension('VK_NV_compute_shader_derivatives', 1, True), Extension('VK_EXT_4444_formats', 1, True), + Extension('VK_VALVE_mutable_descriptor_type', 1, True), ] MAX_API_VERSION = VkVersion('0.0.0') diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 82cddae..7b88ae5 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -927,6 +927,7 @@ struct radv_descriptor_pool_entry { struct radv_descriptor_pool { struct vk_object_base base; struct radeon_winsys_bo *bo; + uint8_t *host_bo; uint8_t *mapped_ptr; uint64_t current_offset; uint64_t size; -- 2.7.4