Added KRDevice::StagingBufferInfo to collect staging buffer related members and functions

This commit is contained in:
2022-07-19 01:11:28 -07:00
parent ff4eb2589c
commit 8f63d9607a
2 changed files with 48 additions and 67 deletions

View File

@@ -47,16 +47,8 @@ KRDevice::KRDevice(KRContext& context, const VkPhysicalDevice& device)
, m_graphicsCommandPool(VK_NULL_HANDLE) , m_graphicsCommandPool(VK_NULL_HANDLE)
, m_computeCommandPool(VK_NULL_HANDLE) , m_computeCommandPool(VK_NULL_HANDLE)
, m_allocator(VK_NULL_HANDLE) , m_allocator(VK_NULL_HANDLE)
, m_streamingStagingBuffer(VK_NULL_HANDLE) , m_streamingStagingBuffer{}
, m_streamingStagingBufferAllocation(VK_NULL_HANDLE) , m_graphicsStagingBuffer{}
, m_streamingStagingBufferSize(0)
, m_streamingStagingBufferUsage(0)
, m_streamingStagingBufferData(nullptr)
, m_graphicsStagingBuffer(VK_NULL_HANDLE)
, m_graphicsStagingBufferAllocation(VK_NULL_HANDLE)
, m_graphicsStagingBufferSize(0)
, m_graphicsStagingBufferUsage(0)
, m_graphicsStagingBufferData(nullptr)
{ {
} }
@@ -66,31 +58,24 @@ KRDevice::~KRDevice()
destroy(); destroy();
} }
void KRDevice::StagingBufferInfo::destroy(VmaAllocator& allocator)
{
if (data) {
vmaUnmapMemory(allocator, allocation);
data = nullptr;
}
if (buffer) {
vmaDestroyBuffer(allocator, buffer, allocation);
size = 0;
buffer = VK_NULL_HANDLE;
allocation = VK_NULL_HANDLE;
}
}
void KRDevice::destroy() void KRDevice::destroy()
{ {
if (m_streamingStagingBufferData) { m_streamingStagingBuffer.destroy(m_allocator);
vmaUnmapMemory(m_allocator, m_streamingStagingBufferAllocation); m_graphicsStagingBuffer.destroy(m_allocator);
m_streamingStagingBufferData = nullptr;
}
if (m_graphicsStagingBufferData) {
vmaUnmapMemory(m_allocator, m_graphicsStagingBufferAllocation);
m_graphicsStagingBufferData = nullptr;
}
if (m_streamingStagingBuffer) {
vmaDestroyBuffer(m_allocator, m_streamingStagingBuffer, m_streamingStagingBufferAllocation);
m_streamingStagingBufferSize = 0;
m_streamingStagingBuffer = VK_NULL_HANDLE;
m_streamingStagingBufferAllocation = VK_NULL_HANDLE;
}
if (m_graphicsStagingBuffer) {
vmaDestroyBuffer(m_allocator, m_graphicsStagingBuffer, m_graphicsStagingBufferAllocation);
m_graphicsStagingBufferSize = 0;
m_graphicsStagingBuffer = VK_NULL_HANDLE;
m_graphicsStagingBufferAllocation = VK_NULL_HANDLE;
}
if (m_graphicsCommandPool != VK_NULL_HANDLE) { if (m_graphicsCommandPool != VK_NULL_HANDLE) {
vkDestroyCommandPool(m_logicalDevice, m_graphicsCommandPool, nullptr); vkDestroyCommandPool(m_logicalDevice, m_graphicsCommandPool, nullptr);
@@ -386,11 +371,8 @@ bool KRDevice::initStagingBuffers()
// This will be used for asynchronous asset streaming in the streamer thread. // This will be used for asynchronous asset streaming in the streamer thread.
// Start with a 256MB staging buffer. // Start with a 256MB staging buffer.
// TODO - Dynamically size staging buffer using heuristics // TODO - Dynamically size staging buffer using heuristics
m_streamingStagingBufferSize = size_t(256) * 1024 * 1024; size_t size = size_t(256) * 1024 * 1024;
if (!createStagingBuffer(m_streamingStagingBufferSize, if (!initStagingBuffer(size, &m_streamingStagingBuffer
&m_streamingStagingBuffer,
&m_streamingStagingBufferAllocation,
&m_streamingStagingBufferData
#if KRENGINE_DEBUG_GPU_LABELS #if KRENGINE_DEBUG_GPU_LABELS
, "Streaming Staging Buffer" , "Streaming Staging Buffer"
#endif // KRENGINE_DEBUG_GPU_LABELS #endif // KRENGINE_DEBUG_GPU_LABELS
@@ -402,11 +384,9 @@ bool KRDevice::initStagingBuffers()
// This will be used for uploading assets procedurally generated while recording the graphics command buffer. // This will be used for uploading assets procedurally generated while recording the graphics command buffer.
// Start with a 256MB staging buffer. // Start with a 256MB staging buffer.
// TODO - Dynamically size staging buffer using heuristics // TODO - Dynamically size staging buffer using heuristics
m_graphicsStagingBufferSize = size_t(256) * 1024 * 1024; size = size_t(256) * 1024 * 1024;
if (!createStagingBuffer(m_graphicsStagingBufferSize, if (!initStagingBuffer(size,
&m_graphicsStagingBuffer, &m_graphicsStagingBuffer
&m_graphicsStagingBufferAllocation,
&m_graphicsStagingBufferData
#if KRENGINE_DEBUG_GPU_LABELS #if KRENGINE_DEBUG_GPU_LABELS
, "Graphics Staging Buffer" , "Graphics Staging Buffer"
#endif // KRENGINE_DEBUG_GPU_LABELS #endif // KRENGINE_DEBUG_GPU_LABELS
@@ -416,7 +396,7 @@ bool KRDevice::initStagingBuffers()
return true; return true;
} }
bool KRDevice::createStagingBuffer(VkDeviceSize size, VkBuffer* buffer, VmaAllocation* allocation, void** data bool KRDevice::initStagingBuffer(VkDeviceSize size, StagingBufferInfo* info
#if KRENGINE_DEBUG_GPU_LABELS #if KRENGINE_DEBUG_GPU_LABELS
, const char* debug_label , const char* debug_label
#endif // KRENGINE_DEBUG_GPU_LABELS #endif // KRENGINE_DEBUG_GPU_LABELS
@@ -426,15 +406,15 @@ bool KRDevice::createStagingBuffer(VkDeviceSize size, VkBuffer* buffer, VmaAlloc
size, size,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
buffer, &info->buffer,
allocation &info->allocation
#if KRENGINE_DEBUG_GPU_LABELS #if KRENGINE_DEBUG_GPU_LABELS
, debug_label , debug_label
#endif // KRENGINE_DEBUG_GPU_LABELS #endif // KRENGINE_DEBUG_GPU_LABELS
)) { )) {
return false; return false;
} }
if (vmaMapMemory(m_allocator, *allocation, data) != VK_SUCCESS) { if (vmaMapMemory(m_allocator, info->allocation, &info->data) != VK_SUCCESS) {
return false; return false;
} }
return true; return true;
@@ -655,7 +635,7 @@ void KRDevice::streamStart()
size_t KRDevice::streamRemaining() const size_t KRDevice::streamRemaining() const
{ {
return m_streamingStagingBufferSize - m_streamingStagingBufferUsage; return m_streamingStagingBuffer.size - m_streamingStagingBuffer.usage;
} }
void KRDevice::streamUpload(KRDataBlock& data, VkBuffer destination) void KRDevice::streamUpload(KRDataBlock& data, VkBuffer destination)
@@ -667,23 +647,23 @@ void KRDevice::streamUpload(KRDataBlock& data, VkBuffer destination)
void KRDevice::streamUpload(void* data, size_t size, VkBuffer destination) void KRDevice::streamUpload(void* data, size_t size, VkBuffer destination)
{ {
memcpy((uint8_t*)m_streamingStagingBufferData + m_streamingStagingBufferUsage, data, size); memcpy((uint8_t*)m_streamingStagingBuffer.data + m_streamingStagingBuffer.usage, data, size);
// TODO - Beneficial to batch many regions in a single call? // TODO - Beneficial to batch many regions in a single call?
VkBufferCopy copyRegion{}; VkBufferCopy copyRegion{};
copyRegion.srcOffset = m_streamingStagingBufferUsage; copyRegion.srcOffset = m_streamingStagingBuffer.usage;
copyRegion.dstOffset = 0; // Optional copyRegion.dstOffset = 0; // Optional
copyRegion.size = size; copyRegion.size = size;
vkCmdCopyBuffer(m_transferCommandBuffers[0], m_streamingStagingBuffer, destination, 1, &copyRegion); vkCmdCopyBuffer(m_transferCommandBuffers[0], m_streamingStagingBuffer.buffer, destination, 1, &copyRegion);
// TODO - Assert on any needed alignment? // TODO - Assert on any needed alignment?
m_streamingStagingBufferUsage += size; m_streamingStagingBuffer.usage += size;
} }
void KRDevice::streamUpload(void* data, size_t size, Vector2i dimensions, VkImage destination) void KRDevice::streamUpload(void* data, size_t size, Vector2i dimensions, VkImage destination)
{ {
memcpy((uint8_t*)m_streamingStagingBufferData + m_streamingStagingBufferUsage, data, size); memcpy((uint8_t*)m_streamingStagingBuffer.data + m_streamingStagingBuffer.usage, data, size);
// TODO - Refactor memory barriers into helper functions // TODO - Refactor memory barriers into helper functions
@@ -737,7 +717,7 @@ void KRDevice::streamUpload(void* data, size_t size, Vector2i dimensions, VkImag
vkCmdCopyBufferToImage( vkCmdCopyBufferToImage(
m_transferCommandBuffers[0], m_transferCommandBuffers[0],
m_streamingStagingBuffer, m_streamingStagingBuffer.buffer,
destination, destination,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, 1,
@@ -763,7 +743,7 @@ void KRDevice::streamUpload(void* data, size_t size, Vector2i dimensions, VkImag
); );
// TODO - Assert on any needed alignment? // TODO - Assert on any needed alignment?
m_streamingStagingBufferUsage += size; m_streamingStagingBuffer.usage += size;
} }
void KRDevice::streamEnd() void KRDevice::streamEnd()

View File

@@ -86,23 +86,25 @@ public:
std::vector<VkCommandBuffer> m_transferCommandBuffers; std::vector<VkCommandBuffer> m_transferCommandBuffers;
VmaAllocator m_allocator; VmaAllocator m_allocator;
struct StagingBufferInfo {
VkBuffer buffer;
VmaAllocation allocation;
size_t size;
size_t usage;
void* data;
void destroy(VmaAllocator& allocator);
};
// Staging buffer for uploading with the transfer queue // Staging buffer for uploading with the transfer queue
// This will be used for asynchronous asset streaming in the streamer thread. // This will be used for asynchronous asset streaming in the streamer thread.
// TODO - We should allocate at least two of these and double-buffer for increased CPU-GPU concurrency // TODO - We should allocate at least two of these and double-buffer for increased CPU-GPU concurrency
VkBuffer m_streamingStagingBuffer; StagingBufferInfo m_streamingStagingBuffer;
VmaAllocation m_streamingStagingBufferAllocation;
size_t m_streamingStagingBufferSize;
size_t m_streamingStagingBufferUsage;
void* m_streamingStagingBufferData;
// Staging buffer for uploading with the graphics queue // Staging buffer for uploading with the graphics queue
// This will be used for uploading assets procedurally generated while recording the graphics command buffer. // This will be used for uploading assets procedurally generated while recording the graphics command buffer.
// TODO - We should allocate at least two of these and double-buffer for increased CPU-GPU concurrency // TODO - We should allocate at least two of these and double-buffer for increased CPU-GPU concurrency
VkBuffer m_graphicsStagingBuffer; StagingBufferInfo m_graphicsStagingBuffer;
VmaAllocation m_graphicsStagingBufferAllocation;
size_t m_graphicsStagingBufferSize;
size_t m_graphicsStagingBufferUsage;
void* m_graphicsStagingBufferData;
private: private:
void getQueueFamiliesForSharing(uint32_t* queueFamilyIndices, uint32_t* familyCount); void getQueueFamiliesForSharing(uint32_t* queueFamilyIndices, uint32_t* familyCount);
@@ -115,8 +117,7 @@ private:
bool initCommandBuffers(); bool initCommandBuffers();
bool initAllocator(); bool initAllocator();
bool initStagingBuffers(); bool initStagingBuffers();
bool initStagingBuffer(VkDeviceSize size, StagingBufferInfo* info
bool createStagingBuffer(VkDeviceSize size, VkBuffer* buffer, VmaAllocation* allocation, void** data
#if KRENGINE_DEBUG_GPU_LABELS #if KRENGINE_DEBUG_GPU_LABELS
, const char* debug_label , const char* debug_label
#endif // KRENGINE_DEBUG_GPU_LABELS #endif // KRENGINE_DEBUG_GPU_LABELS