radv: Implement VK_VALVE_mutable_descriptor_type.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7967>
This commit is contained in:
Hans-Kristian Arntzen
2020-12-07 13:41:26 +01:00
committed by Marge Bot
parent 08fb84dc9d
commit 86644b84b9
5 changed files with 115 additions and 17 deletions

View File

@@ -2,3 +2,4 @@ GL_EXT_demote_to_helper_invocation on radeonsi
EGL_MESA_platform_xcb EGL_MESA_platform_xcb
driconf: remove glx_disable_oml_sync_control, glx_disable_sgi_video_sync, and glx_disable_ext_buffer_age 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 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

View File

@@ -69,6 +69,42 @@ create_sorted_bindings(const VkDescriptorSetLayoutBinding *bindings, unsigned co
return sorted_bindings; 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( VkResult radv_CreateDescriptorSetLayout(
VkDevice _device, VkDevice _device,
const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
@@ -81,6 +117,8 @@ VkResult radv_CreateDescriptorSetLayout(
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO); assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
const VkDescriptorSetLayoutBindingFlagsCreateInfo *variable_flags = const VkDescriptorSetLayoutBindingFlagsCreateInfo *variable_flags =
vk_find_struct_const(pCreateInfo->pNext, DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO); 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 num_bindings = 0;
uint32_t immutable_sampler_count = 0; uint32_t immutable_sampler_count = 0;
@@ -217,6 +255,15 @@ VkResult radv_CreateDescriptorSetLayout(
set_layout->binding[b].size = 16; set_layout->binding[b].size = 16;
alignment = 16; alignment = 16;
break; 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: case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
alignment = 16; alignment = 16;
set_layout->binding[b].size = descriptor_count; 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); vk_find_struct_const(pCreateInfo->pNext, DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO);
VkDescriptorSetVariableDescriptorCountLayoutSupport *variable_count = VkDescriptorSetVariableDescriptorCountLayoutSupport *variable_count =
vk_find_struct((void*)pCreateInfo->pNext, DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT); 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) { if (variable_count) {
variable_count->maxVariableDescriptorCount = 0; variable_count->maxVariableDescriptorCount = 0;
} }
@@ -371,6 +420,12 @@ void radv_GetDescriptorSetLayoutSupport(VkDevice device,
descriptor_size = descriptor_count; descriptor_size = descriptor_count;
descriptor_count = 1; descriptor_count = 1;
break; 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: default:
break; break;
} }
@@ -560,7 +615,7 @@ radv_descriptor_set_create(struct radv_device *device,
if (pool->current_offset + layout_size <= pool->size) { if (pool->current_offset + layout_size <= pool->size) {
set->bo = pool->bo; set->bo = pool->bo;
set->mapped_ptr = (uint32_t*)(pool->mapped_ptr + pool->current_offset); 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) { if (!pool->host_memory_base) {
pool->entries[pool->entry_count].offset = pool->current_offset; pool->entries[pool->entry_count].offset = pool->current_offset;
pool->entries[pool->entry_count].size = layout_size; 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->bo = pool->bo;
set->mapped_ptr = (uint32_t*)(pool->mapped_ptr + offset); 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], memmove(&pool->entries[index + 1], &pool->entries[index],
sizeof(pool->entries[0]) * (pool->entry_count - index)); sizeof(pool->entries[0]) * (pool->entry_count - index));
pool->entries[index].offset = offset; pool->entries[index].offset = offset;
@@ -652,6 +707,8 @@ static void radv_destroy_descriptor_pool(struct radv_device *device,
if (pool->bo) if (pool->bo)
device->ws->buffer_destroy(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_object_base_finish(&pool->base);
vk_free2(&device->vk.alloc, pAllocator, pool); vk_free2(&device->vk.alloc, pAllocator, pool);
@@ -668,6 +725,9 @@ VkResult radv_CreateDescriptorPool(
uint64_t size = sizeof(struct radv_descriptor_pool); uint64_t size = sizeof(struct radv_descriptor_pool);
uint64_t bo_size = 0, bo_count = 0, range_count = 0; 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) { vk_foreach_struct(ext, pCreateInfo->pNext) {
switch (ext->sType) { switch (ext->sType) {
case VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT: { 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: case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
bo_size += 64 * pCreateInfo->pPoolSizes[i].descriptorCount; bo_size += 64 * pCreateInfo->pPoolSizes[i].descriptorCount;
break; 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: case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
bo_size += 96 * pCreateInfo->pPoolSizes[i].descriptorCount; bo_size += 96 * pCreateInfo->pPoolSizes[i].descriptorCount;
break; break;
@@ -743,6 +818,7 @@ VkResult radv_CreateDescriptorPool(
} }
if (bo_size) { if (bo_size) {
if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE)) {
pool->bo = device->ws->buffer_create(device->ws, bo_size, 32, pool->bo = device->ws->buffer_create(device->ws, bo_size, 32,
RADEON_DOMAIN_VRAM, RADEON_DOMAIN_VRAM,
RADEON_FLAG_NO_INTERPROCESS_SHARING | RADEON_FLAG_NO_INTERPROCESS_SHARING |
@@ -758,6 +834,15 @@ VkResult radv_CreateDescriptorPool(
radv_destroy_descriptor_pool(device, pAllocator, pool); radv_destroy_descriptor_pool(device, pAllocator, pool);
return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY); 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; pool->size = bo_size;
pool->max_entry_count = pCreateInfo->maxSets; pool->max_entry_count = pCreateInfo->maxSets;
@@ -1174,6 +1259,10 @@ void radv_update_descriptor_sets(
dst_buffer_list += dst_binding_layout->buffer_offset; dst_buffer_list += dst_binding_layout->buffer_offset;
dst_buffer_list += copyset->dstArrayElement; 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) { for (j = 0; j < copyset->descriptorCount; ++j) {
switch (src_binding_layout->type) { switch (src_binding_layout->type) {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
@@ -1190,7 +1279,7 @@ void radv_update_descriptor_sets(
break; break;
} }
default: default:
memcpy(dst_ptr, src_ptr, src_binding_layout->size); memcpy(dst_ptr, src_ptr, copy_size);
} }
src_ptr += src_binding_layout->size / 4; src_ptr += src_binding_layout->size / 4;
dst_ptr += dst_binding_layout->size / 4; dst_ptr += dst_binding_layout->size / 4;

View File

@@ -1460,6 +1460,12 @@ void radv_GetPhysicalDeviceFeatures2(
features->sparseImageInt64Atomics = false; features->sparseImageInt64Atomics = false;
break; break;
} }
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE: {
VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE *features =
(VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE *)ext;
features->mutableDescriptorType = true;
break;
}
default: default:
break; break;
} }

View File

@@ -191,6 +191,7 @@ EXTENSIONS = [
Extension('VK_GOOGLE_user_type', 1, True), Extension('VK_GOOGLE_user_type', 1, True),
Extension('VK_NV_compute_shader_derivatives', 1, True), Extension('VK_NV_compute_shader_derivatives', 1, True),
Extension('VK_EXT_4444_formats', 1, True), Extension('VK_EXT_4444_formats', 1, True),
Extension('VK_VALVE_mutable_descriptor_type', 1, True),
] ]
MAX_API_VERSION = VkVersion('0.0.0') MAX_API_VERSION = VkVersion('0.0.0')

View File

@@ -927,6 +927,7 @@ struct radv_descriptor_pool_entry {
struct radv_descriptor_pool { struct radv_descriptor_pool {
struct vk_object_base base; struct vk_object_base base;
struct radeon_winsys_bo *bo; struct radeon_winsys_bo *bo;
uint8_t *host_bo;
uint8_t *mapped_ptr; uint8_t *mapped_ptr;
uint64_t current_offset; uint64_t current_offset;
uint64_t size; uint64_t size;