Module: Mesa
Branch: main
Commit: 0a120edfb8d4072aa479631602c69b6919886831
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=0a120edfb8d4072aa479631602c69b6919886831

Author: Paulo Zanoni <[email protected]>
Date:   Thu Sep 28 16:21:58 2023 -0700

anv/sparse: extract anv_sparse_bind()

This function will be able to transparently handle sparse binding
regardless of the backend: vm_bind ioctls or TR-TT. For now we only
support the vm_bind ioctls, but soon we'll have anv_sparse_bind_trtt()
as an option.

It is important to notice that even backends that support the vm_bind
ioctl may choose to do Sparse binding via TR-TT, that's why we're
adding the indirection at this specific point.

Reviewed-by: Lionel Landwerlin <[email protected]>
Signed-off-by: Paulo Zanoni <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26036>

---

 src/intel/vulkan/anv_sparse.c | 73 +++++++++++++++++++++++--------------------
 1 file changed, 39 insertions(+), 34 deletions(-)

diff --git a/src/intel/vulkan/anv_sparse.c b/src/intel/vulkan/anv_sparse.c
index 9b2471332d9..8e8024db1ab 100644
--- a/src/intel/vulkan/anv_sparse.c
+++ b/src/intel/vulkan/anv_sparse.c
@@ -276,6 +276,36 @@ anv_sparse_get_standard_image_block_shape(enum isl_format 
format,
    return vk_extent3d_el_to_px(block_shape, layout);
 }
 
+static VkResult
+anv_sparse_bind_vm_bind(struct anv_device *device, int num_binds,
+                        struct anv_vm_bind *binds)
+{
+   /* FIXME: here we were supposed to issue a single vm_bind ioctl by calling
+    * vm_bind(device, num_binds, binds), but for an unknown reason some
+    * shader-related tests fail when we do that, so work around it for now.
+    * See: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/746
+    */
+   for (int b = 0; b < num_binds; b++) {
+      int rc = device->kmd_backend->vm_bind(device, 1, &binds[b]);
+      if (rc)
+         return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+   }
+   return VK_SUCCESS;
+}
+
+static VkResult
+anv_sparse_bind(struct anv_device *device,
+                struct anv_sparse_binding_data *sparse,
+                int num_binds, struct anv_vm_bind *binds)
+{
+   if (INTEL_DEBUG(DEBUG_SPARSE)) {
+      for (int b = 0; b < num_binds; b++)
+         dump_anv_vm_bind(device, sparse, &binds[b]);
+   }
+
+   return anv_sparse_bind_vm_bind(device, num_binds, binds);
+}
+
 VkResult
 anv_init_sparse_bindings(struct anv_device *device,
                          uint64_t size_,
@@ -302,12 +332,11 @@ anv_init_sparse_bindings(struct anv_device *device,
       .size = size,
       .op = ANV_VM_BIND,
    };
-   dump_anv_vm_bind(device, sparse, &bind);
-   int rc = device->kmd_backend->vm_bind(device, 1, &bind);
-   if (rc) {
+
+   VkResult res = anv_sparse_bind(device, sparse, 1, &bind);
+   if (res != VK_SUCCESS) {
       anv_vma_free(device, sparse->vma_heap, sparse->address, sparse->size);
-      return vk_errorf(device, VK_ERROR_OUT_OF_DEVICE_MEMORY,
-                       "failed to bind sparse buffer");
+      return res;
    }
 
    return VK_SUCCESS;
@@ -330,11 +359,9 @@ anv_free_sparse_bindings(struct anv_device *device,
       .size = sparse->size,
       .op = ANV_VM_UNBIND,
    };
-   dump_anv_vm_bind(device, sparse, &unbind);
-   int ret = device->kmd_backend->vm_bind(device, 1, &unbind);
-   if (ret)
-      return vk_errorf(device, VK_ERROR_UNKNOWN,
-                       "failed to unbind vm for sparse resource\n");
+   VkResult res = anv_sparse_bind(device, sparse, 1, &unbind);
+   if (res != VK_SUCCESS)
+      return res;
 
    anv_vma_free(device, sparse->vma_heap, sparse->address, sparse->size);
 
@@ -577,14 +604,7 @@ anv_sparse_bind_resource_memory(struct anv_device *device,
 {
    struct anv_vm_bind bind = vk_bind_to_anv_vm_bind(sparse, vk_bind);
 
-   dump_anv_vm_bind(device, sparse, &bind);
-   int rc = device->kmd_backend->vm_bind(device, 1, &bind);
-   if (rc) {
-      return vk_errorf(device, VK_ERROR_OUT_OF_DEVICE_MEMORY,
-                       "failed to bind sparse buffer");
-   }
-
-   return VK_SUCCESS;
+   return anv_sparse_bind(device, sparse, 1, &bind);
 }
 
 VkResult
@@ -726,22 +746,7 @@ anv_sparse_bind_image_memory(struct anv_queue *queue,
       }
    }
 
-   if (INTEL_DEBUG(DEBUG_SPARSE)) {
-      for (int b = 0; b < num_binds; b++)
-         dump_anv_vm_bind(device, sparse_data, &binds[b]);
-   }
-
-   /* FIXME: here we were supposed to issue a single vm_bind ioctl by calling
-    * vm_bind(device, num_binds, binds), but for an unknown reason some
-    * shader-related tests fail when we do that, so work around it for now.
-    */
-   for (int b = 0; b < num_binds; b++) {
-      int rc = device->kmd_backend->vm_bind(device, 1, &binds[b]);
-      if (rc) {
-         ret = vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
-         break;
-      }
-   }
+   ret = anv_sparse_bind(device, sparse_data, num_binds, binds);
 
    STACK_ARRAY_FINISH(binds);
 

Reply via email to