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

Author: Faith Ekstrand <[email protected]>
Date:   Thu Nov 16 17:20:10 2023 -0600

nvk: Add a separate VMA heap for BDA capture/replay

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26242>

---

 src/nouveau/vulkan/nvk_buffer.c     |  6 +++---
 src/nouveau/vulkan/nvk_image.c      |  6 +++---
 src/nouveau/winsys/nouveau_bo.c     | 27 +++++++++++++++++++++------
 src/nouveau/winsys/nouveau_bo.h     |  6 ++++--
 src/nouveau/winsys/nouveau_device.c |  8 +++++---
 src/nouveau/winsys/nouveau_device.h |  1 +
 6 files changed, 37 insertions(+), 17 deletions(-)

diff --git a/src/nouveau/vulkan/nvk_buffer.c b/src/nouveau/vulkan/nvk_buffer.c
index 73ce178db0a..487f771fb34 100644
--- a/src/nouveau/vulkan/nvk_buffer.c
+++ b/src/nouveau/vulkan/nvk_buffer.c
@@ -61,8 +61,8 @@ nvk_CreateBuffer(VkDevice device,
       const bool sparse_residency =
          buffer->vk.create_flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT;
 
-      buffer->addr = nouveau_ws_alloc_vma(dev->ws_dev, buffer->vma_size_B,
-                                          alignment, sparse_residency);
+      buffer->addr = nouveau_ws_alloc_vma(dev->ws_dev, 0, buffer->vma_size_B,
+                                          alignment, false, sparse_residency);
       if (buffer->addr == 0) {
          vk_buffer_destroy(&dev->vk, pAllocator, &buffer->vk);
          return vk_errorf(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY,
@@ -92,7 +92,7 @@ nvk_DestroyBuffer(VkDevice device,
 
       nouveau_ws_bo_unbind_vma(dev->ws_dev, buffer->addr, buffer->vma_size_B);
       nouveau_ws_free_vma(dev->ws_dev, buffer->addr, buffer->vma_size_B,
-                          sparse_residency);
+                          false, sparse_residency);
    }
 
    vk_buffer_destroy(&dev->vk, pAllocator, &buffer->vk);
diff --git a/src/nouveau/vulkan/nvk_image.c b/src/nouveau/vulkan/nvk_image.c
index 9809de14aaa..de1c529cc4f 100644
--- a/src/nouveau/vulkan/nvk_image.c
+++ b/src/nouveau/vulkan/nvk_image.c
@@ -539,9 +539,9 @@ nvk_image_plane_alloc_vma(struct nvk_device *dev,
 
    if (sparse_bound || plane->nil.pte_kind) {
       plane->vma_size_B = plane->nil.size_B;
-      plane->addr = nouveau_ws_alloc_vma(dev->ws_dev, plane->vma_size_B,
+      plane->addr = nouveau_ws_alloc_vma(dev->ws_dev, 0, plane->vma_size_B,
                                          plane->nil.align_B,
-                                         sparse_resident);
+                                         false, sparse_resident);
       if (plane->addr == 0) {
          return vk_errorf(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY,
                           "Sparse VMA allocation failed");
@@ -564,7 +564,7 @@ nvk_image_plane_finish(struct nvk_device *dev,
 
       nouveau_ws_bo_unbind_vma(dev->ws_dev, plane->addr, plane->vma_size_B);
       nouveau_ws_free_vma(dev->ws_dev, plane->addr, plane->vma_size_B,
-                          sparse_resident);
+                          false, sparse_resident);
    }
 }
 
diff --git a/src/nouveau/winsys/nouveau_bo.c b/src/nouveau/winsys/nouveau_bo.c
index 5e3e43b044a..5df3e773d76 100644
--- a/src/nouveau/winsys/nouveau_bo.c
+++ b/src/nouveau/winsys/nouveau_bo.c
@@ -57,14 +57,24 @@ bo_unbind(struct nouveau_ws_device *dev,
 
 uint64_t
 nouveau_ws_alloc_vma(struct nouveau_ws_device *dev,
-                     uint64_t size, uint64_t align,
+                     uint64_t req_addr, uint64_t size, uint64_t align,
+                     bool bda_capture_replay,
                      bool sparse_resident)
 {
    assert(dev->has_vm_bind);
 
    uint64_t offset;
    simple_mtx_lock(&dev->vma_mutex);
-   offset = util_vma_heap_alloc(&dev->vma_heap, size, align);
+   if (bda_capture_replay) {
+      if (req_addr != 0) {
+         bool found = util_vma_heap_alloc_addr(&dev->bda_heap, req_addr, size);
+         offset = found ? req_addr : 0;
+      } else {
+         offset = util_vma_heap_alloc(&dev->bda_heap, size, align);
+      }
+   } else {
+      offset = util_vma_heap_alloc(&dev->vma_heap, size, align);
+   }
    simple_mtx_unlock(&dev->vma_mutex);
 
    if (offset == 0) {
@@ -88,6 +98,7 @@ nouveau_ws_alloc_vma(struct nouveau_ws_device *dev,
 void
 nouveau_ws_free_vma(struct nouveau_ws_device *dev,
                     uint64_t offset, uint64_t size,
+                    bool bda_capture_replay,
                     bool sparse_resident)
 {
    assert(dev->has_vm_bind);
@@ -100,7 +111,11 @@ nouveau_ws_free_vma(struct nouveau_ws_device *dev,
       bo_unbind(dev, offset, size, DRM_NOUVEAU_VM_BIND_SPARSE);
 
    simple_mtx_lock(&dev->vma_mutex);
-   util_vma_heap_free(&dev->vma_heap, offset, size);
+   if (bda_capture_replay) {
+      util_vma_heap_free(&dev->bda_heap, offset, size);
+   } else {
+      util_vma_heap_free(&dev->vma_heap, offset, size);
+   }
    simple_mtx_unlock(&dev->vma_mutex);
 }
 
@@ -208,7 +223,7 @@ nouveau_ws_bo_new_locked(struct nouveau_ws_device *dev,
    bo->refcnt = 1;
 
    if (dev->has_vm_bind) {
-      bo->offset = nouveau_ws_alloc_vma(dev, bo->size, align, false);
+      bo->offset = nouveau_ws_alloc_vma(dev, 0, bo->size, align, false, false);
       if (bo->offset == 0)
          goto fail_gem_new;
 
@@ -287,7 +302,7 @@ nouveau_ws_bo_from_dma_buf_locked(struct nouveau_ws_device 
*dev, int fd)
 
    assert(bo->size == ALIGN(bo->size, align));
 
-   bo->offset = nouveau_ws_alloc_vma(dev, bo->size, align, false);
+   bo->offset = nouveau_ws_alloc_vma(dev, 0, bo->size, align, false, false);
    if (bo->offset == 0)
       goto fail_calloc;
 
@@ -330,7 +345,7 @@ nouveau_ws_bo_destroy(struct nouveau_ws_bo *bo)
 
    if (dev->has_vm_bind) {
       nouveau_ws_bo_unbind_vma(bo->dev, bo->offset, bo->size);
-      nouveau_ws_free_vma(bo->dev, bo->offset, bo->size, false);
+      nouveau_ws_free_vma(bo->dev, bo->offset, bo->size, false, false);
    }
 
    drmCloseBufferHandle(bo->dev->fd, bo->handle);
diff --git a/src/nouveau/winsys/nouveau_bo.h b/src/nouveau/winsys/nouveau_bo.h
index 127479fdeec..d931bea44f9 100644
--- a/src/nouveau/winsys/nouveau_bo.h
+++ b/src/nouveau/winsys/nouveau_bo.h
@@ -44,10 +44,12 @@ struct nouveau_ws_bo {
 };
 
 uint64_t nouveau_ws_alloc_vma(struct nouveau_ws_device *dev,
-                              uint64_t size, uint64_t align, bool sparse);
+                              uint64_t addr, uint64_t size, uint64_t align,
+                              bool bda, bool sparse);
 
 void nouveau_ws_free_vma(struct nouveau_ws_device *dev,
-                         uint64_t offset, uint64_t size, bool sparse);
+                         uint64_t offset, uint64_t size,
+                         bool bda, bool sparse);
 
 void nouveau_ws_bo_bind_vma(struct nouveau_ws_device *dev,
                             struct nouveau_ws_bo *bo,
diff --git a/src/nouveau/winsys/nouveau_device.c 
b/src/nouveau/winsys/nouveau_device.c
index 81614be2efa..9e869f43ae6 100644
--- a/src/nouveau/winsys/nouveau_device.c
+++ b/src/nouveau/winsys/nouveau_device.c
@@ -269,13 +269,15 @@ nouveau_ws_device_new(drmDevicePtr drm_device)
    if (version < 0x01000301)
       goto out_err;
 
-   const uint64_t TOP = 1ull << 40;
+   const uint64_t BDA = 1ull << 38;
    const uint64_t KERN = 1ull << 39;
-   struct drm_nouveau_vm_init vminit = { TOP-KERN, KERN };
+   const uint64_t TOP = 1ull << 40;
+   struct drm_nouveau_vm_init vminit = { KERN, TOP-KERN };
    int ret = drmCommandWrite(fd, DRM_NOUVEAU_VM_INIT, &vminit, sizeof(vminit));
    if (ret == 0) {
       device->has_vm_bind = true;
-      util_vma_heap_init(&device->vma_heap, 4096, (TOP - KERN) - 4096);
+      util_vma_heap_init(&device->vma_heap, 4096, BDA - 4096);
+      util_vma_heap_init(&device->bda_heap, BDA, KERN - BDA);
       simple_mtx_init(&device->vma_mutex, mtx_plain);
    }
 
diff --git a/src/nouveau/winsys/nouveau_device.h 
b/src/nouveau/winsys/nouveau_device.h
index ff8eb54b0aa..3174aa2630d 100644
--- a/src/nouveau/winsys/nouveau_device.h
+++ b/src/nouveau/winsys/nouveau_device.h
@@ -51,6 +51,7 @@ struct nouveau_ws_device {
 
    bool has_vm_bind;
    struct util_vma_heap vma_heap;
+   struct util_vma_heap bda_heap;
    simple_mtx_t vma_mutex;
 };
 

Reply via email to