From 53fb1d99cac9ab318c251aa3e448d26e0c94641c Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Tue, 20 Aug 2024 14:56:38 +0200 Subject: [PATCH] panvk: Transition to explicit VA assignment on v10+ Panthor allows us to control the GPU virtual address space, which, among other things, will allow us to support sparse bindings. Let's tweak the device initialization and BO mapping to takes this explicit VA management mode into account. Signed-off-by: Boris Brezillon Reviewed-by: Rebecca Mckeever Reviewed-by: Mary Guillemard Reviewed-by: Lars-Ivar Hesselberg Simonsen Reviewed-by: John Anthony Acked-by: Erik Faye-Lund Part-of: --- src/panfrost/vulkan/panvk_device.h | 6 ++++++ src/panfrost/vulkan/panvk_device_memory.c | 13 +++++++++++++ src/panfrost/vulkan/panvk_priv_bo.c | 10 ++++++++++ src/panfrost/vulkan/panvk_vX_device.c | 8 +++++++- 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/panfrost/vulkan/panvk_device.h b/src/panfrost/vulkan/panvk_device.h index 3b405ef8045..15b53b3f79e 100644 --- a/src/panfrost/vulkan/panvk_device.h +++ b/src/panfrost/vulkan/panvk_device.h @@ -23,11 +23,17 @@ #include "pan_blend.h" #include "pan_blitter.h" +#include "util/vma.h" + #define PANVK_MAX_QUEUE_FAMILIES 1 struct panvk_device { struct vk_device vk; + struct { + struct util_vma_heap heap; + } as; + struct { struct pan_kmod_vm *vm; struct pan_kmod_dev *dev; diff --git a/src/panfrost/vulkan/panvk_device_memory.c b/src/panfrost/vulkan/panvk_device_memory.c index 52248eb4246..f70fd57b74b 100644 --- a/src/panfrost/vulkan/panvk_device_memory.c +++ b/src/panfrost/vulkan/panvk_device_memory.c @@ -89,6 +89,16 @@ panvk_AllocateMemory(VkDevice _device, }, }; + if (!(device->kmod.vm->flags & PAN_KMOD_VM_FLAG_AUTO_VA)) { + op.va.start = + util_vma_heap_alloc(&device->as.heap, op.va.size, + op.va.size > 0x200000 ? 0x200000 : 0x1000); + if (!op.va.start) { + result = vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); + goto err_put_bo; + } + } + int ret = pan_kmod_vm_bind(device->kmod.vm, PAN_KMOD_VM_OP_MODE_IMMEDIATE, &op, 1); if (ret) { @@ -165,6 +175,9 @@ panvk_FreeMemory(VkDevice _device, VkDeviceMemory _mem, pan_kmod_vm_bind(device->kmod.vm, PAN_KMOD_VM_OP_MODE_IMMEDIATE, &op, 1); assert(!ret); + if (!(device->kmod.vm->flags & PAN_KMOD_VM_FLAG_AUTO_VA)) + util_vma_heap_free(&device->as.heap, op.va.start, op.va.size); + pan_kmod_bo_put(mem->bo); vk_device_memory_destroy(&device->vk, pAllocator, &mem->vk); } diff --git a/src/panfrost/vulkan/panvk_priv_bo.c b/src/panfrost/vulkan/panvk_priv_bo.c index b4981d7291f..07899e691f5 100644 --- a/src/panfrost/vulkan/panvk_priv_bo.c +++ b/src/panfrost/vulkan/panvk_priv_bo.c @@ -52,6 +52,13 @@ panvk_priv_bo_create(struct panvk_device *dev, size_t size, uint32_t flags, }, }; + if (!(dev->kmod.vm->flags & PAN_KMOD_VM_FLAG_AUTO_VA)) { + op.va.start = util_vma_heap_alloc( + &dev->as.heap, op.va.size, op.va.size > 0x200000 ? 0x200000 : 0x1000); + if (!op.va.start) + goto err_munmap_bo; + } + ret = pan_kmod_vm_bind(dev->kmod.vm, PAN_KMOD_VM_OP_MODE_IMMEDIATE, &op, 1); if (ret) goto err_munmap_bo; @@ -103,6 +110,9 @@ panvk_priv_bo_destroy(struct panvk_priv_bo *priv_bo) pan_kmod_vm_bind(dev->kmod.vm, PAN_KMOD_VM_OP_MODE_IMMEDIATE, &op, 1); assert(!ret); + if (!(dev->kmod.vm->flags & PAN_KMOD_VM_FLAG_AUTO_VA)) + util_vma_heap_free(&dev->as.heap, op.va.start, op.va.size); + if (priv_bo->addr.host) { ret = os_munmap(priv_bo->addr.host, pan_kmod_bo_size(priv_bo->bo)); assert(!ret); diff --git a/src/panfrost/vulkan/panvk_vX_device.c b/src/panfrost/vulkan/panvk_vX_device.c index d9f89a019aa..a8e7fa6d093 100644 --- a/src/panfrost/vulkan/panvk_vX_device.c +++ b/src/panfrost/vulkan/panvk_vX_device.c @@ -269,9 +269,13 @@ panvk_per_arch(create_device)(struct panvk_physical_device *physical_device, device->kmod.dev, PANVK_VA_RESERVE_BOTTOM); uint64_t user_va_end = panfrost_clamp_to_usable_va_range(device->kmod.dev, 1ull << 32); + uint32_t vm_flags = PAN_ARCH <= 7 ? PAN_KMOD_VM_FLAG_AUTO_VA : 0; + + util_vma_heap_init(&device->as.heap, user_va_start, + user_va_end - user_va_start); device->kmod.vm = - pan_kmod_vm_create(device->kmod.dev, PAN_KMOD_VM_FLAG_AUTO_VA, + pan_kmod_vm_create(device->kmod.dev, vm_flags, user_va_start, user_va_end - user_va_start); if (!device->kmod.vm) { @@ -365,6 +369,7 @@ err_free_priv_bos: panvk_priv_bo_unref(device->tiler_heap); panvk_device_cleanup_mempools(device); pan_kmod_vm_destroy(device->kmod.vm); + util_vma_heap_finish(&device->as.heap); err_destroy_kdev: pan_kmod_dev_destroy(device->kmod.dev); @@ -398,6 +403,7 @@ panvk_per_arch(destroy_device)(struct panvk_device *device, panvk_priv_bo_unref(device->sample_positions); panvk_device_cleanup_mempools(device); pan_kmod_vm_destroy(device->kmod.vm); + util_vma_heap_finish(&device->as.heap); if (device->debug.decode_ctx) pandecode_destroy_context(device->debug.decode_ctx);