Implemented Asynchronous upload (transfer queue) functions in KRDevice.
This commit is contained in:
@@ -50,9 +50,13 @@ KRDevice::KRDevice(KRContext& context, const VkPhysicalDevice& device)
|
|||||||
, m_streamingStagingBuffer(VK_NULL_HANDLE)
|
, m_streamingStagingBuffer(VK_NULL_HANDLE)
|
||||||
, m_streamingStagingBufferAllocation(VK_NULL_HANDLE)
|
, m_streamingStagingBufferAllocation(VK_NULL_HANDLE)
|
||||||
, m_streamingStagingBufferSize(0)
|
, m_streamingStagingBufferSize(0)
|
||||||
|
, m_streamingStagingBufferUsage(0)
|
||||||
|
, m_streamingStagingBufferData(nullptr)
|
||||||
, m_graphicsStagingBuffer(VK_NULL_HANDLE)
|
, m_graphicsStagingBuffer(VK_NULL_HANDLE)
|
||||||
, m_graphicsStagingBufferAllocation(VK_NULL_HANDLE)
|
, m_graphicsStagingBufferAllocation(VK_NULL_HANDLE)
|
||||||
, m_graphicsStagingBufferSize(0)
|
, m_graphicsStagingBufferSize(0)
|
||||||
|
, m_graphicsStagingBufferUsage(0)
|
||||||
|
, m_graphicsStagingBufferData(nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -64,6 +68,16 @@ KRDevice::~KRDevice()
|
|||||||
|
|
||||||
void KRDevice::destroy()
|
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) {
|
if (m_streamingStagingBuffer) {
|
||||||
vmaDestroyBuffer(m_allocator, m_streamingStagingBuffer, m_streamingStagingBufferAllocation);
|
vmaDestroyBuffer(m_allocator, m_streamingStagingBuffer, m_streamingStagingBufferAllocation);
|
||||||
m_streamingStagingBufferSize = 0;
|
m_streamingStagingBufferSize = 0;
|
||||||
@@ -373,6 +387,12 @@ bool KRDevice::initialize(const std::vector<const char*>& deviceExtensions)
|
|||||||
// TODO - Log a warning
|
// TODO - Log a warning
|
||||||
return false;
|
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.
|
// Create Staging Buffer for 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.
|
||||||
@@ -394,6 +414,12 @@ bool KRDevice::initialize(const std::vector<const char*>& deviceExtensions)
|
|||||||
// TODO - Log a warning
|
// TODO - Log a warning
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
res = vmaMapMemory(m_allocator, m_graphicsStagingBufferAllocation, &m_graphicsStagingBufferData);
|
||||||
|
if (res != VK_SUCCESS) {
|
||||||
|
destroy();
|
||||||
|
// TODO - Log a warning
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -524,3 +550,54 @@ KrResult KRDevice::selectPresentMode(VkSurfaceKHR& surface, VkPresentModeKHR& se
|
|||||||
}
|
}
|
||||||
return KR_SUCCESS;
|
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, ©Region);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
class KRDataBlock;
|
||||||
|
|
||||||
class KRDevice : public KRContextObject
|
class KRDevice : public KRContextObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -57,6 +59,12 @@ public:
|
|||||||
KrResult selectDepthFormat(VkFormat& selectedDepthFormat);
|
KrResult selectDepthFormat(VkFormat& selectedDepthFormat);
|
||||||
KrResult selectPresentMode(VkSurfaceKHR& surface, VkPresentModeKHR& selectedPresentMode);
|
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;
|
VkPhysicalDevice m_device;
|
||||||
VkDevice m_logicalDevice;
|
VkDevice m_logicalDevice;
|
||||||
VkPhysicalDeviceProperties m_deviceProperties;
|
VkPhysicalDeviceProperties m_deviceProperties;
|
||||||
@@ -81,6 +89,8 @@ public:
|
|||||||
VkBuffer m_streamingStagingBuffer;
|
VkBuffer m_streamingStagingBuffer;
|
||||||
VmaAllocation m_streamingStagingBufferAllocation;
|
VmaAllocation m_streamingStagingBufferAllocation;
|
||||||
size_t m_streamingStagingBufferSize;
|
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.
|
||||||
@@ -88,5 +98,7 @@ public:
|
|||||||
VkBuffer m_graphicsStagingBuffer;
|
VkBuffer m_graphicsStagingBuffer;
|
||||||
VmaAllocation m_graphicsStagingBufferAllocation;
|
VmaAllocation m_graphicsStagingBufferAllocation;
|
||||||
size_t m_graphicsStagingBufferSize;
|
size_t m_graphicsStagingBufferSize;
|
||||||
|
size_t m_graphicsStagingBufferUsage;
|
||||||
|
void* m_graphicsStagingBufferData;
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user