nvk: Add a separate VMA heap for BDA capture/replay
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26242>
This commit is contained in:
parent
78eee47471
commit
b4cfac64c8
6 changed files with 37 additions and 17 deletions
|
|
@ -61,8 +61,8 @@ nvk_CreateBuffer(VkDevice device,
|
||||||
const bool sparse_residency =
|
const bool sparse_residency =
|
||||||
buffer->vk.create_flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT;
|
buffer->vk.create_flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT;
|
||||||
|
|
||||||
buffer->addr = nouveau_ws_alloc_vma(dev->ws_dev, buffer->vma_size_B,
|
buffer->addr = nouveau_ws_alloc_vma(dev->ws_dev, 0, buffer->vma_size_B,
|
||||||
alignment, sparse_residency);
|
alignment, false, sparse_residency);
|
||||||
if (buffer->addr == 0) {
|
if (buffer->addr == 0) {
|
||||||
vk_buffer_destroy(&dev->vk, pAllocator, &buffer->vk);
|
vk_buffer_destroy(&dev->vk, pAllocator, &buffer->vk);
|
||||||
return vk_errorf(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY,
|
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_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,
|
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);
|
vk_buffer_destroy(&dev->vk, pAllocator, &buffer->vk);
|
||||||
|
|
|
||||||
|
|
@ -539,9 +539,9 @@ nvk_image_plane_alloc_vma(struct nvk_device *dev,
|
||||||
|
|
||||||
if (sparse_bound || plane->nil.pte_kind) {
|
if (sparse_bound || plane->nil.pte_kind) {
|
||||||
plane->vma_size_B = plane->nil.size_B;
|
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,
|
plane->nil.align_B,
|
||||||
sparse_resident);
|
false, sparse_resident);
|
||||||
if (plane->addr == 0) {
|
if (plane->addr == 0) {
|
||||||
return vk_errorf(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY,
|
return vk_errorf(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY,
|
||||||
"Sparse VMA allocation failed");
|
"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_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,
|
nouveau_ws_free_vma(dev->ws_dev, plane->addr, plane->vma_size_B,
|
||||||
sparse_resident);
|
false, sparse_resident);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,14 +57,24 @@ bo_unbind(struct nouveau_ws_device *dev,
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
nouveau_ws_alloc_vma(struct nouveau_ws_device *dev,
|
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)
|
bool sparse_resident)
|
||||||
{
|
{
|
||||||
assert(dev->has_vm_bind);
|
assert(dev->has_vm_bind);
|
||||||
|
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
simple_mtx_lock(&dev->vma_mutex);
|
simple_mtx_lock(&dev->vma_mutex);
|
||||||
|
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);
|
offset = util_vma_heap_alloc(&dev->vma_heap, size, align);
|
||||||
|
}
|
||||||
simple_mtx_unlock(&dev->vma_mutex);
|
simple_mtx_unlock(&dev->vma_mutex);
|
||||||
|
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
|
|
@ -88,6 +98,7 @@ nouveau_ws_alloc_vma(struct nouveau_ws_device *dev,
|
||||||
void
|
void
|
||||||
nouveau_ws_free_vma(struct nouveau_ws_device *dev,
|
nouveau_ws_free_vma(struct nouveau_ws_device *dev,
|
||||||
uint64_t offset, uint64_t size,
|
uint64_t offset, uint64_t size,
|
||||||
|
bool bda_capture_replay,
|
||||||
bool sparse_resident)
|
bool sparse_resident)
|
||||||
{
|
{
|
||||||
assert(dev->has_vm_bind);
|
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);
|
bo_unbind(dev, offset, size, DRM_NOUVEAU_VM_BIND_SPARSE);
|
||||||
|
|
||||||
simple_mtx_lock(&dev->vma_mutex);
|
simple_mtx_lock(&dev->vma_mutex);
|
||||||
|
if (bda_capture_replay) {
|
||||||
|
util_vma_heap_free(&dev->bda_heap, offset, size);
|
||||||
|
} else {
|
||||||
util_vma_heap_free(&dev->vma_heap, offset, size);
|
util_vma_heap_free(&dev->vma_heap, offset, size);
|
||||||
|
}
|
||||||
simple_mtx_unlock(&dev->vma_mutex);
|
simple_mtx_unlock(&dev->vma_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,7 +223,7 @@ nouveau_ws_bo_new_locked(struct nouveau_ws_device *dev,
|
||||||
bo->refcnt = 1;
|
bo->refcnt = 1;
|
||||||
|
|
||||||
if (dev->has_vm_bind) {
|
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)
|
if (bo->offset == 0)
|
||||||
goto fail_gem_new;
|
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));
|
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)
|
if (bo->offset == 0)
|
||||||
goto fail_calloc;
|
goto fail_calloc;
|
||||||
|
|
||||||
|
|
@ -330,7 +345,7 @@ nouveau_ws_bo_destroy(struct nouveau_ws_bo *bo)
|
||||||
|
|
||||||
if (dev->has_vm_bind) {
|
if (dev->has_vm_bind) {
|
||||||
nouveau_ws_bo_unbind_vma(bo->dev, bo->offset, bo->size);
|
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);
|
drmCloseBufferHandle(bo->dev->fd, bo->handle);
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,12 @@ struct nouveau_ws_bo {
|
||||||
};
|
};
|
||||||
|
|
||||||
uint64_t nouveau_ws_alloc_vma(struct nouveau_ws_device *dev,
|
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,
|
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,
|
void nouveau_ws_bo_bind_vma(struct nouveau_ws_device *dev,
|
||||||
struct nouveau_ws_bo *bo,
|
struct nouveau_ws_bo *bo,
|
||||||
|
|
|
||||||
|
|
@ -269,13 +269,15 @@ nouveau_ws_device_new(drmDevicePtr drm_device)
|
||||||
if (version < 0x01000301)
|
if (version < 0x01000301)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
const uint64_t TOP = 1ull << 40;
|
const uint64_t BDA = 1ull << 38;
|
||||||
const uint64_t KERN = 1ull << 39;
|
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));
|
int ret = drmCommandWrite(fd, DRM_NOUVEAU_VM_INIT, &vminit, sizeof(vminit));
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
device->has_vm_bind = true;
|
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);
|
simple_mtx_init(&device->vma_mutex, mtx_plain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ struct nouveau_ws_device {
|
||||||
|
|
||||||
bool has_vm_bind;
|
bool has_vm_bind;
|
||||||
struct util_vma_heap vma_heap;
|
struct util_vma_heap vma_heap;
|
||||||
|
struct util_vma_heap bda_heap;
|
||||||
simple_mtx_t vma_mutex;
|
simple_mtx_t vma_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue