anv/xe: move special WaitIdle optimization to submission path

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39534>
This commit is contained in:
Lionel Landwerlin 2026-01-26 17:52:24 +02:00 committed by Marge Bot
parent 3fed41eade
commit db5319fbf0
2 changed files with 23 additions and 52 deletions

View file

@ -141,43 +141,3 @@ anv_queue_finish(struct anv_queue *queue)
anv_destroy_engine(queue);
vk_queue_finish(&queue->vk);
}
VkResult
anv_QueueWaitIdle(VkQueue _queue)
{
VK_FROM_HANDLE(anv_queue, queue, _queue);
struct anv_device *device = queue->device;
switch (device->info->kmd_type) {
case INTEL_KMD_TYPE_XE:
if (queue->vk.submit.mode != VK_QUEUE_SUBMIT_MODE_THREADED) {
int ret = anv_xe_wait_exec_queue_idle(device, queue->exec_queue_id);
VkResult result;
switch (ret) {
case 0:
result = VK_SUCCESS;
break;
case -ECANCELED:
result = VK_ERROR_DEVICE_LOST;
break;
default:
result = vk_errorf(device, VK_ERROR_UNKNOWN, "anv_xe_wait_exec_queue_idle failed: %m");
break;
}
if (INTEL_DEBUG(DEBUG_SHADER_PRINT)) {
VkResult print_result =
vk_check_printf_status(&device->vk, &device->printf);
result = result != VK_SUCCESS ? result : print_result;
}
return result;
}
FALLTHROUGH;
case INTEL_KMD_TYPE_I915:
return vk_common_QueueWaitIdle(_queue);
default:
UNREACHABLE("Missing");
}
}

View file

@ -59,6 +59,7 @@ xe_exec_process_syncs(struct anv_queue *queue,
uint32_t extra_sync_count, const struct drm_xe_sync *extra_syncs,
struct anv_utrace_submit *utrace_submit,
bool is_companion_rcs_queue,
bool skip_bind_timeline,
struct drm_xe_sync **ret, uint32_t *ret_count)
{
struct anv_device *device = queue->device;
@ -71,7 +72,7 @@ xe_exec_process_syncs(struct anv_queue *queue,
const uint32_t num_syncs = wait_count + signal_count + extra_sync_count +
(has_utrace_sync ? 1 : 0) +
((queue->sync && !is_companion_rcs_queue) ? 1 : 0) +
1 /* vm bind sync */;
(!skip_bind_timeline ? 1 : 0) /* vm bind sync */;
struct drm_xe_sync *xe_syncs = vk_zalloc(&device->vk.alloc,
sizeof(*xe_syncs) * num_syncs, 8,
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
@ -104,15 +105,17 @@ xe_exec_process_syncs(struct anv_queue *queue,
if (queue->sync && !is_companion_rcs_queue)
xe_syncs[count++] = vk_sync_to_drm_xe_sync(queue->sync, 0, TYPE_SIGNAL);
/* vm bind sync */
xe_syncs[count] = (struct drm_xe_sync) {
.type = DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ,
.flags = 0 /* TYPE_WAIT */,
.addr = 0, /* init union to 0 before setting .handle */
.timeline_value = intel_bind_timeline_get_last_point(&device->bind_timeline),
};
xe_syncs[count++].handle =
intel_bind_timeline_get_syncobj(&device->bind_timeline);
if (!skip_bind_timeline) {
/* vm bind sync */
xe_syncs[count] = (struct drm_xe_sync) {
.type = DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ,
.flags = 0 /* TYPE_WAIT */,
.addr = 0, /* init union to 0 before setting .handle */
.timeline_value = intel_bind_timeline_get_last_point(&device->bind_timeline),
};
xe_syncs[count++].handle =
intel_bind_timeline_get_syncobj(&device->bind_timeline);
}
assert(count == num_syncs);
*ret = xe_syncs;
@ -240,6 +243,7 @@ xe_companion_rcs_queue_exec_locked(struct anv_queue *queue,
0, NULL, /* extra_syncs */
NULL /* utrace_submit */,
true /* is_companion_rcs_queue */,
false /* skip_bind_timeline */,
&xe_syncs,
&xe_syncs_count);
if (result != VK_SUCCESS)
@ -282,6 +286,10 @@ xe_queue_exec_locked(struct anv_queue *queue,
struct anv_device *device = queue->device;
VkResult result;
const bool can_skip_bind_timeline = cmd_buffer_count == 0;
const bool is_queue_wait_idle = can_skip_bind_timeline &&
wait_count == 0 && signal_count == 1;
struct drm_xe_sync *xe_syncs = NULL;
uint32_t xe_syncs_count = 0;
result = xe_exec_process_syncs(queue, wait_count, waits,
@ -289,6 +297,7 @@ xe_queue_exec_locked(struct anv_queue *queue,
0, NULL, /* extra_syncs */
utrace_submit,
false, /* is_companion_rcs_queue */
can_skip_bind_timeline,
&xe_syncs, &xe_syncs_count);
if (result != VK_SUCCESS)
return result;
@ -303,12 +312,13 @@ xe_queue_exec_locked(struct anv_queue *queue,
struct drm_xe_exec exec = {
.exec_queue_id = queue->exec_queue_id,
.num_batch_buffer = 1,
.syncs = (uintptr_t)xe_syncs,
.num_syncs = xe_syncs_count,
};
if (cmd_buffer_count) {
exec.num_batch_buffer = 1;
if (unlikely(device->physical->measure_device.config)) {
for (uint32_t i = 0; i < cmd_buffer_count; i++)
anv_measure_submit(cmd_buffers[i]);
@ -326,7 +336,8 @@ xe_queue_exec_locked(struct anv_queue *queue,
struct anv_batch_bo *first_batch_bo = list_first_entry(&first_cmd_buffer->batch_bos,
struct anv_batch_bo, link);
exec.address = first_batch_bo->bo->offset;
} else {
} else if (!is_queue_wait_idle) {
exec.num_batch_buffer = 1;
exec.address = device->trivial_batch_bo->offset;
}