Skip to content

Commit

Permalink
vkd3d: Add generic execution regions to timeline.
Browse files Browse the repository at this point in the history
Makes it easier to tell what the submission threads are doing.

Signed-off-by: Hans-Kristian Arntzen <[email protected]>
  • Loading branch information
HansKristian-Work committed Jan 3, 2025
1 parent baa6c7f commit ceb53e9
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 6 deletions.
16 changes: 16 additions & 0 deletions libs/vkd3d/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -18223,6 +18223,7 @@ static void d3d12_command_queue_wait(struct d3d12_command_queue *command_queue,
struct d3d12_fence *fence, UINT64 value)
{
const struct vkd3d_vk_device_procs *vk_procs = &command_queue->device->vk_procs;
struct vkd3d_queue_timeline_trace_cookie cookie;
struct d3d12_fence_value fence_value;
VkSemaphoreWaitInfo wait_info;
struct vkd3d_queue *queue;
Expand All @@ -18240,7 +18241,9 @@ static void d3d12_command_queue_wait(struct d3d12_command_queue *command_queue,
* but we don't have virtualized queues in Vulkan, so we need to handle the case
* where multiple queues alias over the same physical queue, so effectively, we need to manage out-of-order submits
* ourselves. */
cookie = vkd3d_queue_timeline_trace_register_generic_region(&fence->device->queue_timeline_trace, "WAIT BEFORE SIGNAL");
d3d12_fence_block_until_pending_value_reaches_locked(fence, value);
vkd3d_queue_timeline_trace_complete_execute(&fence->device->queue_timeline_trace, &command_queue->fence_worker, cookie);

/* If a host signal unblocked us, or we know that the fence has reached a specific value, there is no need
* to queue up a wait. */
Expand Down Expand Up @@ -18272,8 +18275,10 @@ static void d3d12_command_queue_wait(struct d3d12_command_queue *command_queue,
wait_info.pSemaphores = &fence_value.vk_semaphore;
wait_info.pValues = &fence_value.vk_semaphore_value;

cookie = vkd3d_queue_timeline_trace_register_generic_region(&fence->device->queue_timeline_trace, "CPU WAIT");
if ((vr = VK_CALL(vkWaitSemaphores(command_queue->device->vk_device, &wait_info, UINT64_MAX))))
ERR("Failed to wait for timeline semaphore, vr %d.\n", vr);
vkd3d_queue_timeline_trace_complete_execute(&fence->device->queue_timeline_trace, &command_queue->fence_worker, cookie);
}
else
{
Expand Down Expand Up @@ -19397,6 +19402,7 @@ static void *d3d12_command_queue_submission_worker_main(void *userdata)
{
struct d3d12_command_queue_submission submission;
struct d3d12_command_queue_transition_pool pool;
struct vkd3d_queue_timeline_trace_cookie cookie;
struct d3d12_command_queue *queue = userdata;
VkSemaphoreSubmitInfo transition_semaphore;
VkCommandBufferSubmitInfo transition_cmd;
Expand Down Expand Up @@ -19427,17 +19433,20 @@ static void *d3d12_command_queue_submission_worker_main(void *userdata)
switch (submission.type)
{
case VKD3D_SUBMISSION_STOP:
cookie = vkd3d_queue_timeline_trace_register_generic_region(&queue->device->queue_timeline_trace, "STOP");
goto cleanup;

case VKD3D_SUBMISSION_WAIT:
VKD3D_REGION_BEGIN(queue_wait);
if (is_shared_ID3D12Fence1(submission.wait.fence))
{
cookie = vkd3d_queue_timeline_trace_register_generic_region(&queue->device->queue_timeline_trace, "WAIT (shared)");
d3d12_command_queue_flush_waiters(queue, 0u);
d3d12_command_queue_wait_shared(queue, shared_impl_from_ID3D12Fence1(submission.wait.fence), submission.wait.value);
}
else
{
cookie = vkd3d_queue_timeline_trace_register_generic_region(&queue->device->queue_timeline_trace, "WAIT (normal)");
d3d12_command_queue_wait(queue, impl_from_ID3D12Fence1(submission.wait.fence), submission.wait.value);
}

Expand All @@ -19446,6 +19455,7 @@ static void *d3d12_command_queue_submission_worker_main(void *userdata)
break;

case VKD3D_SUBMISSION_SIGNAL:
cookie = vkd3d_queue_timeline_trace_register_generic_region(&queue->device->queue_timeline_trace, "SIGNAL");
d3d12_command_queue_flush_waiters(queue, 0u);

VKD3D_REGION_BEGIN(queue_signal);
Expand All @@ -19456,6 +19466,7 @@ static void *d3d12_command_queue_submission_worker_main(void *userdata)

case VKD3D_SUBMISSION_EXECUTE:
VKD3D_REGION_BEGIN(queue_execute);
cookie = vkd3d_queue_timeline_trace_register_generic_region(&queue->device->queue_timeline_trace, "EXECUTE");

memset(&transition_cmd, 0, sizeof(transition_cmd));
transition_cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO;
Expand Down Expand Up @@ -19505,6 +19516,7 @@ static void *d3d12_command_queue_submission_worker_main(void *userdata)
break;

case VKD3D_SUBMISSION_BIND_SPARSE:
cookie = vkd3d_queue_timeline_trace_register_generic_region(&queue->device->queue_timeline_trace, "SPARSE");
d3d12_command_queue_flush_waiters(queue, VKD3D_WAIT_SEMAPHORES_EXTERNAL);

d3d12_command_queue_bind_sparse(queue, submission.bind_sparse.mode,
Expand All @@ -19514,6 +19526,7 @@ static void *d3d12_command_queue_submission_worker_main(void *userdata)
break;

case VKD3D_SUBMISSION_DRAIN:
cookie = vkd3d_queue_timeline_trace_register_generic_region(&queue->device->queue_timeline_trace, "DRAIN");
/* Full flush needed to synchronize interop */
d3d12_command_queue_flush_waiters(queue, VKD3D_WAIT_SEMAPHORES_EXTERNAL | VKD3D_WAIT_SEMAPHORES_SERIALIZING);

Expand All @@ -19524,6 +19537,7 @@ static void *d3d12_command_queue_submission_worker_main(void *userdata)
break;

case VKD3D_SUBMISSION_CALLBACK:
cookie = vkd3d_queue_timeline_trace_register_generic_region(&queue->device->queue_timeline_trace, "CALLBACK");
d3d12_command_queue_flush_waiters(queue, VKD3D_WAIT_SEMAPHORES_EXTERNAL | VKD3D_WAIT_SEMAPHORES_SERIALIZING);

submission.callback.callback(submission.callback.userdata);
Expand All @@ -19533,6 +19547,8 @@ static void *d3d12_command_queue_submission_worker_main(void *userdata)
ERR("Unrecognized submission type %u.\n", submission.type);
break;
}

vkd3d_queue_timeline_trace_complete_execute(&queue->device->queue_timeline_trace, &queue->fence_worker, cookie);
}

cleanup:
Expand Down
25 changes: 19 additions & 6 deletions libs/vkd3d/queue_timeline.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,13 @@ vkd3d_queue_timeline_trace_register_present_wait(struct vkd3d_queue_timeline_tra
return vkd3d_queue_timeline_trace_register_generic_op(trace, VKD3D_QUEUE_TIMELINE_TRACE_STATE_TYPE_PRESENT_WAIT, str);
}

struct vkd3d_queue_timeline_trace_cookie
vkd3d_queue_timeline_trace_register_generic_region(struct vkd3d_queue_timeline_trace *trace, const char *tag)
{
return vkd3d_queue_timeline_trace_register_generic_op(trace, VKD3D_QUEUE_TIMELINE_TRACE_STATE_TYPE_GENERIC_REGION, tag);
}


struct vkd3d_queue_timeline_trace_cookie
vkd3d_queue_timeline_trace_register_present_block(struct vkd3d_queue_timeline_trace *trace, uint64_t present_id)
{
Expand Down Expand Up @@ -565,6 +572,9 @@ void vkd3d_queue_timeline_trace_complete_execute(struct vkd3d_queue_timeline_tra
vkd3d_queue_timeline_trace_flush_instantaneous(trace, worker);

tid = worker->timeline.tid;
if (state->type == VKD3D_QUEUE_TIMELINE_TRACE_STATE_TYPE_GENERIC_REGION)
tid = "regions";

pid = worker->queue->submission_thread_tid;

if (state->type == VKD3D_QUEUE_TIMELINE_TRACE_STATE_TYPE_SUBMISSION)
Expand All @@ -578,13 +588,16 @@ void vkd3d_queue_timeline_trace_complete_execute(struct vkd3d_queue_timeline_tra
start_submit_ts = start_ts;
}

ts_lock = &worker->timeline.lock_end_gpu_ts;
if (state->type != VKD3D_QUEUE_TIMELINE_TRACE_STATE_TYPE_GENERIC_REGION)
{
ts_lock = &worker->timeline.lock_end_gpu_ts;

if (start_submit_ts < *ts_lock)
start_submit_ts = *ts_lock;
if (end_ts < start_submit_ts)
end_ts = start_submit_ts;
*ts_lock = end_ts;
if (start_submit_ts < *ts_lock)
start_submit_ts = *ts_lock;
if (end_ts < start_submit_ts)
end_ts = start_submit_ts;
*ts_lock = end_ts;
}

fprintf(trace->file, "{ \"name\": \"%s\", \"ph\": \"X\", \"tid\": \"%s\", \"pid\": \"0x%04x\", \"ts\": %f, \"dur\": %f },\n",
state->desc, tid, pid, start_submit_ts, end_ts - start_submit_ts);
Expand Down
6 changes: 6 additions & 0 deletions libs/vkd3d/vkd3d_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -4705,6 +4705,9 @@ enum vkd3d_queue_timeline_trace_state_type
/* Waiting for present wait to complete. */
VKD3D_QUEUE_TIMELINE_TRACE_STATE_TYPE_PRESENT_WAIT,

/* Generic region markers. */
VKD3D_QUEUE_TIMELINE_TRACE_STATE_TYPE_GENERIC_REGION,

/* Time spent blocking in ::Present() in user thread. */
VKD3D_QUEUE_TIMELINE_TRACE_STATE_TYPE_PRESENT_BLOCK,

Expand Down Expand Up @@ -4797,6 +4800,9 @@ vkd3d_queue_timeline_trace_register_command_list(struct vkd3d_queue_timeline_tra
void vkd3d_queue_timeline_trace_register_instantaneous(struct vkd3d_queue_timeline_trace *trace,
enum vkd3d_queue_timeline_trace_state_type type, uint64_t value);

struct vkd3d_queue_timeline_trace_cookie
vkd3d_queue_timeline_trace_register_generic_region(struct vkd3d_queue_timeline_trace *trace, const char *tag);

void vkd3d_queue_timeline_trace_complete_event_signal(struct vkd3d_queue_timeline_trace *trace,
struct vkd3d_fence_worker *worker,
struct vkd3d_queue_timeline_trace_cookie cookie);
Expand Down

0 comments on commit ceb53e9

Please sign in to comment.