From 8d5247ddf3bb4ef321ca438389a7ab907e7e6417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 22 Nov 2021 09:41:14 +0100 Subject: [PATCH] Convert the PushBuffer to use VMA. --- Common/GPU/Vulkan/VulkanContext.cpp | 4 +++ Common/GPU/Vulkan/VulkanContext.h | 19 ++++++++++++- Common/GPU/Vulkan/VulkanMemory.cpp | 43 ++++++----------------------- Common/GPU/Vulkan/VulkanMemory.h | 2 +- 4 files changed, 31 insertions(+), 37 deletions(-) diff --git a/Common/GPU/Vulkan/VulkanContext.cpp b/Common/GPU/Vulkan/VulkanContext.cpp index 3621322cea..ebd23986f8 100644 --- a/Common/GPU/Vulkan/VulkanContext.cpp +++ b/Common/GPU/Vulkan/VulkanContext.cpp @@ -1362,6 +1362,10 @@ void VulkanDeleteList::PerformDeletes(VkDevice device, VmaAllocator allocator) { vkDestroyBuffer(device, buf, nullptr); } buffers_.clear(); + for (auto &buf : buffersWithAllocs_) { + vmaDestroyBuffer(allocator, buf.buffer, buf.alloc); + } + buffers_.clear(); for (auto &bufView : bufferViews_) { vkDestroyBufferView(device, bufView, nullptr); } diff --git a/Common/GPU/Vulkan/VulkanContext.h b/Common/GPU/Vulkan/VulkanContext.h index 232161ba3b..19fb168591 100644 --- a/Common/GPU/Vulkan/VulkanContext.h +++ b/Common/GPU/Vulkan/VulkanContext.h @@ -64,6 +64,10 @@ struct VulkanPhysicalDeviceInfo { // This is a bit repetitive... class VulkanDeleteList { + struct BufferWithAlloc { + VkBuffer buffer; + VmaAllocation alloc; + }; struct ImageWithAlloc { VkImage image; VmaAllocation alloc; @@ -86,7 +90,6 @@ public: void QueueDeleteBuffer(VkBuffer &buffer) { _dbg_assert_(buffer != VK_NULL_HANDLE); buffers_.push_back(buffer); buffer = VK_NULL_HANDLE; } void QueueDeleteBufferView(VkBufferView &bufferView) { _dbg_assert_(bufferView != VK_NULL_HANDLE); bufferViews_.push_back(bufferView); bufferView = VK_NULL_HANDLE; } void QueueDeleteImage(VkImage &image) { _dbg_assert_(image != VK_NULL_HANDLE); images_.push_back(image); image = VK_NULL_HANDLE; } - void QueueDeleteImageAllocation(VkImage &image, VmaAllocation &alloc) { _dbg_assert_(image != VK_NULL_HANDLE && alloc != VK_NULL_HANDLE); imagesWithAllocs_.push_back(ImageWithAlloc{ image, alloc }); image = VK_NULL_HANDLE; alloc = VK_NULL_HANDLE; } void QueueDeleteImageView(VkImageView &imageView) { _dbg_assert_(imageView != VK_NULL_HANDLE); imageViews_.push_back(imageView); imageView = VK_NULL_HANDLE; } void QueueDeleteDeviceMemory(VkDeviceMemory &deviceMemory) { _dbg_assert_(deviceMemory != VK_NULL_HANDLE); deviceMemory_.push_back(deviceMemory); deviceMemory = VK_NULL_HANDLE; } void QueueDeleteSampler(VkSampler &sampler) { _dbg_assert_(sampler != VK_NULL_HANDLE); samplers_.push_back(sampler); sampler = VK_NULL_HANDLE; } @@ -98,6 +101,19 @@ public: void QueueDeleteDescriptorSetLayout(VkDescriptorSetLayout &descSetLayout) { _dbg_assert_(descSetLayout != VK_NULL_HANDLE); descSetLayouts_.push_back(descSetLayout); descSetLayout = VK_NULL_HANDLE; } void QueueCallback(void(*func)(void *userdata), void *userdata) { callbacks_.push_back(Callback(func, userdata)); } + void QueueDeleteBufferAllocation(VkBuffer &buffer, VmaAllocation &alloc) { + _dbg_assert_(buffer != VK_NULL_HANDLE); + buffersWithAllocs_.push_back(BufferWithAlloc{ buffer, alloc }); + buffer = VK_NULL_HANDLE; + alloc = VK_NULL_HANDLE; + } + void QueueDeleteImageAllocation(VkImage &image, VmaAllocation &alloc) { + _dbg_assert_(image != VK_NULL_HANDLE && alloc != VK_NULL_HANDLE); + imagesWithAllocs_.push_back(ImageWithAlloc{ image, alloc }); + image = VK_NULL_HANDLE; + alloc = VK_NULL_HANDLE; + } + void Take(VulkanDeleteList &del); void PerformDeletes(VkDevice device, VmaAllocator allocator); @@ -106,6 +122,7 @@ private: std::vector descPools_; std::vector modules_; std::vector buffers_; + std::vector buffersWithAllocs_; std::vector bufferViews_; std::vector images_; std::vector imagesWithAllocs_; diff --git a/Common/GPU/Vulkan/VulkanMemory.cpp b/Common/GPU/Vulkan/VulkanMemory.cpp index f720b34e90..d4f1c25a2b 100644 --- a/Common/GPU/Vulkan/VulkanMemory.cpp +++ b/Common/GPU/Vulkan/VulkanMemory.cpp @@ -48,42 +48,16 @@ bool VulkanPushBuffer::AddBuffer() { b.queueFamilyIndexCount = 0; b.pQueueFamilyIndices = nullptr; - VkResult res = vkCreateBuffer(device, &b, nullptr, &info.buffer); + VmaAllocationCreateInfo allocCreateInfo{}; + allocCreateInfo.usage = type_ == PushBufferType::CPU_TO_GPU ? VMA_MEMORY_USAGE_CPU_TO_GPU : VMA_MEMORY_USAGE_GPU_ONLY; + VmaAllocationInfo allocInfo{}; + + VkResult res = vmaCreateBuffer(vulkan_->Allocator(), &b, &allocCreateInfo, &info.buffer, &info.allocation, &allocInfo); if (VK_SUCCESS != res) { _assert_msg_(false, "vkCreateBuffer failed! result=%d", (int)res); return false; } - VkMemoryPropertyFlags memoryPropertyMask_; - if (type_ == PushBufferType::CPU_TO_GPU) { - memoryPropertyMask_ = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - } else { - memoryPropertyMask_ = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - } - - // Get the buffer memory requirements. None of this can be cached! - VkMemoryRequirements reqs; - vkGetBufferMemoryRequirements(device, info.buffer, &reqs); - - // Okay, that's the buffer. Now let's allocate some memory for it. - VkMemoryAllocateInfo alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; - alloc.allocationSize = reqs.size; - vulkan_->MemoryTypeFromProperties(reqs.memoryTypeBits, memoryPropertyMask_, &alloc.memoryTypeIndex); - - res = vkAllocateMemory(device, &alloc, nullptr, &info.deviceMemory); - if (VK_SUCCESS != res) { - _assert_msg_(false, "vkAllocateMemory failed! size=%d result=%d", (int)reqs.size, (int)res); - vkDestroyBuffer(device, info.buffer, nullptr); - return false; - } - res = vkBindBufferMemory(device, info.buffer, info.deviceMemory, 0); - if (VK_SUCCESS != res) { - ERROR_LOG(G3D, "vkBindBufferMemory failed! result=%d", (int)res); - vkFreeMemory(device, info.deviceMemory, nullptr); - vkDestroyBuffer(device, info.buffer, nullptr); - return false; - } - buffers_.push_back(info); buf_ = buffers_.size() - 1; return true; @@ -91,8 +65,7 @@ bool VulkanPushBuffer::AddBuffer() { void VulkanPushBuffer::Destroy(VulkanContext *vulkan) { for (BufInfo &info : buffers_) { - vulkan->Delete().QueueDeleteBuffer(info.buffer); - vulkan->Delete().QueueDeleteDeviceMemory(info.deviceMemory); + vulkan->Delete().QueueDeleteBufferAllocation(info.buffer, info.allocation); } buffers_.clear(); } @@ -147,7 +120,7 @@ size_t VulkanPushBuffer::GetTotalSize() const { void VulkanPushBuffer::Map() { _dbg_assert_(!writePtr_); - VkResult res = vkMapMemory(vulkan_->GetDevice(), buffers_[buf_].deviceMemory, 0, size_, 0, (void **)(&writePtr_)); + VkResult res = vmaMapMemory(vulkan_->Allocator(), buffers_[buf_].allocation, (void **)(&writePtr_)); _dbg_assert_(writePtr_); _assert_(VK_SUCCESS == res); } @@ -168,6 +141,6 @@ void VulkanPushBuffer::Unmap() { } */ - vkUnmapMemory(vulkan_->GetDevice(), buffers_[buf_].deviceMemory); + vmaUnmapMemory(vulkan_->Allocator(), buffers_[buf_].allocation); writePtr_ = nullptr; } diff --git a/Common/GPU/Vulkan/VulkanMemory.h b/Common/GPU/Vulkan/VulkanMemory.h index 0508bb2102..567be174ee 100644 --- a/Common/GPU/Vulkan/VulkanMemory.h +++ b/Common/GPU/Vulkan/VulkanMemory.h @@ -28,7 +28,7 @@ enum class PushBufferType { class VulkanPushBuffer { struct BufInfo { VkBuffer buffer; - VkDeviceMemory deviceMemory; + VmaAllocation allocation; }; public: