Added KRDevice::StagingBufferInfo to collect staging buffer related members and functions
This commit is contained in:
@@ -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, ©Region);
|
vkCmdCopyBuffer(m_transferCommandBuffers[0], m_streamingStagingBuffer.buffer, destination, 1, ©Region);
|
||||||
|
|
||||||
// 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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user