Use vma in GEVulkanMeshCache

This commit is contained in:
Benau 2022-07-13 12:09:45 +08:00
parent cf8bafaab3
commit c864b9bd60
4 changed files with 36 additions and 92 deletions

View File

@ -288,9 +288,6 @@ namespace GE
} }
VkDevice getDevice() const { return m_vk->device; } VkDevice getDevice() const { return m_vk->device; }
void destroyVulkan(); void destroyVulkan();
bool createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
VkMemoryPropertyFlags properties, VkBuffer& buffer,
VkDeviceMemory& buffer_memory);
bool createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, bool createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
VmaAllocationCreateInfo& alloc_create_info, VmaAllocationCreateInfo& alloc_create_info,
VkBuffer& buffer, VmaAllocation& buffer_allocation); VkBuffer& buffer, VmaAllocation& buffer_allocation);

View File

@ -1451,59 +1451,6 @@ void GEVulkanDriver::createFramebuffers()
} }
} // createFramebuffers } // createFramebuffers
// ----------------------------------------------------------------------------
bool GEVulkanDriver::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
VkMemoryPropertyFlags properties,
VkBuffer& buffer,
VkDeviceMemory& buffer_memory)
{
VkBufferCreateInfo buffer_info = {};
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_info.size = size;
buffer_info.usage = usage;
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
VkResult result = vkCreateBuffer(m_vk->device, &buffer_info, NULL, &buffer);
if (result != VK_SUCCESS)
return false;
VkMemoryRequirements mem_requirements;
vkGetBufferMemoryRequirements(m_vk->device, buffer, &mem_requirements);
VkPhysicalDeviceMemoryProperties mem_properties;
vkGetPhysicalDeviceMemoryProperties(m_physical_device, &mem_properties);
uint32_t memory_type_index = std::numeric_limits<uint32_t>::max();
uint32_t type_filter = mem_requirements.memoryTypeBits;
for (uint32_t i = 0; i < mem_properties.memoryTypeCount; i++)
{
if ((type_filter & (1 << i)) &&
(mem_properties.memoryTypes[i].propertyFlags & properties) == properties)
{
memory_type_index = i;
break;
}
}
if (memory_type_index == std::numeric_limits<uint32_t>::max())
return false;
VkMemoryAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
alloc_info.allocationSize = mem_requirements.size;
alloc_info.memoryTypeIndex = memory_type_index;
result = vkAllocateMemory(m_vk->device, &alloc_info, NULL, &buffer_memory);
if (result != VK_SUCCESS)
return false;
vkBindBufferMemory(m_vk->device, buffer, buffer_memory, 0);
return true;
} // createBuffer
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
bool GEVulkanDriver::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, bool GEVulkanDriver::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,

View File

