[PATCH vkd3d 3/3] vkd3d: Update descriptor sets containing array bindings.

Conor McCarthy cmccarthy at codeweavers.com
Wed May 26 03:07:54 CDT 2021


Signed-off-by: Conor McCarthy <cmccarthy at 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,
-- 
2.31.1




More information about the wine-devel mailing list