vkd3d: Back descriptor heaps with Vulkan descriptor sets if descriptor indexing is available.

The existing implementation using virtual descriptor heaps, where Vk
descriptor sets are created for the bindings in the root descriptor tables,
is inefficient when multiple command lists are used with large descriptor
heaps. It also cannot support updating a descriptor set after it is bound.

This patch creates Vk sets for each D3D12 heap. Because D3D12 heaps
can contain CBV, SRV and UAV descriptors in the same heap, multiple Vk sets
are needed for each heap, however the total number of populated descriptors
is never more than (heap size + UAV counter count).

A new 'virtual_heaps' config option is introduced to make the old
implementation available when needed. It's not always possible to determine
if this is necessary when the device is created.

Up to nine Vk descriptor sets may be used. It's theoretically possible to
reduce this to eight by placing immutable samplers in the push descriptor
set layout, but contradictions in earlier versions of the Vulkan spec made
driver support inconsistent. The documentation was corrected in version
1.2.203.

This patch also adds support for UAV counter descriptor arrays. It's not
practical to add this in a separate patch due to complications with
combining the old UAV counter implementation with the new descriptor heap
implementation.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47713
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47154
Signed-off-by: Conor McCarthy <cmccarthy@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Conor McCarthy
2022-02-22 01:18:59 +10:00
committed by Alexandre Julliard
parent 500ce146c3
commit 2b71ea406f
9 changed files with 787 additions and 19 deletions

View File

@@ -16758,13 +16758,15 @@ static void test_update_descriptor_tables(void)
destroy_test_context(&context);
}
/* This cannot be implemented reasonably in Vulkan. Vulkan doesn't allow
* updating descriptor sets after the vkCmdBindDescriptorSets() command
* is recorded.
/* This requires the Vulkan descriptor indexing extension and Vulkan-backed
* descriptor heaps. Vulkan doesn't allow updating descriptor sets after the
* vkCmdBindDescriptorSets() command is recorded unless the update-after-bind
* feature of descriptor indexing is used.
*/
static void test_update_descriptor_heap_after_closing_command_list(void)
{
ID3D12Resource *red_texture, *green_texture;
D3D12_RESOURCE_BINDING_TIER binding_tier;
ID3D12GraphicsCommandList *command_list;
D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
ID3D12DescriptorHeap *cpu_heap, *heap;
@@ -16814,6 +16816,8 @@ static void test_update_descriptor_heap_after_closing_command_list(void)
command_list = context.list;
queue = context.queue;
binding_tier = get_resource_binding_tier(context.device);
context.root_signature = create_texture_root_signature(context.device,
D3D12_SHADER_VISIBILITY_PIXEL, 0, 0);
context.pipeline_state = create_pipeline_state(context.device,
@@ -16875,7 +16879,8 @@ static void test_update_descriptor_heap_after_closing_command_list(void)
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
value = get_readback_uint(&rb, 0, 0, 0);
todo ok(value == 0xff00ff00, "Got unexpected value %#x.\n", value);
todo_if(binding_tier < D3D12_RESOURCE_BINDING_TIER_3)
ok(value == 0xff00ff00, "Got unexpected value %#x.\n", value);
release_resource_readback(&rb);
ID3D12DescriptorHeap_Release(cpu_heap);