@ -58,70 +58,75 @@ void GEVulkanMeshCache::updateCache()
ibo_size *= sizeof(uint16_t); ibo_size *= sizeof(uint16_t);
VkBuffer staging_buffer = VK_NULL_HANDLE; VkBuffer staging_buffer = VK_NULL_HANDLE;
VkDeviceMemory staging_memory = VK_NULL_HANDLE; VmaAllocation staging_memory = VK_NULL_HANDLE;
VmaAllocationCreateInfo staging_buffer_create_info = {};
staging_buffer_create_info.usage = VMA_MEMORY_USAGE_AUTO;
staging_buffer_create_info.flags =
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
staging_buffer_create_info.preferredFlags = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
if (!m_vk->createBuffer(vbo_size, if (!m_vk->createBuffer(vbo_size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | staging_buffer_create_info, staging_buffer, staging_memory))
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
staging_buffer, staging_memory))
throw std::runtime_error("updateCache create staging vbo failed"); throw std::runtime_error("updateCache create staging vbo failed");
uint8_t* mapped; uint8_t* mapped;
if (vkMapMemory(m_vk->getDevice(), staging_memory, 0, if (vmaMapMemory(m_vk->getVmaAllocator(), staging_memory,
vbo_size, 0, (void**)&mapped) != VK_SUCCESS) (void**)&mapped) != VK_SUCCESS)
throw std::runtime_error("updateCache vkMapMemory failed"); throw std::runtime_error("updateCache vmaMapMemory failed");
size_t offset = 0; size_t offset = 0;
for (GESPMBuffer* spm_buffer : buffers) for (GESPMBuffer* spm_buffer : buffers)
{ {
size_t copy_size = spm_buffer->getVertexCount() * size_t copy_size = spm_buffer->getVertexCount() *
getVertexPitchFromType(video::EVT_SKINNED_MESH); getVertexPitchFromType(video::EVT_SKINNED_MESH);
memcpy(&mapped[offset], spm_buffer->getVertices(), copy_size); uint8_t* loc = mapped + offset;
memcpy(loc, spm_buffer->getVertices(), copy_size);
spm_buffer->setVBOOffset( spm_buffer->setVBOOffset(
offset / getVertexPitchFromType(video::EVT_SKINNED_MESH)); offset / getVertexPitchFromType(video::EVT_SKINNED_MESH));
offset += copy_size; offset += copy_size;
} }
vmaUnmapMemory(m_vk->getVmaAllocator(), staging_memory);
vmaFlushAllocation(m_vk->getVmaAllocator(), staging_memory, 0, offset);
VmaAllocationCreateInfo local_create_info = {};
local_create_info.usage = VMA_MEMORY_USAGE_AUTO;
local_create_info.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
if (!m_vk->createBuffer(vbo_size, if (!m_vk->createBuffer(vbo_size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, local_create_info, m_vbo_buffer, m_vbo_memory))
m_vbo_buffer, m_vbo_memory))
throw std::runtime_error("updateCache create vbo failed"); throw std::runtime_error("updateCache create vbo failed");
m_vk->copyBuffer(staging_buffer, m_vbo_buffer, vbo_size); m_vk->copyBuffer(staging_buffer, m_vbo_buffer, vbo_size);
vkUnmapMemory(m_vk->getDevice(), staging_memory); vmaDestroyBuffer(m_vk->getVmaAllocator(), staging_buffer, staging_memory);
vkFreeMemory(m_vk->getDevice(), staging_memory, NULL);
vkDestroyBuffer(m_vk->getDevice(), staging_buffer, NULL);
if (!m_vk->createBuffer(ibo_size, if (!m_vk->createBuffer(ibo_size,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | staging_buffer_create_info, staging_buffer, staging_memory))
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
staging_buffer, staging_memory))
throw std::runtime_error("updateCache create staging ibo failed"); throw std::runtime_error("updateCache create staging ibo failed");
if (vkMapMemory(m_vk->getDevice(), staging_memory, 0, if (vmaMapMemory(m_vk->getVmaAllocator(), staging_memory,
ibo_size, 0, (void**)&mapped) != VK_SUCCESS) (void**)&mapped) != VK_SUCCESS)
throw std::runtime_error("updateCache vkMapMemory failed"); throw std::runtime_error("updateCache vmaMapMemory failed");
offset = 0; offset = 0;
for (GESPMBuffer* spm_buffer : buffers) for (GESPMBuffer* spm_buffer : buffers)
{ {
size_t copy_size = spm_buffer->getIndexCount() * sizeof(uint16_t); size_t copy_size = spm_buffer->getIndexCount() * sizeof(uint16_t);
memcpy(&mapped[offset], spm_buffer->getIndices(), copy_size); uint8_t* loc = mapped + offset;
memcpy(loc, spm_buffer->getIndices(), copy_size);
spm_buffer->setIBOOffset(offset / sizeof(uint16_t)); spm_buffer->setIBOOffset(offset / sizeof(uint16_t));
offset += copy_size; offset += copy_size;
} }
vmaUnmapMemory(m_vk->getVmaAllocator(), staging_memory);
vmaFlushAllocation(m_vk->getVmaAllocator(), staging_memory, 0, offset);
if (!m_vk->createBuffer(ibo_size, if (!m_vk->createBuffer(ibo_size,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, local_create_info, m_ibo_buffer, m_ibo_memory))
m_ibo_buffer, m_ibo_memory))
throw std::runtime_error("updateCache create ibo failed"); throw std::runtime_error("updateCache create ibo failed");
m_vk->copyBuffer(staging_buffer, m_ibo_buffer, ibo_size); m_vk->copyBuffer(staging_buffer, m_ibo_buffer, ibo_size);
vkUnmapMemory(m_vk->getDevice(), staging_memory); vmaDestroyBuffer(m_vk->getVmaAllocator(), staging_buffer, staging_memory);
vkFreeMemory(m_vk->getDevice(), staging_memory, NULL);
vkDestroyBuffer(m_vk->getDevice(), staging_buffer, NULL);
} // updateCache } // updateCache
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -129,18 +134,12 @@ void GEVulkanMeshCache::destroy()
{ {
m_vk->waitIdle(); m_vk->waitIdle();
if (m_vbo_memory != VK_NULL_HANDLE) vmaDestroyBuffer(m_vk->getVmaAllocator(), m_vbo_buffer, m_vbo_memory);
vkFreeMemory(m_vk->getDevice(), m_vbo_memory, NULL); vmaDestroyBuffer(m_vk->getVmaAllocator(), m_ibo_buffer, m_ibo_memory);
m_vbo_memory = VK_NULL_HANDLE;
if (m_vbo_buffer != VK_NULL_HANDLE)
vkDestroyBuffer(m_vk->getDevice(), m_vbo_buffer, NULL);
m_vbo_buffer = VK_NULL_HANDLE;
if (m_ibo_memory != VK_NULL_HANDLE) m_vbo_memory = VK_NULL_HANDLE;
vkFreeMemory(m_vk->getDevice(), m_ibo_memory, NULL); m_vbo_buffer = VK_NULL_HANDLE;
m_ibo_memory = VK_NULL_HANDLE; m_ibo_memory = VK_NULL_HANDLE;
if (m_ibo_buffer != VK_NULL_HANDLE)
vkDestroyBuffer(m_vk->getDevice(), m_ibo_buffer, NULL);
m_ibo_buffer = VK_NULL_HANDLE; m_ibo_buffer = VK_NULL_HANDLE;
} // destroy } // destroy

View File

@ -2,6 +2,7 @@
#define HEADER_GE_VULKAN_MESH_CACHE_HPP #define HEADER_GE_VULKAN_MESH_CACHE_HPP
#include "vulkan_wrapper.h" #include "vulkan_wrapper.h"
#include "ge_vma.hpp"
#include "../source/Irrlicht/CMeshCache.h" #include "../source/Irrlicht/CMeshCache.h"
#include <cstdint> #include <cstdint>
@ -18,7 +19,7 @@ private:
VkBuffer m_vbo_buffer, m_ibo_buffer; VkBuffer m_vbo_buffer, m_ibo_buffer;
VkDeviceMemory m_vbo_memory, m_ibo_memory; VmaAllocation m_vbo_memory, m_ibo_memory;
public: public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
GEVulkanMeshCache(); GEVulkanMeshCache();