Allow creating different buffer sizes in GEVulkanDynamicBuffer
This commit is contained in:
parent
e5318d8ea9
commit
51a1396313
@ -248,9 +248,9 @@ void GEVulkan2dRenderer::createGraphicsPipeline()
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkan2dRenderer::createTrisBuffers()
|
||||
{
|
||||
g_tris_buffer = new GEVulkanDynamicBuffer(GVDBT_SYSTEM_RAM,
|
||||
g_tris_buffer = new GEVulkanDynamicBuffer(
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
||||
12000);
|
||||
12000, GEVulkanDriver::getMaxFrameInFlight(), 0);
|
||||
} // createTrisBuffers
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -1024,12 +1024,15 @@ void GEVulkanDrawCall::createVulkanData()
|
||||
flags |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
|
||||
extra_size = 200 * sizeof(VkDrawIndexedIndirectCommand);
|
||||
}
|
||||
m_dynamic_data = new GEVulkanDynamicBuffer(GVDBT_GPU_RAM, flags,
|
||||
extra_size + sizeof(GEVulkanCameraUBO));
|
||||
m_dynamic_data = new GEVulkanDynamicBuffer(flags,
|
||||
extra_size + sizeof(GEVulkanCameraUBO),
|
||||
GEVulkanDriver::getMaxFrameInFlight(),
|
||||
GEVulkanDriver::getMaxFrameInFlight());
|
||||
|
||||
flags = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
m_sbo_data = new GEVulkanDynamicBuffer(GVDBT_GPU_RAM, flags,
|
||||
getInitialSBOSize());
|
||||
m_sbo_data = new GEVulkanDynamicBuffer(flags, getInitialSBOSize(),
|
||||
GEVulkanDriver::getMaxFrameInFlight(),
|
||||
GEVulkanDriver::getMaxFrameInFlight());
|
||||
} // createVulkanData
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -11,56 +11,37 @@ namespace GE
|
||||
{
|
||||
int GEVulkanDynamicBuffer::m_supports_host_transfer = -1;
|
||||
// ----------------------------------------------------------------------------
|
||||
GEVulkanDynamicBuffer::GEVulkanDynamicBuffer(GEVulkanDynamicBufferType t,
|
||||
VkBufferUsageFlags usage,
|
||||
size_t initial_size)
|
||||
GEVulkanDynamicBuffer::GEVulkanDynamicBuffer(VkBufferUsageFlags usage,
|
||||
size_t initial_size,
|
||||
unsigned host_buffer_size,
|
||||
unsigned local_buffer_size)
|
||||
{
|
||||
m_type = t;
|
||||
m_usage = usage;
|
||||
m_size = m_real_size = initial_size;
|
||||
|
||||
m_buffer = new VkBuffer[GEVulkanDriver::getMaxFrameInFlight()];
|
||||
m_memory = new VmaAllocation[GEVulkanDriver::getMaxFrameInFlight()];
|
||||
m_mapped_addr = new void*[GEVulkanDriver::getMaxFrameInFlight()];
|
||||
if (t == GVDBT_GPU_RAM)
|
||||
{
|
||||
m_staging_buffer = new VkBuffer[GEVulkanDriver::getMaxFrameInFlight()];
|
||||
m_staging_memory = new VmaAllocation[GEVulkanDriver::getMaxFrameInFlight()];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_staging_buffer = NULL;
|
||||
m_staging_memory = NULL;
|
||||
}
|
||||
m_host_buffer.resize(host_buffer_size, VK_NULL_HANDLE);
|
||||
m_host_memory.resize(host_buffer_size, VK_NULL_HANDLE);
|
||||
m_mapped_addr.resize(host_buffer_size, VK_NULL_HANDLE);
|
||||
|
||||
for (unsigned i = 0; i < GEVulkanDriver::getMaxFrameInFlight(); i++)
|
||||
initPerFrame(i);
|
||||
m_local_buffer.resize(local_buffer_size, VK_NULL_HANDLE);
|
||||
m_local_memory.resize(local_buffer_size, VK_NULL_HANDLE);
|
||||
|
||||
for (unsigned i = 0; i < m_host_buffer.size(); i++)
|
||||
initHostBuffer(i, m_local_buffer.size() == 0);
|
||||
for (unsigned i = 0; i < m_local_buffer.size(); i++)
|
||||
initLocalBuffer(i);
|
||||
} // GEVulkanDynamicBuffer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
GEVulkanDynamicBuffer::~GEVulkanDynamicBuffer()
|
||||
{
|
||||
destroy();
|
||||
delete [] m_buffer;
|
||||
delete [] m_memory;
|
||||
delete [] m_staging_buffer;
|
||||
delete [] m_staging_memory;
|
||||
delete [] m_mapped_addr;
|
||||
} // ~GEVulkanDynamicBuffer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDynamicBuffer::initPerFrame(unsigned frame)
|
||||
void GEVulkanDynamicBuffer::initHostBuffer(unsigned frame, bool with_transfer)
|
||||
{
|
||||
GEVulkanDriver* vk = getVKDriver();
|
||||
m_buffer[frame] = VK_NULL_HANDLE;
|
||||
m_memory[frame] = VK_NULL_HANDLE;
|
||||
m_mapped_addr[frame] = NULL;
|
||||
if (m_type == GVDBT_GPU_RAM)
|
||||
{
|
||||
m_staging_buffer[frame] = VK_NULL_HANDLE;
|
||||
m_staging_memory[frame] = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
start:
|
||||
VkMemoryPropertyFlags prop = {};
|
||||
VkBuffer host_buffer = VK_NULL_HANDLE;
|
||||
@ -70,8 +51,8 @@ start:
|
||||
host_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
|
||||
VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
||||
host_info.preferredFlags = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
||||
if ((m_type == GVDBT_SYSTEM_RAM && m_supports_host_transfer == 1) ||
|
||||
(m_type == GVDBT_SYSTEM_RAM && m_supports_host_transfer == -1))
|
||||
if ((with_transfer && m_supports_host_transfer == 1) ||
|
||||
(with_transfer && m_supports_host_transfer == -1))
|
||||
{
|
||||
host_info.flags |=
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT;
|
||||
@ -84,7 +65,7 @@ start:
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_type == GVDBT_SYSTEM_RAM && m_supports_host_transfer == -1)
|
||||
if (with_transfer && m_supports_host_transfer == -1)
|
||||
{
|
||||
vmaGetAllocationMemoryProperties(vk->getVmaAllocator(), host_memory,
|
||||
&prop);
|
||||
@ -100,57 +81,54 @@ start:
|
||||
|
||||
VmaAllocationInfo info = {};
|
||||
vmaGetAllocationInfo(vk->getVmaAllocator(), host_memory, &info);
|
||||
if (m_type == GVDBT_SYSTEM_RAM)
|
||||
{
|
||||
m_buffer[frame] = host_buffer;
|
||||
m_memory[frame] = host_memory;
|
||||
m_mapped_addr[frame] = info.pMappedData;
|
||||
return;
|
||||
}
|
||||
|
||||
m_host_buffer[frame] = host_buffer;
|
||||
m_host_memory[frame] = host_memory;
|
||||
m_mapped_addr[frame] = info.pMappedData;
|
||||
} // initHostBuffer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDynamicBuffer::initLocalBuffer(unsigned frame)
|
||||
{
|
||||
GEVulkanDriver* vk = getVKDriver();
|
||||
VkBuffer local_buffer = VK_NULL_HANDLE;
|
||||
VmaAllocation local_memory = VK_NULL_HANDLE;
|
||||
VmaAllocationCreateInfo local_info = {};
|
||||
local_info.usage = VMA_MEMORY_USAGE_AUTO;
|
||||
|
||||
if (!vk->createBuffer(m_size, m_usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
local_info, local_buffer, local_memory))
|
||||
VkBufferUsageFlags flags = m_usage;
|
||||
if (!m_host_buffer.empty())
|
||||
flags |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
if (!vk->createBuffer(m_size, flags, local_info, local_buffer,
|
||||
local_memory))
|
||||
{
|
||||
vmaDestroyBuffer(vk->getVmaAllocator(), host_buffer, host_memory);
|
||||
vmaDestroyBuffer(vk->getVmaAllocator(), local_buffer, local_memory);
|
||||
return;
|
||||
}
|
||||
m_buffer[frame] = local_buffer;
|
||||
m_memory[frame] = local_memory;
|
||||
m_staging_buffer[frame] = host_buffer;
|
||||
m_staging_memory[frame] = host_memory;
|
||||
m_mapped_addr[frame] = info.pMappedData;
|
||||
} // initPerFrame
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDynamicBuffer::destroyPerFrame(unsigned frame)
|
||||
{
|
||||
GEVulkanDriver* vk = getVKDriver();
|
||||
vmaDestroyBuffer(vk->getVmaAllocator(), m_buffer[frame], m_memory[frame]);
|
||||
m_buffer[frame] = VK_NULL_HANDLE;
|
||||
m_memory[frame] = VK_NULL_HANDLE;
|
||||
m_mapped_addr[frame] = NULL;
|
||||
|
||||
if (m_type == GVDBT_GPU_RAM)
|
||||
{
|
||||
vmaDestroyBuffer(vk->getVmaAllocator(), m_staging_buffer[frame],
|
||||
m_staging_memory[frame]);
|
||||
m_staging_buffer[frame] = VK_NULL_HANDLE;
|
||||
m_staging_memory[frame] = VK_NULL_HANDLE;
|
||||
}
|
||||
} // destroyPerFrame
|
||||
m_local_buffer[frame] = local_buffer;
|
||||
m_local_memory[frame] = local_memory;
|
||||
} // initLocalBuffer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDynamicBuffer::destroy()
|
||||
{
|
||||
getVKDriver()->waitIdle();
|
||||
for (unsigned i = 0; i < GEVulkanDriver::getMaxFrameInFlight(); i++)
|
||||
destroyPerFrame(i);
|
||||
GEVulkanDriver* vk = getVKDriver();
|
||||
vk->waitIdle();
|
||||
for (unsigned i = 0; i < m_host_buffer.size(); i++)
|
||||
{
|
||||
vmaDestroyBuffer(vk->getVmaAllocator(), m_host_buffer[i],
|
||||
m_host_memory[i]);
|
||||
m_host_buffer[i] = VK_NULL_HANDLE;
|
||||
m_host_memory[i] = VK_NULL_HANDLE;
|
||||
m_mapped_addr[i] = NULL;
|
||||
}
|
||||
for (unsigned i = 0; i < m_local_buffer.size(); i++)
|
||||
{
|
||||
vmaDestroyBuffer(vk->getVmaAllocator(), m_local_buffer[i],
|
||||
m_local_memory[i]);
|
||||
m_local_buffer[i] = VK_NULL_HANDLE;
|
||||
m_local_memory[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
} // destroy
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -159,7 +137,6 @@ void GEVulkanDynamicBuffer::setCurrentData(const std::vector<
|
||||
VkCommandBuffer custom_cmd)
|
||||
{
|
||||
GEVulkanDriver* vk = getVKDriver();
|
||||
const unsigned cur_frame = vk->getCurrentFrame();
|
||||
|
||||
size_t size = 0;
|
||||
for (auto& p : data)
|
||||
@ -167,7 +144,11 @@ void GEVulkanDynamicBuffer::setCurrentData(const std::vector<
|
||||
resizeIfNeeded(size);
|
||||
|
||||
m_real_size = size;
|
||||
if (size == 0 || m_mapped_addr[cur_frame] == NULL)
|
||||
unsigned cur_frame = getVKDriver()->getCurrentFrame();
|
||||
if (cur_frame >= m_mapped_addr.size())
|
||||
cur_frame = 0;
|
||||
|
||||
if (size == 0 || m_mapped_addr.empty() || m_mapped_addr[cur_frame] == NULL)
|
||||
return;
|
||||
|
||||
uint8_t* addr = (uint8_t*)m_mapped_addr[cur_frame];
|
||||
@ -176,15 +157,19 @@ void GEVulkanDynamicBuffer::setCurrentData(const std::vector<
|
||||
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);
|
||||
vmaFlushAllocation(vk->getVmaAllocator(), m_host_memory[cur_frame], 0,
|
||||
size);
|
||||
|
||||
if (m_type == GVDBT_GPU_RAM)
|
||||
if (!m_local_buffer.empty())
|
||||
{
|
||||
unsigned cur_local_frame = getVKDriver()->getCurrentFrame();
|
||||
if (cur_local_frame >= m_local_buffer.size())
|
||||
cur_local_frame = 0;
|
||||
VkBufferCopy copy_region = {};
|
||||
copy_region.size = size;
|
||||
vkCmdCopyBuffer(custom_cmd ? custom_cmd : vk->getCurrentCommandBuffer(),
|
||||
m_staging_buffer[cur_frame], m_buffer[cur_frame], 1, ©_region);
|
||||
m_host_buffer[cur_frame], m_local_buffer[cur_local_frame], 1,
|
||||
©_region);
|
||||
}
|
||||
} // setCurrentData
|
||||
|
||||
@ -195,15 +180,29 @@ void GEVulkanDynamicBuffer::resizeIfNeeded(size_t new_size)
|
||||
{
|
||||
destroy();
|
||||
m_size = new_size + 100;
|
||||
for (unsigned i = 0; i < GEVulkanDriver::getMaxFrameInFlight(); i++)
|
||||
initPerFrame(i);
|
||||
for (unsigned i = 0; i < m_host_buffer.size(); i++)
|
||||
initHostBuffer(i, m_local_buffer.size() == 0);
|
||||
for (unsigned i = 0; i < m_local_buffer.size(); i++)
|
||||
initLocalBuffer(i);
|
||||
}
|
||||
} // resizeIfNeeded
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
VkBuffer GEVulkanDynamicBuffer::getCurrentBuffer() const
|
||||
{
|
||||
return m_buffer[getVKDriver()->getCurrentFrame()];
|
||||
unsigned cur_frame = getVKDriver()->getCurrentFrame();
|
||||
if (m_local_buffer.empty())
|
||||
{
|
||||
if (cur_frame >= m_host_buffer.size())
|
||||
cur_frame = 0;
|
||||
return m_host_buffer[cur_frame];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cur_frame >= m_local_buffer.size())
|
||||
cur_frame = 0;
|
||||
return m_local_buffer[cur_frame];
|
||||
}
|
||||
} // getCurrentBuffer
|
||||
|
||||
}
|
||||
|
@ -10,42 +10,31 @@
|
||||
namespace GE
|
||||
{
|
||||
|
||||
enum GEVulkanDynamicBufferType : unsigned
|
||||
{
|
||||
GVDBT_GPU_RAM,
|
||||
GVDBT_SYSTEM_RAM
|
||||
};
|
||||
|
||||
class GEVulkanDynamicBuffer
|
||||
{
|
||||
private:
|
||||
VkBuffer* m_buffer;
|
||||
std::vector<VkBuffer> m_host_buffer, m_local_buffer;
|
||||
|
||||
VmaAllocation* m_memory;
|
||||
std::vector<VmaAllocation> m_host_memory, m_local_memory;
|
||||
|
||||
VkBuffer* m_staging_buffer;
|
||||
|
||||
VmaAllocation* m_staging_memory;
|
||||
|
||||
void** m_mapped_addr;
|
||||
std::vector<void*> m_mapped_addr;
|
||||
|
||||
VkBufferUsageFlags m_usage;
|
||||
|
||||
GEVulkanDynamicBufferType m_type;
|
||||
|
||||
size_t m_size, m_real_size;
|
||||
|
||||
static int m_supports_host_transfer;
|
||||
// ------------------------------------------------------------------------
|
||||
void initPerFrame(unsigned frame);
|
||||
void initHostBuffer(unsigned frame, bool with_transfer);
|
||||
// ------------------------------------------------------------------------
|
||||
void destroyPerFrame(unsigned frame);
|
||||
void initLocalBuffer(unsigned frame);
|
||||
// ------------------------------------------------------------------------
|
||||
void destroy();
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
GEVulkanDynamicBuffer(GEVulkanDynamicBufferType t,
|
||||
VkBufferUsageFlags usage, size_t initial_size);
|
||||
GEVulkanDynamicBuffer(VkBufferUsageFlags usage, size_t initial_size,
|
||||
unsigned host_buffer_size,
|
||||
unsigned local_buffer_size);
|
||||
// ------------------------------------------------------------------------
|
||||
~GEVulkanDynamicBuffer();
|
||||
// ------------------------------------------------------------------------
|
||||
@ -61,6 +50,17 @@ public:
|
||||
void resizeIfNeeded(size_t new_size);
|
||||
// ------------------------------------------------------------------------
|
||||
size_t getRealSize() const { return m_real_size; }
|
||||
// ------------------------------------------------------------------------
|
||||
std::vector<VkBuffer>& getHostBuffer() { return m_host_buffer; }
|
||||
// ------------------------------------------------------------------------
|
||||
std::vector<VkBuffer>& getLocalBuffer() { return m_local_buffer; }
|
||||
// ------------------------------------------------------------------------
|
||||
std::vector<VmaAllocation>& getHostMemory() { return m_host_memory; }
|
||||
// ------------------------------------------------------------------------
|
||||
std::vector<VmaAllocation>& getLocalMemory() { return m_local_memory; }
|
||||
// ------------------------------------------------------------------------
|
||||
std::vector<void*>& getMappedAddr() { return m_mapped_addr; }
|
||||
|
||||
}; // GEVulkanDynamicBuffer
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user