[PATCH vkd3d 1/4] vkd3d: Create and track unbounded descriptor set layouts.

Conor McCarthy cmccarthy at codeweavers.com
Wed May 26 03:06:16 CDT 2021


Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
 libs/vkd3d/state.c         | 124 ++++++++++++++++++++++++++++++-------
 libs/vkd3d/vkd3d_private.h |   3 +
 2 files changed, 106 insertions(+), 21 deletions(-)

diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index 03684264..18340a07 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -683,6 +683,9 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat
 struct vkd3d_descriptor_set_context
 {
     VkDescriptorSetLayoutBinding *current_binding;
+    VkDescriptorSetLayoutBinding *first_binding;
+    unsigned int table_index;
+    bool unbounded;
     unsigned int descriptor_index;
     uint32_t descriptor_binding;
 };
@@ -805,6 +808,62 @@ static unsigned int vk_descriptor_count_from_d3d12_desc_range_type(D3D12_DESCRIP
     return min(type_max, all_max);
 }
 
+static unsigned int vkd3d_count_static_descriptor_bindings(struct vkd3d_descriptor_set_context *context)
+{
+    unsigned int i, binding_count, count = 0;
+
+    binding_count = context->descriptor_binding - !!context->unbounded;
+    for (i = 0; i < binding_count; ++i)
+        count += context->first_binding[i].descriptorCount;
+
+    return count;
+}
+
+static HRESULT vkd3d_validate_descriptor_set_count(struct d3d12_device *device, unsigned int set_count)
+{
+    uint32_t max_count = min(VKD3D_MAX_DESCRIPTOR_SETS,
+            device->vk_info.device_limits.maxBoundDescriptorSets);
+    if (set_count > max_count)
+    {
+        ERR("Required descriptor set count exceeds maximum allowed count of %u.\n", max_count);
+        return E_INVALIDARG;
+    }
+    return S_OK;
+}
+
+static HRESULT vkd3d_create_descriptor_set_layout(struct d3d12_device *device,
+        VkDescriptorSetLayoutCreateFlags flags, bool unbounded, unsigned int binding_count,
+        const VkDescriptorSetLayoutBinding *bindings, VkDescriptorSetLayout *set_layout);
+
+static HRESULT d3d12_root_signature_append_descriptor_set_layout(struct d3d12_root_signature *root_signature,
+    struct vkd3d_descriptor_set_context *context, VkDescriptorSetLayoutCreateFlags flags)
+{
+    HRESULT hr;
+
+    if (!context->descriptor_binding)
+        return S_OK;
+
+    if (FAILED(hr = vkd3d_validate_descriptor_set_count(root_signature->device,
+            root_signature->vk_set_count + 1)))
+        return hr;
+
+    if (FAILED(hr = vkd3d_create_descriptor_set_layout(root_signature->device,
+            flags, context->unbounded, context->descriptor_binding,
+            context->first_binding, &root_signature->vk_set_layouts[root_signature->vk_set_count])))
+        return hr;
+    root_signature->vk_unbounded_set_tables[root_signature->vk_set_count]
+            = context->unbounded ? context->table_index : -1;
+    root_signature->vk_set_layout_static_counts[root_signature->vk_set_count]
+            = vkd3d_count_static_descriptor_bindings(context);
+    ++root_signature->vk_set_count;
+
+    context->current_binding = context->first_binding;
+    context->descriptor_binding = 0;
+    context->unbounded = false;
+
+    return S_OK;
+}
+
 static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_root_signature *root_signature,
         const D3D12_ROOT_SIGNATURE_DESC *desc, struct vkd3d_descriptor_set_context *context)
 {
@@ -815,6 +874,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
     uint32_t vk_binding;
 
     root_signature->descriptor_table_mask = 0;
+    context->unbounded = false;
 
     for (i = 0; i < desc->NumParameters; ++i)
     {
@@ -832,6 +892,8 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
         if (!(table->ranges = vkd3d_calloc(table->range_count, sizeof(*table->ranges))))
             return E_OUTOFMEMORY;
 
+        context->table_index = i;
+
         for (j = 0; j < range_count; ++j)
         {
             range = &p->u.DescriptorTable.pDescriptorRanges[j];
@@ -948,10 +1010,12 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa
 }
 
 static HRESULT vkd3d_create_descriptor_set_layout(struct d3d12_device *device,
-        VkDescriptorSetLayoutCreateFlags flags, unsigned int binding_count,
+        VkDescriptorSetLayoutCreateFlags flags, bool unbounded, unsigned int binding_count,
         const VkDescriptorSetLayoutBinding *bindings, VkDescriptorSetLayout *set_layout)
 {
     const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+    VkDescriptorSetLayoutBindingFlagsCreateInfoEXT flags_info;
+    VkDescriptorBindingFlagsEXT *set_flags = NULL;
     VkDescriptorSetLayoutCreateInfo set_desc;
     VkResult vr;
 
@@ -960,7 +1024,28 @@ static HRESULT vkd3d_create_descriptor_set_layout(struct d3d12_device *device,
     set_desc.flags = flags;
     set_desc.bindingCount = binding_count;
     set_desc.pBindings = bindings;
-    if ((vr = VK_CALL(vkCreateDescriptorSetLayout(device->vk_device, &set_desc, NULL, set_layout))) < 0)
+    if (binding_count && device->vk_info.EXT_descriptor_indexing)
+    {
+        unsigned int i;
+
+        if (!(set_flags = vkd3d_malloc(binding_count * sizeof(*set_flags))))
+            return E_OUTOFMEMORY;
+
+        for (i = 0; i < binding_count; ++i)
+            set_flags[i] = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT;
+
+        if (unbounded)
+            set_flags[binding_count - 1] |= VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT;
+
+        set_desc.pNext = &flags_info;
+        flags_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT;
+        flags_info.pNext = NULL;
+        flags_info.bindingCount = binding_count;
+        flags_info.pBindingFlags = set_flags;
+    }
+    vr = VK_CALL(vkCreateDescriptorSetLayout(device->vk_device, &set_desc, NULL, set_layout));
+    vkd3d_free(set_flags);
+    if (vr < 0)
     {
         WARN("Failed to create Vulkan descriptor set layout, vr %d.\n", vr);
         return hresult_from_vk_result(vr);
@@ -977,6 +1062,10 @@ static HRESULT vkd3d_create_pipeline_layout(struct d3d12_device *device,
     const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
     struct VkPipelineLayoutCreateInfo pipeline_layout_info;
     VkResult vr;
+    HRESULT hr;
+
+    if (FAILED(hr = vkd3d_validate_descriptor_set_count(device, set_layout_count)))
+        return hr;
 
     pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
     pipeline_layout_info.pNext = NULL;
@@ -1017,6 +1106,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
     root_signature->descriptor_mapping = NULL;
     root_signature->static_sampler_count = 0;
     root_signature->static_samplers = NULL;
+    root_signature->device = device;
 
     if (desc->Flags & ~(D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT
             | D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT))
@@ -1033,6 +1123,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
     root_signature->mapping_count = info.mapping_count;
     root_signature->static_sampler_count = desc->NumStaticSamplers;
     root_signature->root_descriptor_count = info.root_descriptor_count;
+    root_signature->bindless = device->vk_info.EXT_descriptor_indexing;
 
     hr = E_OUTOFMEMORY;
     root_signature->parameter_count = desc->NumParameters;
@@ -1052,22 +1143,18 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
 
     if (!(binding_desc = vkd3d_calloc(info.binding_count, sizeof(*binding_desc))))
         goto fail;
+    context.first_binding = binding_desc;
     context.current_binding = binding_desc;
 
     if (FAILED(hr = d3d12_root_signature_init_root_descriptors(root_signature, desc, &context)))
         goto fail;
 
     /* We use KHR_push_descriptor for root descriptor parameters. */
-    if (vk_info->KHR_push_descriptor && context.descriptor_binding)
+    if (vk_info->KHR_push_descriptor)
     {
-        if (FAILED(hr = vkd3d_create_descriptor_set_layout(device,
-                VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
-                context.descriptor_binding, binding_desc, &root_signature->vk_set_layouts[0])))
+        if (FAILED(hr = d3d12_root_signature_append_descriptor_set_layout(root_signature,
+                &context, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)))
             goto fail;
-        ++root_signature->vk_set_count;
-
-        context.current_binding = binding_desc;
-        context.descriptor_binding = 0;
     }
 
     if (FAILED(hr = d3d12_root_signature_init_push_constants(root_signature, desc,
@@ -1079,14 +1166,9 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
         goto fail;
 
     root_signature->main_set = root_signature->vk_set_count;
-    if (context.descriptor_binding)
-    {
-        if (FAILED(hr = vkd3d_create_descriptor_set_layout(device,
-                0, context.descriptor_binding, binding_desc,
-                &root_signature->vk_set_layouts[root_signature->vk_set_count])))
-            goto fail;
-        ++root_signature->vk_set_count;
-    }
+    if (FAILED(hr = d3d12_root_signature_append_descriptor_set_layout(root_signature, &context, 0)))
+        goto fail;
+
     vkd3d_free(binding_desc);
     binding_desc = NULL;
 
@@ -1098,7 +1180,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
     if (FAILED(hr = vkd3d_private_store_init(&root_signature->private_store)))
         goto fail;
 
-    d3d12_device_add_ref(root_signature->device = device);
+    d3d12_device_add_ref(device);
 
     return S_OK;
 
@@ -1708,7 +1790,7 @@ static HRESULT d3d12_pipeline_state_init_compute_uav_counters(struct d3d12_pipel
 
     /* Create a descriptor set layout for UAV counters. */
     hr = vkd3d_create_descriptor_set_layout(device,
-            0, descriptor_binding, binding_desc, &state->vk_set_layout);
+            0, false, descriptor_binding, binding_desc, &state->vk_set_layout);
     vkd3d_free(binding_desc);
     if (FAILED(hr))
     {
@@ -3185,7 +3267,7 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d
     {
         set_binding.descriptorType = set_layouts[i].descriptor_type;
 
-        if (FAILED(hr = vkd3d_create_descriptor_set_layout(device, 0, 1, &set_binding, set_layouts[i].set_layout)))
+        if (FAILED(hr = vkd3d_create_descriptor_set_layout(device, 0, false, 1, &set_binding, set_layouts[i].set_layout)))
         {
             ERR("Failed to create descriptor set layout %u, hr %#x.\n", i, hr);
             goto fail;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 79cd3f4f..cc1bf46f 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -702,6 +702,9 @@ struct d3d12_root_signature
     VkPipelineLayout vk_pipeline_layout;
     uint32_t vk_set_count;
     VkDescriptorSetLayout vk_set_layouts[VKD3D_MAX_DESCRIPTOR_SETS];
+    unsigned int vk_set_layout_static_counts[VKD3D_MAX_DESCRIPTOR_SETS];
+    int vk_unbounded_set_tables[VKD3D_MAX_DESCRIPTOR_SETS];
+    bool bindless;
 
     struct d3d12_root_parameter *parameters;
     unsigned int parameter_count;
-- 
2.31.1




More information about the wine-devel mailing list