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; };