mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-04-13 05:43:18 -07:00
vkd3d: Put all root descriptors in a single Vulkan descriptor set when using Vulkan heaps.
Since 4a94bfc2f6
we segregate
different D3D12 descriptor types in different Vulkan descriptor sets.
This change was introduced to reduce descriptor wasting when
allocating a new descriptor pool; that can be very useful when
using virtual heaps, which have to often cycle through many
descriptors, but it is expected to have limited impact for Vulkan
heaps, given that in that case most descriptors are allocated through
the descriptor heap rather than through the command allocator.
Instead, it has a rather detrimental effect with Vulkan heaps,
because it tends to use many more Vulkan descriptor sets than
necessary, often with just a handful of descriptors each. This
causes a regression on some Vulkan implementations that support
too few descriptor sets.
With this change we revert to a situation similar to before,
stuffing all the descriptors that do not live in a root
descriptor table in as few descriptor sets as possible (at most
one or two, depending on whether push descriptors are used).
This commit is contained in:
committed by
Henri Verbeet
parent
6415c6b0e0
commit
07b7975d09
Notes:
Henri Verbeet
2025-02-19 18:03:19 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1376
@ -1499,7 +1499,7 @@ static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool(
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
struct VkDescriptorPoolCreateInfo pool_desc;
|
||||
VkDevice vk_device = device->vk_device;
|
||||
VkDescriptorPoolSize vk_pool_sizes[2];
|
||||
VkDescriptorPoolSize vk_pool_sizes[4];
|
||||
unsigned int pool_size, pool_limit;
|
||||
VkDescriptorPool vk_pool;
|
||||
VkResult vr;
|
||||
@ -1530,21 +1530,43 @@ static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool(
|
||||
}
|
||||
descriptor_count = pool_size;
|
||||
|
||||
vk_pool_sizes[0].type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, true);
|
||||
vk_pool_sizes[0].descriptorCount = descriptor_count;
|
||||
|
||||
vk_pool_sizes[1].type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, false);
|
||||
vk_pool_sizes[1].descriptorCount = descriptor_count;
|
||||
|
||||
pool_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||
pool_desc.pNext = NULL;
|
||||
pool_desc.flags = 0;
|
||||
pool_desc.maxSets = 512;
|
||||
pool_desc.poolSizeCount = 1;
|
||||
if (vk_pool_sizes[1].type != vk_pool_sizes[0].type)
|
||||
++pool_desc.poolSizeCount;
|
||||
pool_desc.pPoolSizes = vk_pool_sizes;
|
||||
|
||||
if (allocator->device->use_vk_heaps)
|
||||
{
|
||||
/* SRV root descriptors. */
|
||||
vk_pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
|
||||
vk_pool_sizes[0].descriptorCount = descriptor_count;
|
||||
|
||||
/* UAV root descriptors and UAV counters. */
|
||||
vk_pool_sizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
|
||||
vk_pool_sizes[1].descriptorCount = descriptor_count;
|
||||
|
||||
/* CBV root descriptors. */
|
||||
vk_pool_sizes[2].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
vk_pool_sizes[2].descriptorCount = descriptor_count;
|
||||
|
||||
/* Static samplers. */
|
||||
vk_pool_sizes[3].type = VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||
vk_pool_sizes[3].descriptorCount = descriptor_count;
|
||||
|
||||
pool_desc.poolSizeCount = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
vk_pool_sizes[0].type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, true);
|
||||
vk_pool_sizes[0].descriptorCount = descriptor_count;
|
||||
|
||||
vk_pool_sizes[1].type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, false);
|
||||
vk_pool_sizes[1].descriptorCount = descriptor_count;
|
||||
|
||||
pool_desc.poolSizeCount = 1 + (vk_pool_sizes[0].type != vk_pool_sizes[1].type);
|
||||
}
|
||||
|
||||
if ((vr = VK_CALL(vkCreateDescriptorPool(vk_device, &pool_desc, NULL, &vk_pool))) < 0)
|
||||
{
|
||||
ERR("Failed to create descriptor pool, vr %d.\n", vr);
|
||||
@ -1578,6 +1600,10 @@ static VkDescriptorSet d3d12_command_allocator_allocate_descriptor_set(struct d3
|
||||
VkDescriptorSet vk_descriptor_set;
|
||||
VkResult vr;
|
||||
|
||||
/* With Vulkan heaps we use just one descriptor pool. */
|
||||
if (device->use_vk_heaps)
|
||||
descriptor_type = 0;
|
||||
|
||||
if (!allocator->vk_descriptor_pools[descriptor_type])
|
||||
allocator->vk_descriptor_pools[descriptor_type] = d3d12_command_allocator_allocate_descriptor_pool(allocator,
|
||||
descriptor_type, descriptor_count, unbounded);
|
||||
|
@ -755,7 +755,10 @@ struct vkd3d_descriptor_set_context
|
||||
unsigned int push_constant_index;
|
||||
|
||||
struct vk_binding_array *root_descriptor_set;
|
||||
struct vk_binding_array *static_samplers_descriptor_set;
|
||||
bool push_descriptor;
|
||||
bool static_samplers;
|
||||
bool use_vk_heaps;
|
||||
};
|
||||
|
||||
static void descriptor_set_context_cleanup(struct vkd3d_descriptor_set_context *context)
|
||||
@ -806,15 +809,61 @@ static struct vk_binding_array *d3d12_root_signature_vk_binding_array_for_type(
|
||||
{
|
||||
struct vk_binding_array *array, **current;
|
||||
|
||||
/* There are a few different ways we can reach this point:
|
||||
* * If we are using virtual heaps we want to allocate descriptors to sets
|
||||
* depending on their descriptor type, in order to minimize waste when
|
||||
* recycling descriptor pools.
|
||||
* + With the exception of root descriptors when we are using push
|
||||
* descriptors: the push descriptors must be in a separate set, so we
|
||||
* keep one specifically for them.
|
||||
* * If we are using Vulkan heaps then all the root table descriptors don't
|
||||
* even reach here, because they are managed by the D3D12 descriptor
|
||||
* heap. Thus we only have to deal with root descriptors and static
|
||||
* samplers.
|
||||
* + If we're using push descriptors then again we have to dedicate a set
|
||||
* for them, so static samplers will and up in their own set too.
|
||||
* + If we're not using push descriptors then we can use the same set and
|
||||
* save one. In this case we don't care too much about minimizing
|
||||
* wasted descriptors, because few descriptors can end up here anyway.
|
||||
*/
|
||||
|
||||
if (context->push_descriptor)
|
||||
{
|
||||
/* The descriptor type is irrelevant here, it will never be used. */
|
||||
if (!context->root_descriptor_set)
|
||||
context->root_descriptor_set = d3d12_root_signature_append_vk_binding_array(root_signature,
|
||||
descriptor_type, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, context);
|
||||
0, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, context);
|
||||
|
||||
return context->root_descriptor_set;
|
||||
}
|
||||
|
||||
if (context->use_vk_heaps)
|
||||
{
|
||||
if (context->static_samplers)
|
||||
{
|
||||
if (!context->static_samplers_descriptor_set)
|
||||
{
|
||||
if (!context->push_descriptor && context->root_descriptor_set)
|
||||
context->static_samplers_descriptor_set = context->root_descriptor_set;
|
||||
else
|
||||
/* The descriptor type is irrelevant here, it will never be used. */
|
||||
context->static_samplers_descriptor_set = d3d12_root_signature_append_vk_binding_array(
|
||||
root_signature, 0, 0, context);
|
||||
}
|
||||
|
||||
return context->static_samplers_descriptor_set;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The descriptor type is irrelevant here, it will never be used. */
|
||||
if (!context->root_descriptor_set)
|
||||
context->root_descriptor_set = d3d12_root_signature_append_vk_binding_array(
|
||||
root_signature, 0, 0, context);
|
||||
|
||||
return context->root_descriptor_set;
|
||||
}
|
||||
}
|
||||
|
||||
current = context->current_binding_array;
|
||||
if (!(array = current[descriptor_type]))
|
||||
{
|
||||
@ -1638,17 +1687,22 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
|
||||
sizeof(*root_signature->static_samplers))))
|
||||
goto fail;
|
||||
|
||||
context.use_vk_heaps = use_vk_heaps;
|
||||
context.push_descriptor = vk_info->KHR_push_descriptor;
|
||||
if (FAILED(hr = d3d12_root_signature_init_root_descriptors(root_signature, desc, &context)))
|
||||
goto fail;
|
||||
root_signature->main_set = !!context.root_descriptor_set;
|
||||
root_signature->main_set = context.root_descriptor_set && context.push_descriptor;
|
||||
context.push_descriptor = false;
|
||||
|
||||
if (FAILED(hr = d3d12_root_signature_init_push_constants(root_signature, desc,
|
||||
root_signature->push_constant_ranges, &root_signature->push_constant_range_count)))
|
||||
goto fail;
|
||||
|
||||
context.static_samplers = true;
|
||||
if (FAILED(hr = d3d12_root_signature_init_static_samplers(root_signature, device, desc, &context)))
|
||||
goto fail;
|
||||
context.static_samplers = false;
|
||||
|
||||
context.push_constant_index = 0;
|
||||
if (FAILED(hr = d3d12_root_signature_init_root_descriptor_tables(root_signature, desc, &info, &context)))
|
||||
goto fail;
|
||||
|
Reference in New Issue
Block a user