Combine vbo and ibo buffers

This commit is contained in:
Benau 2022-07-14 10:44:28 +08:00
parent c864b9bd60
commit 15eec8a8d2
5 changed files with 62 additions and 69 deletions

View File

@ -34,8 +34,6 @@ VkDescriptorSetLayout g_descriptor_set_layout = VK_NULL_HANDLE;
GEVulkanDynamicBuffer* g_tris_buffer = NULL;
GEVulkanDynamicBuffer* g_tris_index_buffer = NULL;
std::vector<VkDescriptorSet> g_descriptor_sets;
struct Tri
@ -69,8 +67,6 @@ void GEVulkan2dRenderer::destroy()
{
delete g_tris_buffer;
g_tris_buffer = NULL;
delete g_tris_index_buffer;
g_tris_index_buffer = NULL;
if (!g_vk)
return;
@ -284,9 +280,8 @@ void GEVulkan2dRenderer::createGraphicsPipeline()
void GEVulkan2dRenderer::createTrisBuffers()
{
g_tris_buffer = new GEVulkanDynamicBuffer(GVDBT_SYSTEM_RAM,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, 10000);
g_tris_index_buffer = new GEVulkanDynamicBuffer(GVDBT_SYSTEM_RAM,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT, 2000);
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
12000);
} // createTrisBuffers
// ----------------------------------------------------------------------------
@ -339,10 +334,11 @@ void GEVulkan2dRenderer::uploadTrisBuffers()
if (g_tex_map.empty())
return;
g_tris_buffer->setCurrentData(g_tris_queue.data(),
g_tris_queue.size() * sizeof(Tri));
g_tris_index_buffer->setCurrentData(g_tris_index_queue.data(),
g_tris_index_queue.size() * sizeof(uint16_t));
g_tris_buffer->setCurrentData(
{
{ (void*)g_tris_queue.data(), g_tris_queue.size() * sizeof(Tri) },
{ (void*)g_tris_index_queue.data(), g_tris_index_queue.size() * sizeof(uint16_t) }
});
} // uploadTrisBuffers
// ----------------------------------------------------------------------------
@ -412,27 +408,24 @@ void GEVulkan2dRenderer::render()
}
VkDeviceSize offsets[] = {0};
VkBuffer vertex_buffer = VK_NULL_HANDLE;
VkBuffer indices_buffer = VK_NULL_HANDLE;
VkBuffer buffer = VK_NULL_HANDLE;
unsigned idx = 0;
unsigned idx_count = 0;
int sampler_idx = 0;
core::recti clip;
vertex_buffer = g_tris_buffer->getCurrentBuffer();
indices_buffer = g_tris_index_buffer->getCurrentBuffer();
if (vertex_buffer == VK_NULL_HANDLE || indices_buffer == VK_NULL_HANDLE)
buffer = g_tris_buffer->getCurrentBuffer();
if (buffer == VK_NULL_HANDLE)
goto end;
vkCmdBindPipeline(g_vk->getCurrentCommandBuffer(),
VK_PIPELINE_BIND_POINT_GRAPHICS, g_graphics_pipeline);
vkCmdBindVertexBuffers(g_vk->getCurrentCommandBuffer(), 0, 1,
&vertex_buffer, offsets);
&buffer, offsets);
vkCmdBindIndexBuffer(g_vk->getCurrentCommandBuffer(), indices_buffer, 0,
VK_INDEX_TYPE_UINT16);
vkCmdBindIndexBuffer(g_vk->getCurrentCommandBuffer(), buffer,
g_tris_queue.size() * sizeof(Tri), VK_INDEX_TYPE_UINT16);
VkViewport vp;
vp.x = g_vk->getViewPort().UpperLeftCorner.X;

View File

@ -154,10 +154,15 @@ void GEVulkanDynamicBuffer::destroy()
} // destroy
// ----------------------------------------------------------------------------
void GEVulkanDynamicBuffer::setCurrentData(void* data, size_t size)
void GEVulkanDynamicBuffer::setCurrentData(const std::vector<
std::pair<void*, size_t> >& data)
{
GEVulkanDriver* vk = getVKDriver();
const unsigned cur_frame = vk->getCurrentFrame();
size_t size = 0;
for (auto& p : data)
size += p.second;
if (size > m_size)
{
destroy();
@ -168,7 +173,13 @@ void GEVulkanDynamicBuffer::setCurrentData(void* data, size_t size)
m_real_size = size;
if (size == 0 || m_mapped_addr[cur_frame] == NULL)
return;
memcpy(m_mapped_addr[cur_frame], data, size);
uint8_t* addr = (uint8_t*)m_mapped_addr[cur_frame];
for (auto& p : data)
{
memcpy(addr, p.first, p.second);
addr += p.second;
}
vmaFlushAllocation(vk->getVmaAllocator(), m_staging_memory != NULL ?
m_staging_memory[cur_frame] : m_memory[cur_frame], 0, size);

View File

@ -4,6 +4,9 @@
#include "vulkan_wrapper.h"
#include "ge_vma.hpp"
#include <vector>
#include <utility>
namespace GE
{
@ -46,7 +49,10 @@ public:
// ------------------------------------------------------------------------
~GEVulkanDynamicBuffer();
// ------------------------------------------------------------------------
void setCurrentData(void* data, size_t size);
void setCurrentData(const std::vector<std::pair<void*, size_t> >& data);
// ------------------------------------------------------------------------
void setCurrentData(void* data, size_t size)
{ setCurrentData({{ data, size }}); }
// ------------------------------------------------------------------------
VkBuffer getCurrentBuffer() const;
// ------------------------------------------------------------------------

View File

@ -17,10 +17,9 @@ GEVulkanMeshCache::GEVulkanMeshCache()
m_vk = getVKDriver();
m_irrlicht_cache_time = getMonoTimeMs();
m_ge_cache_time = 0;
m_vbo_buffer = VK_NULL_HANDLE;
m_vbo_memory = VK_NULL_HANDLE;
m_ibo_buffer = VK_NULL_HANDLE;
m_ibo_memory = VK_NULL_HANDLE;
m_buffer = VK_NULL_HANDLE;
m_memory = VK_NULL_HANDLE;
m_ibo_offset = 0;
} // init
// ----------------------------------------------------------------------------
@ -66,10 +65,11 @@ void GEVulkanMeshCache::updateCache()
VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
staging_buffer_create_info.preferredFlags = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
if (!m_vk->createBuffer(vbo_size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
staging_buffer_create_info, staging_buffer, staging_memory))
throw std::runtime_error("updateCache create staging vbo failed");
if (!m_vk->createBuffer(vbo_size + ibo_size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, staging_buffer_create_info,
staging_buffer, staging_memory))
throw std::runtime_error("updateCache create staging buffer failed");
uint8_t* mapped;
if (vmaMapMemory(m_vk->getVmaAllocator(), staging_memory,
@ -86,33 +86,13 @@ void GEVulkanMeshCache::updateCache()
offset / getVertexPitchFromType(video::EVT_SKINNED_MESH));
offset += copy_size;
}
vmaUnmapMemory(m_vk->getVmaAllocator(), staging_memory);
vmaFlushAllocation(m_vk->getVmaAllocator(), staging_memory, 0, offset);
m_ibo_offset = 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,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
local_create_info, m_vbo_buffer, m_vbo_memory))
throw std::runtime_error("updateCache create vbo failed");
m_vk->copyBuffer(staging_buffer, m_vbo_buffer, vbo_size);
vmaDestroyBuffer(m_vk->getVmaAllocator(), staging_buffer, staging_memory);
if (!m_vk->createBuffer(ibo_size,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
staging_buffer_create_info, staging_buffer, staging_memory))
throw std::runtime_error("updateCache create staging ibo failed");
if (vmaMapMemory(m_vk->getVmaAllocator(), staging_memory,
(void**)&mapped) != VK_SUCCESS)
throw std::runtime_error("updateCache vmaMapMemory failed");
offset = 0;
for (GESPMBuffer* spm_buffer : buffers)
{
size_t copy_size = spm_buffer->getIndexCount() * sizeof(uint16_t);
uint8_t* loc = mapped + offset;
uint8_t* loc = mapped + offset + m_ibo_offset;
memcpy(loc, spm_buffer->getIndices(), copy_size);
spm_buffer->setIBOOffset(offset / sizeof(uint16_t));
offset += copy_size;
@ -120,12 +100,16 @@ void GEVulkanMeshCache::updateCache()
vmaUnmapMemory(m_vk->getVmaAllocator(), staging_memory);
vmaFlushAllocation(m_vk->getVmaAllocator(), staging_memory, 0, offset);
if (!m_vk->createBuffer(ibo_size,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
local_create_info, m_ibo_buffer, m_ibo_memory))
throw std::runtime_error("updateCache create ibo failed");
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 + ibo_size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT, local_create_info, m_buffer,
m_memory))
throw std::runtime_error("updateCache create buffer failed");
m_vk->copyBuffer(staging_buffer, m_ibo_buffer, ibo_size);
m_vk->copyBuffer(staging_buffer, m_buffer, vbo_size + ibo_size);
vmaDestroyBuffer(m_vk->getVmaAllocator(), staging_buffer, staging_memory);
} // updateCache
@ -134,13 +118,10 @@ void GEVulkanMeshCache::destroy()
{
m_vk->waitIdle();
vmaDestroyBuffer(m_vk->getVmaAllocator(), m_vbo_buffer, m_vbo_memory);
vmaDestroyBuffer(m_vk->getVmaAllocator(), m_ibo_buffer, m_ibo_memory);
m_vbo_memory = VK_NULL_HANDLE;
m_vbo_buffer = VK_NULL_HANDLE;
m_ibo_memory = VK_NULL_HANDLE;
m_ibo_buffer = VK_NULL_HANDLE;
vmaDestroyBuffer(m_vk->getVmaAllocator(), m_buffer, m_memory);
m_buffer = VK_NULL_HANDLE;
m_memory = VK_NULL_HANDLE;
m_ibo_offset = 0;
} // destroy
}

View File

@ -17,9 +17,11 @@ private:
uint64_t m_irrlicht_cache_time, m_ge_cache_time;
VkBuffer m_vbo_buffer, m_ibo_buffer;
VkBuffer m_buffer;
VmaAllocation m_vbo_memory, m_ibo_memory;
VmaAllocation m_memory;
size_t m_ibo_offset;
public:
// ------------------------------------------------------------------------
GEVulkanMeshCache();
@ -30,9 +32,9 @@ public:
// ------------------------------------------------------------------------
void destroy();
// ------------------------------------------------------------------------
VkBuffer getVBO() const { return m_vbo_buffer; }
VkBuffer getBuffer() const { return m_buffer; }
// ------------------------------------------------------------------------
VkBuffer getIBO() const { return m_ibo_buffer; }
size_t getIBOOffset() const { return m_ibo_offset; }
}; // GEVulkanMeshCache
}