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:
Iago Toral Quiroga
2022-10-19 09:48:19 +02:00
parent 8cd50ef071
commit ecb01d53fd
4 changed files with 578 additions and 149 deletions
-58
View File
@@ -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: