[PATCH vkd3d 3/4] vkd3d: Emit a noop wait between command queue executions to implement the D3D12 command order guarantee.
Conor McCarthy
cmccarthy at codeweavers.com
Thu May 12 10:11:07 CDT 2022
D3D12 guarantees no overlap between commands sent in separate calls to
ExecuteCommandLists(). A Vulkan noop wait provides a barrier against
reordering.
Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
libs/vkd3d/command.c | 18 ++++++++++++++++++
libs/vkd3d/device.c | 13 +++++++++++++
libs/vkd3d/vkd3d_private.h | 2 ++
3 files changed, 33 insertions(+)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index d0782e5a..a44eb02f 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -6285,9 +6285,13 @@ static void STDMETHODCALLTYPE d3d12_command_queue_CopyTileMappings(ID3D12Command
static void d3d12_command_queue_execute(struct d3d12_command_queue *command_queue,
VkCommandBuffer *buffers, unsigned int count)
{
+ static const VkPipelineStageFlagBits wait_stage_mask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
const struct vkd3d_vk_device_procs *vk_procs = &command_queue->device->vk_procs;
struct vkd3d_queue *vkd3d_queue = command_queue->vkd3d_queue;
+ VkTimelineSemaphoreSubmitInfoKHR timeline_submit_info;
+ struct d3d12_device *device = command_queue->device;
VkSubmitInfo submit_desc;
+ uint64_t noop_value = 0;
VkQueue vk_queue;
VkResult vr;
@@ -6300,6 +6304,20 @@ static void d3d12_command_queue_execute(struct d3d12_command_queue *command_queu
}
submit_desc.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ if (device->vk_info.KHR_timeline_semaphore)
+ {
+ /* Insert a noop wait to provide the barrier between executions which D3D12 guarantees.
+ * The limitations of binary semaphores would make this complex to do with them. */
+ submit_desc.pNext = &timeline_submit_info;
+ submit_desc.pWaitSemaphores = &device->noop_semaphore;
+ submit_desc.waitSemaphoreCount = 1;
+ submit_desc.pWaitDstStageMask = &wait_stage_mask;
+
+ memset(&timeline_submit_info, 0, sizeof(timeline_submit_info));
+ timeline_submit_info.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR;
+ timeline_submit_info.waitSemaphoreValueCount = 1;
+ timeline_submit_info.pWaitSemaphoreValues = &noop_value;
+ }
submit_desc.commandBufferCount = count;
submit_desc.pCommandBuffers = buffers;
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index eaedc444..bdc80ba3 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -2626,6 +2626,7 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface)
vkd3d_private_store_destroy(&device->private_store);
vkd3d_cleanup_format_info(device);
+ VK_CALL(vkDestroySemaphore(device->vk_device, device->noop_semaphore, NULL));
vkd3d_vk_descriptor_heap_layouts_cleanup(device);
vkd3d_uav_clear_state_cleanup(&device->uav_clear_state, device);
vkd3d_destroy_null_resources(&device->null_resources, device);
@@ -4241,6 +4242,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
struct vkd3d_instance *instance, const struct vkd3d_device_create_info *create_info)
{
const struct vkd3d_vk_device_procs *vk_procs;
+ VkResult vr;
HRESULT hr;
size_t i;
@@ -4278,6 +4280,15 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
if (FAILED(hr = vkd3d_vk_descriptor_heap_layouts_init(device)))
goto out_cleanup_uav_clear_state;
+ device->noop_semaphore = VK_NULL_HANDLE;
+ if (device->vk_info.KHR_timeline_semaphore && (vr = vkd3d_create_timeline_semaphore(device, 0,
+ &device->noop_semaphore)) < 0)
+ {
+ WARN("Failed to create timeline semaphore, vr %d.\n", vr);
+ hr = hresult_from_vk_result(vr);
+ goto out_cleanup_descriptor_heap_layouts;
+ }
+
vkd3d_render_pass_cache_init(&device->render_pass_cache);
vkd3d_gpu_descriptor_allocator_init(&device->gpu_descriptor_allocator);
vkd3d_gpu_va_allocator_init(&device->gpu_va_allocator);
@@ -4295,6 +4306,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
return S_OK;
+out_cleanup_descriptor_heap_layouts:
+ vkd3d_vk_descriptor_heap_layouts_cleanup(device);
out_cleanup_uav_clear_state:
vkd3d_uav_clear_state_cleanup(&device->uav_clear_state, device);
out_destroy_null_resources:
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index f00181a2..37bac159 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -1493,6 +1493,8 @@ struct d3d12_device
struct d3d12_command_queue *blocked_queues[VKD3D_MAX_DEVICE_BLOCKED_QUEUES];
unsigned int blocked_queue_count;
+ VkSemaphore noop_semaphore;
+
struct vkd3d_instance *vkd3d_instance;
IUnknown *parent;
--
2.35.1
More information about the wine-devel
mailing list