Implemented Asynchronous upload (transfer queue) functions in KRDevice.

This commit is contained in:
2022-07-12 00:31:30 -07:00
parent dfde4f876d
commit 7ea1349fb9
2 changed files with 90 additions and 1 deletions

View File

@@ -50,9 +50,13 @@ KRDevice::KRDevice(KRContext& context, const VkPhysicalDevice& device)
, m_streamingStagingBuffer(VK_NULL_HANDLE)
, m_streamingStagingBufferAllocation(VK_NULL_HANDLE)
, 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)
{
}
@@ -64,6 +68,16 @@ KRDevice::~KRDevice()
void KRDevice::destroy()
{
if (m_streamingStagingBufferData) {
vmaUnmapMemory(m_allocator, m_streamingStagingBufferAllocation);
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;
@@ -373,6 +387,12 @@ bool KRDevice::initialize(const std::vector<const char*>& deviceExtensions)
// TODO - Log a warning
return false;
}
VkResult res = vmaMapMemory(m_allocator, m_streamingStagingBufferAllocation, &m_streamingStagingBufferData);
if (res != VK_SUCCESS) {
destroy();
// TODO - Log a warning
return false;
}
// Create Staging Buffer for the graphics queue.
// This will be used for uploading assets procedurally generated while recording the graphics command buffer.
@@ -394,6 +414,12 @@ bool KRDevice::initialize(const std::vector<const char*>& deviceExtensions)
// TODO - Log a warning
return false;
}
res = vmaMapMemory(m_allocator, m_graphicsStagingBufferAllocation, &m_graphicsStagingBufferData);
if (res != VK_SUCCESS) {
destroy();
// TODO - Log a warning
return false;
}
return true;
}
@@ -524,3 +550,54 @@ KrResult KRDevice::selectPresentMode(VkSurfaceKHR& surface, VkPresentModeKHR& se
}
return KR_SUCCESS;
}
void KRDevice::streamStart()
{
VkCommandBufferBeginInfo beginInfo{};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
vkBeginCommandBuffer(m_transferCommandBuffers[0], &beginInfo);
}
size_t KRDevice::streamRemaining() const
{
return m_streamingStagingBufferSize - m_streamingStagingBufferUsage;
}
void KRDevice::streamUpload(KRDataBlock& data, VkBuffer destination)
{
data.lock();
streamUpload(data.getStart(), data.getSize(), destination);
data.unlock();
}
void KRDevice::streamUpload(void* data, size_t size, VkBuffer destination)
{
memcpy((uint8_t*)m_streamingStagingBufferData + m_streamingStagingBufferUsage, data, size);
// TODO - Beneficial to batch many regions in a single call?
VkBufferCopy copyRegion{};
copyRegion.srcOffset = m_streamingStagingBufferUsage;
copyRegion.dstOffset = 0; // Optional
copyRegion.size = size;
vkCmdCopyBuffer(m_transferCommandBuffers[0], m_streamingStagingBuffer, destination, 1, &copyRegion);
// TODO - Assert on any needed alignment?
m_streamingStagingBufferUsage += size;
}
void KRDevice::streamEnd()
{
vkEndCommandBuffer(m_transferCommandBuffers[0]);
// TODO - Should double buffer and use a fence rather than block the thread
VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &m_transferCommandBuffers[0];
vkQueueSubmit(m_transferQueue, 1, &submitInfo, VK_NULL_HANDLE);
vkQueueWaitIdle(m_transferQueue);
}

View File

@@ -34,6 +34,8 @@
#pragma once
class KRDataBlock;
class KRDevice : public KRContextObject
{
public:
@@ -57,6 +59,12 @@ public:
KrResult selectDepthFormat(VkFormat& selectedDepthFormat);
KrResult selectPresentMode(VkSurfaceKHR& surface, VkPresentModeKHR& selectedPresentMode);
void streamStart();
size_t streamRemaining() const;
void streamUpload(KRDataBlock& data, VkBuffer destination);
void streamUpload(void *data, size_t size, VkBuffer destination);
void streamEnd();
VkPhysicalDevice m_device;
VkDevice m_logicalDevice;
VkPhysicalDeviceProperties m_deviceProperties;
@@ -81,6 +89,8 @@ public:
VkBuffer m_streamingStagingBuffer;
VmaAllocation m_streamingStagingBufferAllocation;
size_t m_streamingStagingBufferSize;
size_t m_streamingStagingBufferUsage;
void* m_streamingStagingBufferData;
// Staging buffer for uploading with the graphics queue
// This will be used for uploading assets procedurally generated while recording the graphics command buffer.
@@ -88,5 +98,7 @@ public:
VkBuffer m_graphicsStagingBuffer;
VmaAllocation m_graphicsStagingBufferAllocation;
size_t m_graphicsStagingBufferSize;
size_t m_graphicsStagingBufferUsage;
void* m_graphicsStagingBufferData;
private:
};