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@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;