vkd3d: Store only a single vkd3d descriptor type in each Vulkan descriptor set.

We currently create statically sized descriptor pools, shared among
different descriptor types. Once we're unable to allocate a descriptor
set from a pool, we create a new pool. The unfortunate but predictable
consequence is that when we run out of descriptors of one type, we waste
any unallocated descriptors of the other types.

Dynamically adjusting the pool sizes could mitigate the issue, but it
seems non-trivial to handle all the edge cases, particularly in
situations where the descriptor count ratios change significantly
between frames. Instead, by storing only a single vkd3d descriptor type
in each Vulkan descriptor set we're able to create separate descriptor
pools for each vkd3d descriptor type, which also avoids the issue.

The main drawback of using separate descriptor sets for each descriptor
type is that we can no longer pack all bounded descriptor ranges into a
single descriptor set, potentially leaving fewer descriptor sets
available for unbounded ranges. That seems worth it, but we may end up
having to switch to a more complicated strategy if this ends up being a
problem on Vulkan implementations with a very limited number of
available descriptor sets.
This commit is contained in:
Conor McCarthy
2024-09-16 16:47:18 +10:00
committed by Henri Verbeet
parent 01117c716d
commit 4a94bfc2f6
Notes: Henri Verbeet 2024-12-05 21:35:35 +01:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1088
3 changed files with 131 additions and 90 deletions

View File

@@ -2805,15 +2805,8 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des
break;
}
if (range->descriptor_count == UINT_MAX)
{
vk_descriptor_write->dstSet = vk_descriptor_sets[set + 1];
vk_descriptor_write->dstBinding = 0;
}
else
{
vk_descriptor_write->dstBinding += use_array ? 1 : range->descriptor_count;
}
vk_descriptor_write->dstSet = vk_descriptor_sets[range->image_set];
vk_descriptor_write->dstBinding = use_array ? range->image_binding : range->image_binding + index;
vk_image_info->sampler = VK_NULL_HANDLE;
vk_image_info->imageView = u.view->v.u.vk_image_view;
@@ -2934,10 +2927,11 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list
}
static bool vk_write_descriptor_set_from_root_descriptor(VkWriteDescriptorSet *vk_descriptor_write,
const struct d3d12_root_parameter *root_parameter, VkDescriptorSet vk_descriptor_set,
const struct d3d12_root_parameter *root_parameter, const VkDescriptorSet *vk_descriptor_sets,
VkBufferView *vk_buffer_view, const VkDescriptorBufferInfo *vk_buffer_info)
{
const struct d3d12_root_descriptor *root_descriptor;
VkDescriptorSet vk_descriptor_set;
switch (root_parameter->parameter_type)
{
@@ -2956,6 +2950,7 @@ static bool vk_write_descriptor_set_from_root_descriptor(VkWriteDescriptorSet *v
}
root_descriptor = &root_parameter->u.descriptor;
vk_descriptor_set = vk_descriptor_sets ? vk_descriptor_sets[root_descriptor->set] : VK_NULL_HANDLE;
vk_descriptor_write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
vk_descriptor_write->pNext = NULL;
@@ -3011,7 +3006,7 @@ static void d3d12_command_list_update_push_descriptors(struct d3d12_command_list
}
if (!vk_write_descriptor_set_from_root_descriptor(&descriptor_writes[descriptor_count],
root_parameter, bindings->descriptor_sets[0], vk_buffer_view, vk_buffer_info))
root_parameter, bindings->descriptor_sets, vk_buffer_view, vk_buffer_info))
continue;
++descriptor_count;
@@ -4612,8 +4607,7 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list,
if (vk_info->KHR_push_descriptor)
{
vk_write_descriptor_set_from_root_descriptor(&descriptor_write,
root_parameter, VK_NULL_HANDLE, NULL, &buffer_info);
vk_write_descriptor_set_from_root_descriptor(&descriptor_write, root_parameter, NULL, NULL, &buffer_info);
VK_CALL(vkCmdPushDescriptorSetKHR(list->vk_command_buffer, bindings->vk_bind_point,
root_signature->vk_pipeline_layout, 0, 1, &descriptor_write));
}
@@ -4621,7 +4615,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_sets[0], NULL, &buffer_info);
root_parameter, bindings->descriptor_sets, NULL, &buffer_info);
VK_CALL(vkUpdateDescriptorSets(list->device->vk_device, 1, &descriptor_write, 0, NULL));
VKD3D_ASSERT(index < ARRAY_SIZE(bindings->push_descriptors));
@@ -4685,8 +4679,7 @@ static void d3d12_command_list_set_root_descriptor(struct d3d12_command_list *li
if (vk_info->KHR_push_descriptor)
{
vk_write_descriptor_set_from_root_descriptor(&descriptor_write,
root_parameter, VK_NULL_HANDLE, &vk_buffer_view, NULL);
vk_write_descriptor_set_from_root_descriptor(&descriptor_write, root_parameter, NULL, &vk_buffer_view, NULL);
VK_CALL(vkCmdPushDescriptorSetKHR(list->vk_command_buffer, bindings->vk_bind_point,
root_signature->vk_pipeline_layout, 0, 1, &descriptor_write));
}
@@ -4694,7 +4687,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_sets[0], &vk_buffer_view, NULL);
root_parameter, bindings->descriptor_sets, &vk_buffer_view, NULL);
VK_CALL(vkUpdateDescriptorSets(list->device->vk_device, 1, &descriptor_write, 0, NULL));
VKD3D_ASSERT(index < ARRAY_SIZE(bindings->push_descriptors));