From 4863e12679f17a30a61a3f78ed6536f9c58ddaf6 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Fri, 1 Mar 2024 11:18:04 -0800 Subject: [PATCH] anv/sparse: don't use the bind_timeline when doing sparse binding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bind_timeline is used to guarantee that non-sparse objects will be bound when batches use them (although any batch will wait on the most recent bind, even if that's not necessary). For sparse binding resources, it's up to the user to guarantee synchronization: do not force every single batch buffer to wait on the latest sparse binding operation, as that adds unnecessary synchronization points. v2: Document how each of the vfuncs interacts with bind_timeline (José). Reviewed-by: José Roberto de Souza Signed-off-by: Paulo Zanoni Part-of: --- src/intel/vulkan/anv_kmd_backend.h | 16 ++++++++++-- src/intel/vulkan/xe/anv_kmd_backend.c | 35 ++++++++++++++++----------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/intel/vulkan/anv_kmd_backend.h b/src/intel/vulkan/anv_kmd_backend.h index 595a3f8fc57..eb9a5749e9d 100644 --- a/src/intel/vulkan/anv_kmd_backend.h +++ b/src/intel/vulkan/anv_kmd_backend.h @@ -73,12 +73,24 @@ struct anv_kmd_backend { /* Returns MAP_FAILED on error */ void *(*gem_mmap)(struct anv_device *device, struct anv_bo *bo, uint64_t offset, uint64_t size, void *placed_addr); - /* Bind things however you want. */ + + /* + * Bind things however you want. + * This is intended for sparse resources, so it does not use the + * bind_timeline interface: synchronization is up to the callers. + */ int (*vm_bind)(struct anv_device *device, struct anv_sparse_submission *submit); - /* Fully bind or unbind a BO. */ + + /* + * Fully bind or unbind a BO. + * This is intended for general buffer creation/destruction, so it creates + * a new point in the bind_timeline, which will be waited for the next time + * a batch is submitted. + */ int (*vm_bind_bo)(struct anv_device *device, struct anv_bo *bo); int (*vm_unbind_bo)(struct anv_device *device, struct anv_bo *bo); + VkResult (*execute_simple_batch)(struct anv_queue *queue, struct anv_bo *batch_bo, uint32_t batch_bo_size, diff --git a/src/intel/vulkan/xe/anv_kmd_backend.c b/src/intel/vulkan/xe/anv_kmd_backend.c index c556890e5cf..8e3fbb84a9f 100644 --- a/src/intel/vulkan/xe/anv_kmd_backend.c +++ b/src/intel/vulkan/xe/anv_kmd_backend.c @@ -124,9 +124,11 @@ capture_vm_in_error_dump(struct anv_device *device, struct anv_bo *bo) static inline int xe_vm_bind_op(struct anv_device *device, - struct anv_sparse_submission *submit) + struct anv_sparse_submission *submit, + bool signal_bind_timeline) { - int num_syncs = submit->wait_count + submit->signal_count + 1; + int num_syncs = submit->wait_count + submit->signal_count + + signal_bind_timeline; STACK_ARRAY(struct drm_xe_sync, xe_syncs, num_syncs); if (!xe_syncs) return -ENOMEM; @@ -160,12 +162,14 @@ xe_vm_bind_op(struct anv_device *device, .timeline_value = val, }; } - xe_syncs[sync_idx++] = (struct drm_xe_sync) { - .type = DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ, - .flags = DRM_XE_SYNC_FLAG_SIGNAL, - .handle = intel_bind_timeline_get_syncobj(&device->bind_timeline), - /* .timeline_value will be set later. */ - }; + if (signal_bind_timeline) { + xe_syncs[sync_idx++] = (struct drm_xe_sync) { + .type = DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ, + .flags = DRM_XE_SYNC_FLAG_SIGNAL, + .handle = intel_bind_timeline_get_syncobj(&device->bind_timeline), + /* .timeline_value will be set later. */ + }; + } assert(sync_idx == num_syncs); struct drm_xe_vm_bind args = { @@ -237,10 +241,13 @@ xe_vm_bind_op(struct anv_device *device, xe_bind->userptr = (uintptr_t)bo->map; } - xe_syncs[num_syncs - 1].timeline_value = - intel_bind_timeline_bind_begin(&device->bind_timeline); + if (signal_bind_timeline) { + xe_syncs[num_syncs - 1].timeline_value = + intel_bind_timeline_bind_begin(&device->bind_timeline); + } ret = intel_ioctl(device->fd, DRM_IOCTL_XE_VM_BIND, &args); - intel_bind_timeline_bind_end(&device->bind_timeline); + if (signal_bind_timeline) + intel_bind_timeline_bind_end(&device->bind_timeline); if (ret) goto out_stackarray; @@ -258,7 +265,7 @@ out_syncs: static int xe_vm_bind(struct anv_device *device, struct anv_sparse_submission *submit) { - return xe_vm_bind_op(device, submit); + return xe_vm_bind_op(device, submit, false); } static int xe_vm_bind_bo(struct anv_device *device, struct anv_bo *bo) @@ -278,7 +285,7 @@ static int xe_vm_bind_bo(struct anv_device *device, struct anv_bo *bo) .wait_count = 0, .signal_count = 0, }; - return xe_vm_bind_op(device, &submit); + return xe_vm_bind_op(device, &submit, true); } static int xe_vm_unbind_bo(struct anv_device *device, struct anv_bo *bo) @@ -298,7 +305,7 @@ static int xe_vm_unbind_bo(struct anv_device *device, struct anv_bo *bo) .wait_count = 0, .signal_count = 0, }; - return xe_vm_bind_op(device, &submit); + return xe_vm_bind_op(device, &submit, true); } static uint32_t