From f00b10a56c8c2cbee71c823b3db15edc0fde02d3 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Fri, 23 Feb 2024 12:48:21 +0100 Subject: [PATCH 1/3] vkd3d: Add low latency sleep support to queue profile. Display region application is sleeping. Signed-off-by: Hans-Kristian Arntzen --- libs/vkd3d/queue_timeline.c | 28 ++++++++++++++++++++++++---- libs/vkd3d/swapchain.c | 5 +++++ libs/vkd3d/vkd3d_private.h | 8 ++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/libs/vkd3d/queue_timeline.c b/libs/vkd3d/queue_timeline.c index db7ae8c566..dc2c102afb 100644 --- a/libs/vkd3d/queue_timeline.c +++ b/libs/vkd3d/queue_timeline.c @@ -221,8 +221,8 @@ void vkd3d_queue_timeline_trace_complete_present_wait(struct vkd3d_queue_timelin vkd3d_queue_timeline_trace_free_index(trace, cookie.index); } -void vkd3d_queue_timeline_trace_complete_present_block(struct vkd3d_queue_timeline_trace *trace, - struct vkd3d_queue_timeline_trace_cookie cookie) +void vkd3d_queue_timeline_trace_complete_blocking(struct vkd3d_queue_timeline_trace *trace, + struct vkd3d_queue_timeline_trace_cookie cookie, const char *pid) { const struct vkd3d_queue_timeline_trace_state *state; double end_ts, start_ts; @@ -234,12 +234,24 @@ void vkd3d_queue_timeline_trace_complete_present_block(struct vkd3d_queue_timeli end_ts = (double)(vkd3d_get_current_time_ns() - trace->base_ts) * 1e-3; start_ts = (double)(state->start_ts - trace->base_ts) * 1e-3; - fprintf(trace->file, "{ \"name\": \"%s\", \"ph\": \"X\", \"tid\": \"0x%04x\", \"pid\": \"IDXGISwapChain::Present()\", \"ts\": %f, \"dur\": %f },\n", - state->desc, state->tid, start_ts, end_ts - start_ts); + fprintf(trace->file, "{ \"name\": \"%s\", \"ph\": \"X\", \"tid\": \"0x%04x\", \"pid\": \"%s\", \"ts\": %f, \"dur\": %f },\n", + state->desc, state->tid, pid, start_ts, end_ts - start_ts); vkd3d_queue_timeline_trace_free_index(trace, cookie.index); } +void vkd3d_queue_timeline_trace_complete_present_block(struct vkd3d_queue_timeline_trace *trace, + struct vkd3d_queue_timeline_trace_cookie cookie) +{ + vkd3d_queue_timeline_trace_complete_blocking(trace, cookie, "IDXGISwapChain::Present()"); +} + +void vkd3d_queue_timeline_trace_complete_low_latency_sleep(struct vkd3d_queue_timeline_trace *trace, + struct vkd3d_queue_timeline_trace_cookie cookie) +{ + vkd3d_queue_timeline_trace_complete_blocking(trace, cookie, "ID3DLowLatencyDevice::LatencySleep()"); +} + struct vkd3d_queue_timeline_trace_cookie vkd3d_queue_timeline_trace_register_execute(struct vkd3d_queue_timeline_trace *trace, ID3D12CommandList * const *command_lists, unsigned int count) @@ -419,6 +431,14 @@ vkd3d_queue_timeline_trace_register_present_block(struct vkd3d_queue_timeline_tr return vkd3d_queue_timeline_trace_register_generic_op(trace, VKD3D_QUEUE_TIMELINE_TRACE_STATE_TYPE_PRESENT_BLOCK, str); } +struct vkd3d_queue_timeline_trace_cookie +vkd3d_queue_timeline_trace_register_low_latency_sleep(struct vkd3d_queue_timeline_trace *trace, uint64_t present_id) +{ + char str[128]; + snprintf(str, sizeof(str), "LATENCY SLEEP (id = %"PRIu64")", present_id); + return vkd3d_queue_timeline_trace_register_generic_op(trace, VKD3D_QUEUE_TIMELINE_TRACE_STATE_TYPE_LOW_LATENCY_SLEEP, str); +} + static void vkd3d_queue_timeline_trace_flush_instantaneous(struct vkd3d_queue_timeline_trace *trace, struct vkd3d_fence_worker *worker) { diff --git a/libs/vkd3d/swapchain.c b/libs/vkd3d/swapchain.c index 4b7e8a6191..c644daeb3c 100644 --- a/libs/vkd3d/swapchain.c +++ b/libs/vkd3d/swapchain.c @@ -2697,6 +2697,7 @@ bool dxgi_vk_swap_chain_low_latency_enabled(struct dxgi_vk_swap_chain *chain) void dxgi_vk_swap_chain_latency_sleep(struct dxgi_vk_swap_chain *chain) { const struct vkd3d_vk_device_procs *vk_procs = &chain->queue->device->vk_procs; + struct vkd3d_queue_timeline_trace_cookie cookie; VkLatencySleepInfoNV latency_sleep_info; VkSemaphoreWaitInfo sem_wait_info; bool should_sleep = false; @@ -2730,7 +2731,11 @@ void dxgi_vk_swap_chain_latency_sleep(struct dxgi_vk_swap_chain *chain) sem_wait_info.pSemaphores = &chain->present.low_latency_sem; sem_wait_info.pValues = &chain->present.low_latency_sem_value; + cookie = vkd3d_queue_timeline_trace_register_low_latency_sleep( + &chain->queue->device->queue_timeline_trace, chain->present.low_latency_sem_value); VK_CALL(vkWaitSemaphores(chain->queue->device->vk_device, &sem_wait_info, UINT64_MAX)); + vkd3d_queue_timeline_trace_complete_low_latency_sleep( + &chain->queue->device->queue_timeline_trace, cookie); } } diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index a6576afbe7..a471571704 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -4536,6 +4536,9 @@ enum vkd3d_queue_timeline_trace_state_type /* Time spent blocking in ::Present() in user thread. */ VKD3D_QUEUE_TIMELINE_TRACE_STATE_TYPE_PRESENT_BLOCK, + /* Time spent blocking in LowLatencySleep in user thread. */ + VKD3D_QUEUE_TIMELINE_TRACE_STATE_TYPE_LOW_LATENCY_SLEEP, + /* Reset() and Close() are useful instant events to see when command recording is happening and * which threads do so. */ VKD3D_QUEUE_TIMELINE_TRACE_STATE_TYPE_COMMAND_LIST, @@ -4605,6 +4608,9 @@ struct vkd3d_queue_timeline_trace_cookie vkd3d_queue_timeline_trace_register_present_block(struct vkd3d_queue_timeline_trace *trace, uint64_t present_id); struct vkd3d_queue_timeline_trace_cookie +vkd3d_queue_timeline_trace_register_low_latency_sleep(struct vkd3d_queue_timeline_trace *trace, + uint64_t present_id); +struct vkd3d_queue_timeline_trace_cookie vkd3d_queue_timeline_trace_register_execute(struct vkd3d_queue_timeline_trace *trace, ID3D12CommandList * const *command_lists, unsigned int count); struct vkd3d_queue_timeline_trace_cookie @@ -4623,6 +4629,8 @@ void vkd3d_queue_timeline_trace_complete_present_wait(struct vkd3d_queue_timelin struct vkd3d_queue_timeline_trace_cookie cookie); void vkd3d_queue_timeline_trace_complete_present_block(struct vkd3d_queue_timeline_trace *trace, struct vkd3d_queue_timeline_trace_cookie cookie); +void vkd3d_queue_timeline_trace_complete_low_latency_sleep(struct vkd3d_queue_timeline_trace *trace, + struct vkd3d_queue_timeline_trace_cookie cookie); void vkd3d_queue_timeline_trace_close_command_list(struct vkd3d_queue_timeline_trace *trace, struct vkd3d_queue_timeline_trace_cookie cookie); void vkd3d_queue_timeline_trace_begin_execute(struct vkd3d_queue_timeline_trace *trace, From 834798060c8faff100fa3cf6714aea5919dcad1f Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Fri, 23 Feb 2024 12:51:22 +0100 Subject: [PATCH 2/3] vkd3d: Report user frame ID in PRESENT (blit) command trace. Signed-off-by: Hans-Kristian Arntzen --- libs/vkd3d/swapchain.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/vkd3d/swapchain.c b/libs/vkd3d/swapchain.c index c644daeb3c..9aa1f63ffb 100644 --- a/libs/vkd3d/swapchain.c +++ b/libs/vkd3d/swapchain.c @@ -1810,7 +1810,9 @@ static void dxgi_vk_swap_chain_present_signal_blit_semaphore(struct dxgi_vk_swap /* Mark frame boundary. */ cookie = vkd3d_queue_timeline_trace_register_swapchain_blit( - &chain->queue->device->queue_timeline_trace, chain->present.complete_count); + &chain->queue->device->queue_timeline_trace, + chain->present.present_id_valid ? + chain->present.present_id : chain->present.complete_count); if (vkd3d_queue_timeline_trace_cookie_is_valid(cookie)) { From 3c9bc221a6ea3fad8b8d4ebb7a970498d92bdfda Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Fri, 23 Feb 2024 14:03:12 +0100 Subject: [PATCH 3/3] vkd3d: Use user frame marker for queue profile when available. Signed-off-by: Hans-Kristian Arntzen --- libs/vkd3d/swapchain.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libs/vkd3d/swapchain.c b/libs/vkd3d/swapchain.c index 9aa1f63ffb..f6b42707df 100644 --- a/libs/vkd3d/swapchain.c +++ b/libs/vkd3d/swapchain.c @@ -949,7 +949,10 @@ static HRESULT STDMETHODCALLTYPE dxgi_vk_swap_chain_Present(IDXGIVkSwapChain *if chain->user.index = (chain->user.index + 1) % chain->desc.BufferCount; cookie = vkd3d_queue_timeline_trace_register_present_block( - &chain->queue->device->queue_timeline_trace, chain->user.blit_count); + &chain->queue->device->queue_timeline_trace, + chain->queue->device->frame_markers.present ? + chain->queue->device->frame_markers.present : + chain->user.blit_count); /* Relevant if application does not use latency fence, or we force a lower latency through VKD3D_SWAPCHAIN_FRAME_LATENCY overrides. */ if (vkd3d_native_sync_handle_is_valid(chain->frame_latency_event_internal))