mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d: Track all descriptor heaps bound during command list recording and flush their writes.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54895
This commit is contained in:
parent
d3876e49bc
commit
fa63da6030
@ -3159,6 +3159,27 @@ static void d3d12_command_list_update_descriptor_tables(struct d3d12_command_lis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool contains_heap(struct d3d12_descriptor_heap **heap_array, unsigned int count,
|
||||||
|
const struct d3d12_descriptor_heap *query)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
if (heap_array[i] == query)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void command_list_flush_vk_heap_updates(struct d3d12_command_list *list)
|
||||||
|
{
|
||||||
|
struct d3d12_device *device = list->device;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < list->descriptor_heap_count; ++i)
|
||||||
|
d3d12_desc_flush_vk_heap_updates(list->descriptor_heaps[i], device);
|
||||||
|
list->descriptor_heap_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void d3d12_command_list_bind_descriptor_heap(struct d3d12_command_list *list,
|
static void d3d12_command_list_bind_descriptor_heap(struct d3d12_command_list *list,
|
||||||
enum vkd3d_pipeline_bind_point bind_point, struct d3d12_descriptor_heap *heap)
|
enum vkd3d_pipeline_bind_point bind_point, struct d3d12_descriptor_heap *heap)
|
||||||
{
|
{
|
||||||
@ -3183,6 +3204,17 @@ static void d3d12_command_list_bind_descriptor_heap(struct d3d12_command_list *l
|
|||||||
bindings->sampler_heap_id = heap->serial_id;
|
bindings->sampler_heap_id = heap->serial_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!contains_heap(list->descriptor_heaps, list->descriptor_heap_count, heap))
|
||||||
|
{
|
||||||
|
if (list->descriptor_heap_count == ARRAY_SIZE(list->descriptor_heaps))
|
||||||
|
{
|
||||||
|
/* Descriptors can be written after binding. */
|
||||||
|
FIXME("Flushing descriptor updates while list %p is not closed.\n", list);
|
||||||
|
command_list_flush_vk_heap_updates(list);
|
||||||
|
}
|
||||||
|
list->descriptor_heaps[list->descriptor_heap_count++] = heap;
|
||||||
|
}
|
||||||
|
|
||||||
for (set = 0; set < ARRAY_SIZE(heap->vk_descriptor_sets); ++set)
|
for (set = 0; set < ARRAY_SIZE(heap->vk_descriptor_sets); ++set)
|
||||||
{
|
{
|
||||||
VkDescriptorSet vk_descriptor_set = heap->vk_descriptor_sets[set].vk_set;
|
VkDescriptorSet vk_descriptor_set = heap->vk_descriptor_sets[set].vk_set;
|
||||||
@ -5927,6 +5959,7 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d
|
|||||||
|
|
||||||
list->update_descriptors = device->use_vk_heaps ? d3d12_command_list_update_heap_descriptors
|
list->update_descriptors = device->use_vk_heaps ? d3d12_command_list_update_heap_descriptors
|
||||||
: d3d12_command_list_update_descriptors;
|
: d3d12_command_list_update_descriptors;
|
||||||
|
list->descriptor_heap_count = 0;
|
||||||
|
|
||||||
if (SUCCEEDED(hr = d3d12_command_allocator_allocate_command_buffer(allocator, list)))
|
if (SUCCEEDED(hr = d3d12_command_allocator_allocate_command_buffer(allocator, list)))
|
||||||
{
|
{
|
||||||
@ -6187,44 +6220,6 @@ static void d3d12_command_queue_submit_locked(struct d3d12_command_queue *queue)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool contains_heap(const struct d3d12_descriptor_heap **heap_array, unsigned int count,
|
|
||||||
const struct d3d12_descriptor_heap *query)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; ++i)
|
|
||||||
if (heap_array[i] == query)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pipeline_bindings_flush_vk_heap_updates(struct vkd3d_pipeline_bindings *bindings,
|
|
||||||
struct d3d12_device *device)
|
|
||||||
{
|
|
||||||
/* Only two heaps are strictly allowed, but more could be supported with a hack. */
|
|
||||||
const struct d3d12_descriptor_heap *heap_array[3];
|
|
||||||
struct d3d12_descriptor_heap *descriptor_heap;
|
|
||||||
unsigned int i, count;
|
|
||||||
uint64_t mask;
|
|
||||||
|
|
||||||
mask = bindings->descriptor_table_active_mask & bindings->root_signature->descriptor_table_mask;
|
|
||||||
|
|
||||||
for (i = 0, count = 0; i < ARRAY_SIZE(bindings->descriptor_tables); ++i)
|
|
||||||
{
|
|
||||||
if (!(mask & (1ull << i)) || !bindings->descriptor_tables[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
descriptor_heap = d3d12_desc_get_descriptor_heap(bindings->descriptor_tables[i]);
|
|
||||||
/* Another thread could be writing unused descriptors, so try to check each heap only once. Flushing
|
|
||||||
* any updates added after the first flush will only delay execution of the command list. */
|
|
||||||
if (contains_heap(heap_array, count, descriptor_heap))
|
|
||||||
continue;
|
|
||||||
if (count < ARRAY_SIZE(heap_array))
|
|
||||||
heap_array[count++] = descriptor_heap;
|
|
||||||
d3d12_desc_flush_vk_heap_updates(descriptor_heap, device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12CommandQueue *iface,
|
static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12CommandQueue *iface,
|
||||||
UINT command_list_count, ID3D12CommandList * const *command_lists)
|
UINT command_list_count, ID3D12CommandList * const *command_lists)
|
||||||
{
|
{
|
||||||
@ -6258,9 +6253,7 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd_list->state)
|
command_list_flush_vk_heap_updates(cmd_list);
|
||||||
pipeline_bindings_flush_vk_heap_updates(&cmd_list->pipeline_bindings[cmd_list->state->vk_bind_point],
|
|
||||||
cmd_list->device);
|
|
||||||
|
|
||||||
buffers[i] = cmd_list->vk_command_buffer;
|
buffers[i] = cmd_list->vk_command_buffer;
|
||||||
}
|
}
|
||||||
|
@ -1407,6 +1407,8 @@ struct d3d12_command_list
|
|||||||
VkDeviceSize so_counter_buffer_offsets[D3D12_SO_BUFFER_SLOT_COUNT];
|
VkDeviceSize so_counter_buffer_offsets[D3D12_SO_BUFFER_SLOT_COUNT];
|
||||||
|
|
||||||
void (*update_descriptors)(struct d3d12_command_list *list, enum vkd3d_pipeline_bind_point bind_point);
|
void (*update_descriptors)(struct d3d12_command_list *list, enum vkd3d_pipeline_bind_point bind_point);
|
||||||
|
struct d3d12_descriptor_heap *descriptor_heaps[64];
|
||||||
|
unsigned int descriptor_heap_count;
|
||||||
|
|
||||||
struct vkd3d_private_store private_store;
|
struct vkd3d_private_store private_store;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user