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