Convert the PushBuffer to use VMA.

This commit is contained in:
Henrik Rydgård 2021-11-22 09:41:14 +01:00
parent 0cbb7ab027
commit 8d5247ddf3
4 changed files with 31 additions and 37 deletions

View File

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

View File

@ -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<VkDescriptorPool> descPools_;
std::vector<VkShaderModule> modules_;
std::vector<VkBuffer> buffers_;
std::vector<BufferWithAlloc> buffersWithAllocs_;
std::vector<VkBufferView> bufferViews_;
std::vector<VkImage> images_;
std::vector<ImageWithAlloc> imagesWithAllocs_;

View File

@ -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;
}

View File

@ -28,7 +28,7 @@ enum class PushBufferType {
class VulkanPushBuffer {
struct BufInfo {
VkBuffer buffer;
VkDeviceMemory deviceMemory;
VmaAllocation allocation;
};
public: