[PATCH vkd3d 2/3] vkd3d: Create Vulkan descriptor sets from variable layouts.
Conor McCarthy
cmccarthy at codeweavers.com
Wed May 26 03:07:53 CDT 2021
Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
libs/vkd3d/command.c | 70 +++++++++++++++++++++++++++++++-------
libs/vkd3d/vkd3d_private.h | 4 ++-
2 files changed, 61 insertions(+), 13 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 116a8a62..5cb95869 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -1363,10 +1363,12 @@ static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool(
}
static VkDescriptorSet d3d12_command_allocator_allocate_descriptor_set(
- struct d3d12_command_allocator *allocator, VkDescriptorSetLayout vk_set_layout)
+ struct d3d12_command_allocator *allocator, VkDescriptorSetLayout vk_set_layout,
+ uint32_t variable_binding_size, bool unbounded)
{
struct d3d12_device *device = allocator->device;
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+ VkDescriptorSetVariableDescriptorCountAllocateInfoEXT set_size;
struct VkDescriptorSetAllocateInfo set_desc;
VkDevice vk_device = device->vk_device;
VkDescriptorSet vk_descriptor_set;
@@ -1382,6 +1384,14 @@ static VkDescriptorSet d3d12_command_allocator_allocate_descriptor_set(
set_desc.descriptorPool = allocator->vk_descriptor_pool;
set_desc.descriptorSetCount = 1;
set_desc.pSetLayouts = &vk_set_layout;
+ if (unbounded)
+ {
+ set_desc.pNext = &set_size;
+ set_size.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT;
+ set_size.pNext = NULL;
+ set_size.descriptorSetCount = 1;
+ set_size.pDescriptorCounts = &variable_binding_size;
+ }
if ((vr = VK_CALL(vkAllocateDescriptorSets(vk_device, &set_desc, &vk_descriptor_set))) >= 0)
return vk_descriptor_set;
@@ -1881,7 +1891,7 @@ static void d3d12_command_list_invalidate_root_parameters(struct d3d12_command_l
if (!bindings->root_signature)
return;
- bindings->descriptor_set = VK_NULL_HANDLE;
+ bindings->descriptor_set_count = 0;
bindings->descriptor_table_dirty_mask = bindings->descriptor_table_active_mask & bindings->root_signature->descriptor_table_mask;
bindings->push_descriptor_dirty_mask = bindings->push_descriptor_active_mask & bindings->root_signature->push_descriptor_mask;
}
@@ -2565,8 +2575,10 @@ static void d3d12_command_list_prepare_descriptors(struct d3d12_command_list *li
{
struct vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point];
const struct d3d12_root_signature *root_signature = bindings->root_signature;
+ struct d3d12_device *device = list->device;
+ unsigned int i;
- if (bindings->descriptor_set && !bindings->in_use)
+ if (bindings->descriptor_set_count && !bindings->in_use)
return;
/* We cannot modify bound descriptor sets. We need a new descriptor set if
@@ -2581,8 +2593,41 @@ static void d3d12_command_list_prepare_descriptors(struct d3d12_command_list *li
* by an update command, or freed) between when the command is recorded
* and when the command completes executing on the queue."
*/
- bindings->descriptor_set = d3d12_command_allocator_allocate_descriptor_set(list->allocator,
- root_signature->vk_set_layouts[root_signature->main_set]);
+ bindings->descriptor_set_count = 0;
+ for (i = root_signature->main_set; i < root_signature->vk_set_count; ++i)
+ {
+ int unbounded_table = root_signature->vk_unbounded_set_tables[i];
+ unsigned int variable_binding_size = 0;
+ if (unbounded_table >= 0)
+ {
+ const struct d3d12_desc *base_descriptor
+ = d3d12_desc_from_gpu_handle(bindings->descriptor_tables[unbounded_table]);
+ /* Descriptors may not be set, eg. WoW. */
+ if (base_descriptor)
+ {
+ unsigned int static_descriptor_count = root_signature->vk_set_layout_static_counts[i];
+ unsigned int heap_size;
+ int rc;
+
+ rc = pthread_mutex_lock(&device->mutex);
+ if (rc)
+ ERR("Failed to lock mutex, error %d.\n", rc);
+ heap_size = d3d12_device_descriptor_heap_size_from_descriptor(device, base_descriptor);
+ if (!rc)
+ pthread_mutex_unlock(&device->mutex);
+
+ if (heap_size >= static_descriptor_count)
+ variable_binding_size = heap_size - static_descriptor_count;
+ else
+ WARN("Descriptor heap size %u is less than the variable binding offset %u.\n", variable_binding_size,
+ static_descriptor_count);
+ }
+ }
+ bindings->descriptor_sets[bindings->descriptor_set_count] =
+ d3d12_command_allocator_allocate_descriptor_set(list->allocator,
+ root_signature->vk_set_layouts[i], variable_binding_size, unbounded_table >= 0);
+ ++bindings->descriptor_set_count;
+ }
bindings->in_use = false;
bindings->descriptor_table_dirty_mask |= bindings->descriptor_table_active_mask & root_signature->descriptor_table_mask;
@@ -2819,7 +2864,7 @@ static void d3d12_command_list_update_push_descriptors(struct d3d12_command_list
}
if (!vk_write_descriptor_set_from_root_descriptor(current_descriptor_write,
- root_parameter, bindings->descriptor_set, vk_buffer_view, vk_buffer_info))
+ root_parameter, bindings->descriptor_sets[0], vk_buffer_view, vk_buffer_info))
continue;
++descriptor_count;
@@ -2849,7 +2894,7 @@ static void d3d12_command_list_update_uav_counter_descriptors(struct d3d12_comma
uav_counter_count = state->uav_counter_count;
if (!(vk_descriptor_writes = vkd3d_calloc(uav_counter_count, sizeof(*vk_descriptor_writes))))
return;
- if (!(vk_descriptor_set = d3d12_command_allocator_allocate_descriptor_set(list->allocator, state->vk_set_layout)))
+ if (!(vk_descriptor_set = d3d12_command_allocator_allocate_descriptor_set(list->allocator, state->vk_set_layout, 0, false)))
goto done;
for (i = 0; i < uav_counter_count; ++i)
@@ -2911,10 +2956,11 @@ static void d3d12_command_list_update_descriptors(struct d3d12_command_list *lis
d3d12_command_list_update_push_descriptors(list, bind_point);
- if (bindings->descriptor_set)
+ if (bindings->descriptor_set_count)
{
VK_CALL(vkCmdBindDescriptorSets(list->vk_command_buffer, bindings->vk_bind_point,
- rs->vk_pipeline_layout, rs->main_set, 1, &bindings->descriptor_set, 0, NULL));
+ rs->vk_pipeline_layout, rs->main_set, bindings->descriptor_set_count, bindings->descriptor_sets,
+ 0, NULL));
bindings->in_use = true;
}
@@ -4229,7 +4275,7 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list,
{
d3d12_command_list_prepare_descriptors(list, bind_point);
vk_write_descriptor_set_from_root_descriptor(&descriptor_write,
- root_parameter, bindings->descriptor_set, NULL, &buffer_info);
+ root_parameter, bindings->descriptor_sets[0], NULL, &buffer_info);
VK_CALL(vkUpdateDescriptorSets(list->device->vk_device, 1, &descriptor_write, 0, NULL));
assert(index < ARRAY_SIZE(bindings->push_descriptors));
@@ -4302,7 +4348,7 @@ static void d3d12_command_list_set_root_descriptor(struct d3d12_command_list *li
{
d3d12_command_list_prepare_descriptors(list, bind_point);
vk_write_descriptor_set_from_root_descriptor(&descriptor_write,
- root_parameter, bindings->descriptor_set, &vk_buffer_view, NULL);
+ root_parameter, bindings->descriptor_sets[0], &vk_buffer_view, NULL);
VK_CALL(vkUpdateDescriptorSets(list->device->vk_device, 1, &descriptor_write, 0, NULL));
assert(index < ARRAY_SIZE(bindings->push_descriptors));
@@ -4949,7 +4995,7 @@ static void d3d12_command_list_clear_uav(struct d3d12_command_list *list,
}
if (!(write_set.dstSet = d3d12_command_allocator_allocate_descriptor_set(
- list->allocator, pipeline.vk_set_layout)))
+ list->allocator, pipeline.vk_set_layout, 0, false)))
{
ERR("Failed to allocate descriptor set.\n");
return;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 28742a8b..d0275062 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -924,7 +924,9 @@ struct vkd3d_pipeline_bindings
const struct d3d12_root_signature *root_signature;
VkPipelineBindPoint vk_bind_point;
- VkDescriptorSet descriptor_set;
+ /* All descriptor sets at index > 1 are for unbounded D3D12 ranges. Set 0 or 1 may be unbounded too. */
+ size_t descriptor_set_count;
+ VkDescriptorSet descriptor_sets[VKD3D_MAX_DESCRIPTOR_SETS];
bool in_use;
D3D12_GPU_DESCRIPTOR_HANDLE descriptor_tables[D3D12_MAX_ROOT_COST];
--
2.31.1
More information about the wine-devel
mailing list