From 03f0f01904ce8c4478be662c85f54bde41e852f6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 19 Jul 2023 16:45:27 -0500 Subject: [PATCH] nvk: Add support for sparse buffers Reviewed-by: Faith Ekstrand Part-of: --- src/nouveau/vulkan/nvk_buffer.c | 47 ++++++++++++++++++++++++++++++++++++- src/nouveau/vulkan/nvk_buffer.h | 8 ++++++- src/nouveau/vulkan/nvk_cmd_buffer.c | 4 ++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/nouveau/vulkan/nvk_buffer.c b/src/nouveau/vulkan/nvk_buffer.c index 2040965..c4aa191 100644 --- a/src/nouveau/vulkan/nvk_buffer.c +++ b/src/nouveau/vulkan/nvk_buffer.c @@ -7,7 +7,7 @@ uint32_t nvk_get_buffer_alignment(UNUSED const struct nvk_physical_device *pdev, VkBufferUsageFlags2KHR usage_flags, - UNUSED VkBufferCreateFlags create_flags) + VkBufferCreateFlags create_flags) { uint32_t alignment = 16; @@ -21,6 +21,9 @@ nvk_get_buffer_alignment(UNUSED const struct nvk_physical_device *pdev, VK_BUFFER_USAGE_2_STORAGE_TEXEL_BUFFER_BIT_KHR)) alignment = MAX2(alignment, NVK_MIN_UBO_ALIGNMENT); + if (create_flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) + alignment = MAX2(alignment, 4096); + return alignment; } @@ -38,6 +41,23 @@ nvk_CreateBuffer(VkDevice device, if (!buffer) return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY); +#if NVK_NEW_UAPI == 1 + if (buffer->vk.create_flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) { + const uint32_t alignment = + nvk_get_buffer_alignment(nvk_device_physical(dev), + buffer->vk.usage, + buffer->vk.create_flags); + assert(alignment >= 4096); + buffer->vma_size_B = ALIGN_POT(buffer->vk.size, alignment); + + 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); + } +#endif + *pBuffer = nvk_buffer_to_handle(buffer); return VK_SUCCESS; @@ -54,6 +74,17 @@ nvk_DestroyBuffer(VkDevice device, if (!buffer) return; +#if NVK_NEW_UAPI == 1 + if (buffer->vma_size_B > 0) { + const bool sparse_residency = + buffer->vk.create_flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT; + + 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); + } +#endif + vk_buffer_destroy(&dev->vk, pAllocator, &buffer->vk); } @@ -145,8 +176,22 @@ nvk_BindBufferMemory2(VkDevice device, VK_FROM_HANDLE(nvk_device_memory, mem, pBindInfos[i].memory); VK_FROM_HANDLE(nvk_buffer, buffer, pBindInfos[i].buffer); +#if NVK_NEW_UAPI == 1 + if (buffer->vma_size_B) { + VK_FROM_HANDLE(nvk_device, dev, device); + nouveau_ws_bo_bind_vma(dev->ws_dev, + mem->bo, + buffer->addr, + buffer->vma_size_B, + pBindInfos[i].memoryOffset, + 0 /* pte_kind */); + } else { + buffer->addr = mem->bo->offset + pBindInfos[i].memoryOffset; + } +#else buffer->mem = mem; buffer->addr = mem->bo->offset + pBindInfos[i].memoryOffset; +#endif } return VK_SUCCESS; } diff --git a/src/nouveau/vulkan/nvk_buffer.h b/src/nouveau/vulkan/nvk_buffer.h index 07f8e96..9afa0f1 100644 --- a/src/nouveau/vulkan/nvk_buffer.h +++ b/src/nouveau/vulkan/nvk_buffer.h @@ -17,8 +17,14 @@ nvk_get_buffer_alignment(const struct nvk_physical_device *pdev, struct nvk_buffer { struct vk_buffer vk; - struct nvk_device_memory *mem; uint64_t addr; + +#if NVK_NEW_UAPI == 1 + /** Size of the reserved VMA range for sparse buffers, zero otherwise. */ + uint64_t vma_size_B; +#else + struct nvk_device_memory *mem; +#endif }; VK_DEFINE_NONDISP_HANDLE_CASTS(nvk_buffer, vk.base, VkBuffer, VK_OBJECT_TYPE_BUFFER) diff --git a/src/nouveau/vulkan/nvk_cmd_buffer.c b/src/nouveau/vulkan/nvk_cmd_buffer.c index eaae440..46e5339 100644 --- a/src/nouveau/vulkan/nvk_cmd_buffer.c +++ b/src/nouveau/vulkan/nvk_cmd_buffer.c @@ -153,6 +153,9 @@ nvk_cmd_buffer_push_indirect_buffer(struct nvk_cmd_buffer *cmd, { nvk_cmd_buffer_flush_push(cmd); +#if NVK_NEW_UAPI == 1 + unreachable("Does not yet support sparse"); +#else /* TODO: The new uAPI should just take addresses */ struct nouveau_ws_bo *bo = buffer->mem->bo; uint64_t bo_offset = nvk_buffer_address(buffer, offset) - bo->offset; @@ -164,6 +167,7 @@ nvk_cmd_buffer_push_indirect_buffer(struct nvk_cmd_buffer *cmd, .range = NVC0_IB_ENTRY_1_NO_PREFETCH | range, }; util_dynarray_append(&cmd->pushes, struct nvk_cmd_push, push); +#endif } VkResult -- 2.7.4