Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d/command.c | 72 ++++++++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 19 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 5cb95869..7e17eb68 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -1,6 +1,7 @@ /* * Copyright 2016 Józef Kucia for CodeWeavers * Copyright 2016 Henri Verbeet for CodeWeavers + * Copyright 2021 Conor McCarthy for Codeweavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -2636,19 +2637,24 @@ static void d3d12_command_list_prepare_descriptors(struct d3d12_command_list *li
static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_descriptor_write, VkDescriptorImageInfo *vk_image_info, const struct d3d12_desc *descriptor, - uint32_t descriptor_range_magic, VkDescriptorSet vk_descriptor_set, - uint32_t vk_binding, unsigned int index) + const struct d3d12_root_descriptor_table_range *range, VkDescriptorSet *vk_descriptor_sets, + unsigned int index, bool bindless) { + uint32_t descriptor_range_magic = range->descriptor_magic; const struct vkd3d_view *view = descriptor->u.view; + uint32_t vk_binding = range->binding; + uint32_t set = range->set;
if (descriptor->magic != descriptor_range_magic) return false;
vk_descriptor_write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; vk_descriptor_write->pNext = NULL; - vk_descriptor_write->dstSet = vk_descriptor_set; - vk_descriptor_write->dstBinding = vk_binding + index; - vk_descriptor_write->dstArrayElement = 0; + vk_descriptor_write->dstSet = vk_descriptor_sets[set]; + /* If bindless is true the descriptors use a single array binding. The value of + * range->descriptor_count is not necessarily UINT_MAX in this case. */ + vk_descriptor_write->dstBinding = bindless ? vk_binding : vk_binding + index; + vk_descriptor_write->dstArrayElement = bindless ? range->binding_offset + index : 0; vk_descriptor_write->descriptorCount = 1; vk_descriptor_write->descriptorType = descriptor->vk_descriptor_type; vk_descriptor_write->pImageInfo = NULL; @@ -2664,11 +2670,25 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des case VKD3D_DESCRIPTOR_MAGIC_SRV: case VKD3D_DESCRIPTOR_MAGIC_UAV: /* We use separate bindings for buffer and texture SRVs/UAVs. - * See d3d12_root_signature_init(). */ - vk_descriptor_write->dstBinding = vk_binding + 2 * index; - if (descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER - && descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) - ++vk_descriptor_write->dstBinding; + * See d3d12_root_signature_init(). For unbounded ranges the descriptors exist + * in two consecutive sets, otherwise they occur in pairs in one set. */ + if (range->descriptor_count == ~0u) + { + if (descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER + && descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) + { + vk_descriptor_write->dstSet = vk_descriptor_sets[set + 1]; + vk_descriptor_write->dstBinding = 0; + } + } + else + { + if(!bindless) + vk_descriptor_write->dstBinding = vk_binding + 2 * index; + if (descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER + && descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) + ++vk_descriptor_write->dstBinding; + }
if (descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) @@ -2716,10 +2736,10 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list VkDevice vk_device = list->device->vk_device; unsigned int i, j, k, descriptor_count; struct d3d12_desc *descriptor; + unsigned int write_count = 0;
descriptor_table = root_signature_get_descriptor_table(root_signature, index);
- descriptor_count = 0; current_descriptor_write = descriptor_writes; current_image_info = image_infos; for (i = 0; i < descriptor_table->range_count; ++i) @@ -2731,7 +2751,18 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list
descriptor = base_descriptor + range->offset;
- for (j = 0; j < range->descriptor_count; ++j, ++descriptor) + descriptor_count = range->descriptor_count; + if (descriptor_count == ~0u) + { + int rc = pthread_mutex_lock(&list->device->mutex); + if (rc) + ERR("Failed to lock mutex, error %d.\n", rc); + descriptor_count = d3d12_device_descriptor_heap_size_from_descriptor(list->device, descriptor); + if (!rc) + pthread_mutex_unlock(&list->device->mutex); + } + + for (j = 0; j < descriptor_count; ++j, ++descriptor) { unsigned int register_idx = range->base_register_idx + j;
@@ -2750,26 +2781,29 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list } }
+ /* Not all descriptors are necessarily valid if the range is unbounded. */ + if (!descriptor->magic) + continue; + if (!vk_write_descriptor_set_from_d3d12_desc(current_descriptor_write, - current_image_info, descriptor, range->descriptor_magic, - bindings->descriptor_set, range->binding, j)) + current_image_info, descriptor, range, bindings->descriptor_sets, j, root_signature->bindless)) continue;
- ++descriptor_count; + ++write_count; ++current_descriptor_write; ++current_image_info;
- if (descriptor_count == ARRAY_SIZE(descriptor_writes)) + if (write_count == ARRAY_SIZE(descriptor_writes)) { - VK_CALL(vkUpdateDescriptorSets(vk_device, descriptor_count, descriptor_writes, 0, NULL)); - descriptor_count = 0; + VK_CALL(vkUpdateDescriptorSets(vk_device, write_count, descriptor_writes, 0, NULL)); + write_count = 0; current_descriptor_write = descriptor_writes; current_image_info = image_infos; } } }
- VK_CALL(vkUpdateDescriptorSets(vk_device, descriptor_count, descriptor_writes, 0, NULL)); + VK_CALL(vkUpdateDescriptorSets(vk_device, write_count, descriptor_writes, 0, NULL)); }
static bool vk_write_descriptor_set_from_root_descriptor(VkWriteDescriptorSet *vk_descriptor_write,