v3dv: refactor events
This replaces our current implementation, which is 100% CPU based, with an implementation that uses compute shaders for the GPU-side event functions. The benefit of this solution is that we no longer need to stall on the CPU when we need to handle GPU-side event commands. Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19313>
This commit is contained in:
@@ -289,60 +289,6 @@ handle_copy_query_results_cpu_job(struct v3dv_job *job)
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
handle_set_event_cpu_job(struct v3dv_queue *queue, struct v3dv_job *job,
|
||||
struct v3dv_submit_sync_info *sync_info)
|
||||
{
|
||||
/* From the Vulkan 1.0 spec:
|
||||
*
|
||||
* "When vkCmdSetEvent is submitted to a queue, it defines an execution
|
||||
* dependency on commands that were submitted before it, and defines an
|
||||
* event signal operation which sets the event to the signaled state.
|
||||
* The first synchronization scope includes every command previously
|
||||
* submitted to the same queue, including those in the same command
|
||||
* buffer and batch".
|
||||
*
|
||||
* So we should wait for all prior work to be completed before signaling
|
||||
* the event, this includes all active CPU wait threads spawned for any
|
||||
* command buffer submitted *before* this.
|
||||
*/
|
||||
|
||||
VkResult result = queue_wait_idle(queue, sync_info);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
struct v3dv_event_set_cpu_job_info *info = &job->cpu.event_set;
|
||||
p_atomic_set(&info->event->state, info->state);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_wait_events_complete(struct v3dv_job *job)
|
||||
{
|
||||
assert(job->type == V3DV_JOB_TYPE_CPU_WAIT_EVENTS);
|
||||
|
||||
struct v3dv_event_wait_cpu_job_info *info = &job->cpu.event_wait;
|
||||
for (uint32_t i = 0; i < info->event_count; i++) {
|
||||
if (!p_atomic_read(&info->events[i]->state))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
handle_wait_events_cpu_job(struct v3dv_job *job)
|
||||
{
|
||||
assert(job->type == V3DV_JOB_TYPE_CPU_WAIT_EVENTS);
|
||||
|
||||
/* Wait for events to be signaled */
|
||||
const useconds_t wait_interval_ms = 1;
|
||||
while (!check_wait_events_complete(job))
|
||||
usleep(wait_interval_ms * 1000);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
handle_copy_buffer_to_image_cpu_job(struct v3dv_queue *queue,
|
||||
struct v3dv_job *job,
|
||||
@@ -1014,10 +960,6 @@ queue_handle_job(struct v3dv_queue *queue,
|
||||
return handle_end_query_cpu_job(job, counter_pass_idx);
|
||||
case V3DV_JOB_TYPE_CPU_COPY_QUERY_RESULTS:
|
||||
return handle_copy_query_results_cpu_job(job);
|
||||
case V3DV_JOB_TYPE_CPU_SET_EVENT:
|
||||
return handle_set_event_cpu_job(queue, job, sync_info);
|
||||
case V3DV_JOB_TYPE_CPU_WAIT_EVENTS:
|
||||
return handle_wait_events_cpu_job(job);
|
||||
case V3DV_JOB_TYPE_CPU_COPY_BUFFER_TO_IMAGE:
|
||||
return handle_copy_buffer_to_image_cpu_job(queue, job, sync_info);
|
||||
case V3DV_JOB_TYPE_CPU_CSD_INDIRECT:
|
||||
|
||||
Reference in New Issue
Block a user