mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 06:53:58 +00:00
- implement queue family transfers
This commit is contained in:
parent
651d749eea
commit
88355393df
6 changed files with 201 additions and 66 deletions
|
@ -347,7 +347,7 @@ VkPPTexture::VkPPTexture(PPTexture *texture)
|
||||||
|
|
||||||
PipelineBarrier barrier0;
|
PipelineBarrier barrier0;
|
||||||
barrier0.addImage(Image.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT);
|
barrier0.addImage(Image.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||||
barrier0.execute(fb->GetUploadCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
barrier0.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||||
|
|
||||||
void *data = Staging->Map(0, totalsize);
|
void *data = Staging->Map(0, totalsize);
|
||||||
memcpy(data, texture->Data.get(), totalsize);
|
memcpy(data, texture->Data.get(), totalsize);
|
||||||
|
@ -359,18 +359,26 @@ VkPPTexture::VkPPTexture(PPTexture *texture)
|
||||||
region.imageExtent.depth = 1;
|
region.imageExtent.depth = 1;
|
||||||
region.imageExtent.width = texture->Width;
|
region.imageExtent.width = texture->Width;
|
||||||
region.imageExtent.height = texture->Height;
|
region.imageExtent.height = texture->Height;
|
||||||
fb->GetUploadCommands()->copyBufferToImage(Staging->buffer, Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
fb->GetTransferCommands()->copyBufferToImage(Staging->buffer, Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||||
|
|
||||||
PipelineBarrier barrier1;
|
PipelineBarrier barrier1;
|
||||||
barrier1.addImage(Image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
|
barrier1.addImage(Image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||||
barrier1.execute(fb->GetUploadCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
barrier1.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
Layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
Layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
|
||||||
|
if (fb->device->transferFamily != fb->device->graphicsFamily)
|
||||||
|
{
|
||||||
|
PipelineBarrier transfer;
|
||||||
|
transfer.addQueueTransfer(fb->device->transferFamily, fb->device->graphicsFamily, Image.get(), Layout);
|
||||||
|
transfer.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
transfer.execute(fb->GetPreDrawCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PipelineBarrier barrier;
|
PipelineBarrier barrier;
|
||||||
barrier.addImage(Image.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
|
barrier.addImage(Image.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
|
||||||
barrier.execute(fb->GetUploadCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
barrier.execute(fb->GetPreDrawCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||||
Layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
Layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,15 @@ void VKBuffer::SetData(size_t size, const void *data, bool staticdata)
|
||||||
memcpy(dst, data, size);
|
memcpy(dst, data, size);
|
||||||
mStaging->Unmap();
|
mStaging->Unmap();
|
||||||
|
|
||||||
fb->GetUploadCommands()->copyBuffer(mStaging.get(), mBuffer.get());
|
fb->GetTransferCommands()->copyBuffer(mStaging.get(), mBuffer.get());
|
||||||
|
|
||||||
|
if (fb->device->transferFamily != fb->device->graphicsFamily)
|
||||||
|
{
|
||||||
|
PipelineBarrier transfer;
|
||||||
|
transfer.addQueueTransfer(fb->device->transferFamily, fb->device->graphicsFamily, mBuffer.get(), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_SHADER_READ_BIT);
|
||||||
|
transfer.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
transfer.execute(fb->GetPreDrawCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -78,7 +86,22 @@ void VKBuffer::SetSubData(size_t offset, size_t size, const void *data)
|
||||||
memcpy(dst, data, size);
|
memcpy(dst, data, size);
|
||||||
mStaging->Unmap();
|
mStaging->Unmap();
|
||||||
|
|
||||||
fb->GetUploadCommands()->copyBuffer(mStaging.get(), mBuffer.get(), offset, offset, size);
|
if (fb->device->transferFamily != fb->device->graphicsFamily)
|
||||||
|
{
|
||||||
|
PipelineBarrier transfer;
|
||||||
|
transfer.addQueueTransfer(fb->device->graphicsFamily, fb->device->transferFamily, mBuffer.get(), VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_SHADER_READ_BIT, 0);
|
||||||
|
transfer.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
fb->GetTransferCommands()->copyBuffer(mStaging.get(), mBuffer.get(), offset, offset, size);
|
||||||
|
|
||||||
|
if (fb->device->transferFamily != fb->device->graphicsFamily)
|
||||||
|
{
|
||||||
|
PipelineBarrier transfer;
|
||||||
|
transfer.addQueueTransfer(fb->device->transferFamily, fb->device->graphicsFamily, mBuffer.get(), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_SHADER_READ_BIT);
|
||||||
|
transfer.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
transfer.execute(fb->GetPreDrawCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -292,6 +292,8 @@ public:
|
||||||
void addBuffer(VulkanBuffer *buffer, VkDeviceSize offset, VkDeviceSize size, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
|
void addBuffer(VulkanBuffer *buffer, VkDeviceSize offset, VkDeviceSize size, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
|
||||||
void addImage(VulkanImage *image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
|
void addImage(VulkanImage *image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
|
||||||
void addImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
|
void addImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
|
||||||
|
void addQueueTransfer(int srcFamily, int dstFamily, VulkanBuffer *buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
|
||||||
|
void addQueueTransfer(int srcFamily, int dstFamily, VulkanImage *image, VkImageLayout layout, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
|
||||||
|
|
||||||
void execute(VulkanCommandBuffer *commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags = 0);
|
void execute(VulkanCommandBuffer *commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags = 0);
|
||||||
|
|
||||||
|
@ -301,6 +303,24 @@ private:
|
||||||
FixedSizeVector<VkImageMemoryBarrier, 8> imageMemoryBarriers;
|
FixedSizeVector<VkImageMemoryBarrier, 8> imageMemoryBarriers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QueueSubmit
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QueueSubmit();
|
||||||
|
|
||||||
|
void addCommandBuffer(VulkanCommandBuffer *buffer);
|
||||||
|
void addWait(VkPipelineStageFlags waitStageMask, VulkanSemaphore *semaphore);
|
||||||
|
void addSignal(VulkanSemaphore *semaphore);
|
||||||
|
void execute(VulkanDevice *device, VkQueue queue, VulkanFence *fence = nullptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
VkSubmitInfo submitInfo = {};
|
||||||
|
FixedSizeVector<VkSemaphore, 8> waitSemaphores;
|
||||||
|
FixedSizeVector<VkPipelineStageFlags, 8> waitStages;
|
||||||
|
FixedSizeVector<VkSemaphore, 8> signalSemaphores;
|
||||||
|
FixedSizeVector<VkCommandBuffer, 8> commandBuffers;
|
||||||
|
};
|
||||||
|
|
||||||
class WriteDescriptors
|
class WriteDescriptors
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -1140,6 +1160,37 @@ inline void PipelineBarrier::addImage(VkImage image, VkImageLayout oldLayout, Vk
|
||||||
imageMemoryBarriers.push_back(barrier);
|
imageMemoryBarriers.push_back(barrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void PipelineBarrier::addQueueTransfer(int srcFamily, int dstFamily, VulkanBuffer *buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask)
|
||||||
|
{
|
||||||
|
VkBufferMemoryBarrier barrier = { };
|
||||||
|
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||||
|
barrier.srcAccessMask = srcAccessMask;
|
||||||
|
barrier.dstAccessMask = dstAccessMask;
|
||||||
|
barrier.srcQueueFamilyIndex = srcFamily;
|
||||||
|
barrier.dstQueueFamilyIndex = dstFamily;
|
||||||
|
barrier.buffer = buffer->buffer;
|
||||||
|
barrier.offset = 0;
|
||||||
|
barrier.size = buffer->size;
|
||||||
|
bufferMemoryBarriers.push_back(barrier);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void PipelineBarrier::addQueueTransfer(int srcFamily, int dstFamily, VulkanImage *image, VkImageLayout layout, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount)
|
||||||
|
{
|
||||||
|
VkImageMemoryBarrier barrier = { };
|
||||||
|
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||||
|
barrier.oldLayout = layout;
|
||||||
|
barrier.newLayout = layout;
|
||||||
|
barrier.srcQueueFamilyIndex = srcFamily;
|
||||||
|
barrier.dstQueueFamilyIndex = dstFamily;
|
||||||
|
barrier.image = image->image;
|
||||||
|
barrier.subresourceRange.aspectMask = aspectMask;
|
||||||
|
barrier.subresourceRange.baseMipLevel = baseMipLevel;
|
||||||
|
barrier.subresourceRange.levelCount = levelCount;
|
||||||
|
barrier.subresourceRange.baseArrayLayer = 0;
|
||||||
|
barrier.subresourceRange.layerCount = 1;
|
||||||
|
imageMemoryBarriers.push_back(barrier);
|
||||||
|
}
|
||||||
|
|
||||||
inline void PipelineBarrier::execute(VulkanCommandBuffer *commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags)
|
inline void PipelineBarrier::execute(VulkanCommandBuffer *commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags)
|
||||||
{
|
{
|
||||||
commandBuffer->pipelineBarrier(
|
commandBuffer->pipelineBarrier(
|
||||||
|
@ -1151,6 +1202,44 @@ inline void PipelineBarrier::execute(VulkanCommandBuffer *commandBuffer, VkPipel
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline QueueSubmit::QueueSubmit()
|
||||||
|
{
|
||||||
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void QueueSubmit::addCommandBuffer(VulkanCommandBuffer *buffer)
|
||||||
|
{
|
||||||
|
commandBuffers.push_back(buffer->buffer);
|
||||||
|
submitInfo.pCommandBuffers = commandBuffers.data();
|
||||||
|
submitInfo.commandBufferCount = (uint32_t)commandBuffers.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void QueueSubmit::addWait(VkPipelineStageFlags waitStageMask, VulkanSemaphore *semaphore)
|
||||||
|
{
|
||||||
|
waitStages.push_back(waitStageMask);
|
||||||
|
waitSemaphores.push_back(semaphore->semaphore);
|
||||||
|
|
||||||
|
submitInfo.pWaitDstStageMask = waitStages.data();
|
||||||
|
submitInfo.pWaitSemaphores = waitSemaphores.data();
|
||||||
|
submitInfo.waitSemaphoreCount = (uint32_t)waitSemaphores.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void QueueSubmit::addSignal(VulkanSemaphore *semaphore)
|
||||||
|
{
|
||||||
|
signalSemaphores.push_back(semaphore->semaphore);
|
||||||
|
submitInfo.pSignalSemaphores = signalSemaphores.data();
|
||||||
|
submitInfo.signalSemaphoreCount = (uint32_t)signalSemaphores.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void QueueSubmit::execute(VulkanDevice *device, VkQueue queue, VulkanFence *fence)
|
||||||
|
{
|
||||||
|
VkResult result = vkQueueSubmit(device->graphicsQueue, 1, &submitInfo, fence ? fence->fence : VK_NULL_HANDLE);
|
||||||
|
if (result < VK_SUCCESS)
|
||||||
|
throw std::runtime_error("Failed to submit command buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
inline void WriteDescriptors::addBuffer(VulkanDescriptorSet *descriptorSet, int binding, VkDescriptorType type, VulkanBuffer *buffer)
|
inline void WriteDescriptors::addBuffer(VulkanDescriptorSet *descriptorSet, int binding, VkDescriptorType type, VulkanBuffer *buffer)
|
||||||
{
|
{
|
||||||
addBuffer(descriptorSet, binding, type, buffer, 0, buffer->size);
|
addBuffer(descriptorSet, binding, type, buffer, 0, buffer->size);
|
||||||
|
|
|
@ -118,8 +118,10 @@ void VulkanFrameBuffer::InitializeState()
|
||||||
uniformblockalignment = (unsigned int)device->PhysicalDevice.Properties.limits.minUniformBufferOffsetAlignment;
|
uniformblockalignment = (unsigned int)device->PhysicalDevice.Properties.limits.minUniformBufferOffsetAlignment;
|
||||||
maxuniformblock = device->PhysicalDevice.Properties.limits.maxUniformBufferRange;
|
maxuniformblock = device->PhysicalDevice.Properties.limits.maxUniformBufferRange;
|
||||||
|
|
||||||
mUploadSemaphore.reset(new VulkanSemaphore(device));
|
mTransferSemaphore.reset(new VulkanSemaphore(device));
|
||||||
|
mPreDrawSemaphore.reset(new VulkanSemaphore(device));
|
||||||
mGraphicsCommandPool.reset(new VulkanCommandPool(device, device->graphicsFamily));
|
mGraphicsCommandPool.reset(new VulkanCommandPool(device, device->graphicsFamily));
|
||||||
|
mTransferCommandPool.reset(new VulkanCommandPool(device, device->transferFamily));
|
||||||
|
|
||||||
mScreenBuffers.reset(new VkRenderBuffers());
|
mScreenBuffers.reset(new VkRenderBuffers());
|
||||||
mSaveBuffers.reset(new VkRenderBuffers());
|
mSaveBuffers.reset(new VkRenderBuffers());
|
||||||
|
@ -206,7 +208,8 @@ void VulkanFrameBuffer::Update()
|
||||||
vkResetFences(device->device, 1, &mRenderFinishedFence->fence);
|
vkResetFences(device->device, 1, &mRenderFinishedFence->fence);
|
||||||
|
|
||||||
mDrawCommands.reset();
|
mDrawCommands.reset();
|
||||||
mUploadCommands.reset();
|
mTransferCommands.reset();
|
||||||
|
mPreDrawCommands.reset();
|
||||||
DeleteFrameObjects();
|
DeleteFrameObjects();
|
||||||
|
|
||||||
Finish.Unclock();
|
Finish.Unclock();
|
||||||
|
@ -224,62 +227,50 @@ void VulkanFrameBuffer::DeleteFrameObjects()
|
||||||
|
|
||||||
void VulkanFrameBuffer::SubmitCommands(bool finish)
|
void VulkanFrameBuffer::SubmitCommands(bool finish)
|
||||||
{
|
{
|
||||||
|
if (mTransferCommands)
|
||||||
|
{
|
||||||
|
mTransferCommands->end();
|
||||||
|
|
||||||
|
QueueSubmit submit;
|
||||||
|
submit.addCommandBuffer(mTransferCommands.get());
|
||||||
|
submit.addSignal(mTransferSemaphore.get());
|
||||||
|
submit.execute(device, device->transferQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPreDrawCommands)
|
||||||
|
{
|
||||||
|
mPreDrawCommands->end();
|
||||||
|
|
||||||
|
QueueSubmit submit;
|
||||||
|
submit.addCommandBuffer(mPreDrawCommands.get());
|
||||||
|
if (mTransferCommands)
|
||||||
|
submit.addWait(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, mTransferSemaphore.get());
|
||||||
|
submit.addSignal(mPreDrawSemaphore.get());
|
||||||
|
submit.execute(device, device->graphicsQueue);
|
||||||
|
}
|
||||||
|
|
||||||
mDrawCommands->end();
|
mDrawCommands->end();
|
||||||
|
|
||||||
if (mUploadCommands)
|
QueueSubmit submit;
|
||||||
|
submit.addCommandBuffer(mDrawCommands.get());
|
||||||
|
if (mPreDrawCommands)
|
||||||
|
submit.addWait(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, mPreDrawSemaphore.get());
|
||||||
|
else if (mTransferCommands)
|
||||||
|
submit.addWait(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, mTransferSemaphore.get());
|
||||||
|
if (finish)
|
||||||
{
|
{
|
||||||
mUploadCommands->end();
|
submit.addWait(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, mSwapChainImageAvailableSemaphore.get());
|
||||||
|
submit.addSignal(mRenderFinishedSemaphore.get());
|
||||||
// Submit upload commands immediately
|
|
||||||
VkSubmitInfo submitInfo = {};
|
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
||||||
submitInfo.commandBufferCount = 1;
|
|
||||||
submitInfo.pCommandBuffers = &mUploadCommands->buffer;
|
|
||||||
submitInfo.signalSemaphoreCount = 1;
|
|
||||||
submitInfo.pSignalSemaphores = &mUploadSemaphore->semaphore;
|
|
||||||
VkResult result = vkQueueSubmit(device->graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
|
|
||||||
if (result < VK_SUCCESS)
|
|
||||||
I_FatalError("Failed to submit command buffer! Error %d\n", result);
|
|
||||||
|
|
||||||
// Wait for upload commands to finish, then submit render commands
|
|
||||||
VkSemaphore waitSemaphores[] = { mUploadSemaphore->semaphore, mSwapChainImageAvailableSemaphore->semaphore };
|
|
||||||
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
|
||||||
submitInfo.waitSemaphoreCount = finish ? 2 : 1;
|
|
||||||
submitInfo.pWaitSemaphores = waitSemaphores;
|
|
||||||
submitInfo.pWaitDstStageMask = waitStages;
|
|
||||||
submitInfo.commandBufferCount = 1;
|
|
||||||
submitInfo.pCommandBuffers = &mDrawCommands->buffer;
|
|
||||||
submitInfo.signalSemaphoreCount = finish ? 1 : 0;
|
|
||||||
submitInfo.pSignalSemaphores = &mRenderFinishedSemaphore->semaphore;
|
|
||||||
result = vkQueueSubmit(device->graphicsQueue, 1, &submitInfo, mRenderFinishedFence->fence);
|
|
||||||
if (result < VK_SUCCESS)
|
|
||||||
I_FatalError("Failed to submit command buffer! Error %d\n", result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VkSemaphore waitSemaphores[] = { mSwapChainImageAvailableSemaphore->semaphore };
|
|
||||||
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
|
||||||
|
|
||||||
VkSubmitInfo submitInfo = {};
|
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
||||||
submitInfo.waitSemaphoreCount = finish ? 1 : 0;
|
|
||||||
submitInfo.pWaitSemaphores = waitSemaphores;
|
|
||||||
submitInfo.pWaitDstStageMask = waitStages;
|
|
||||||
submitInfo.commandBufferCount = 1;
|
|
||||||
submitInfo.pCommandBuffers = &mDrawCommands->buffer;
|
|
||||||
submitInfo.signalSemaphoreCount = finish ? 1 : 0;
|
|
||||||
submitInfo.pSignalSemaphores = &mRenderFinishedSemaphore->semaphore;
|
|
||||||
VkResult result = vkQueueSubmit(device->graphicsQueue, 1, &submitInfo, mRenderFinishedFence->fence);
|
|
||||||
if (result < VK_SUCCESS)
|
|
||||||
I_FatalError("Failed to submit command buffer! Error %d\n", result);
|
|
||||||
}
|
}
|
||||||
|
submit.execute(device, device->graphicsQueue, mRenderFinishedFence.get());
|
||||||
|
|
||||||
if (!finish)
|
if (!finish)
|
||||||
{
|
{
|
||||||
vkWaitForFences(device->device, 1, &mRenderFinishedFence->fence, VK_TRUE, std::numeric_limits<uint64_t>::max());
|
vkWaitForFences(device->device, 1, &mRenderFinishedFence->fence, VK_TRUE, std::numeric_limits<uint64_t>::max());
|
||||||
vkResetFences(device->device, 1, &mRenderFinishedFence->fence);
|
vkResetFences(device->device, 1, &mRenderFinishedFence->fence);
|
||||||
mDrawCommands.reset();
|
mDrawCommands.reset();
|
||||||
mUploadCommands.reset();
|
mTransferCommands.reset();
|
||||||
|
mPreDrawCommands.reset();
|
||||||
DeleteFrameObjects();
|
DeleteFrameObjects();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -794,15 +785,26 @@ void VulkanFrameBuffer::Draw2D()
|
||||||
::Draw2D(&m2DDrawer, *mRenderState);
|
::Draw2D(&m2DDrawer, *mRenderState);
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanCommandBuffer *VulkanFrameBuffer::GetUploadCommands()
|
VulkanCommandBuffer *VulkanFrameBuffer::GetTransferCommands()
|
||||||
{
|
{
|
||||||
if (!mUploadCommands)
|
if (!mTransferCommands)
|
||||||
{
|
{
|
||||||
mUploadCommands = mGraphicsCommandPool->createBuffer();
|
mTransferCommands = mTransferCommandPool->createBuffer();
|
||||||
mUploadCommands->SetDebugName("VulkanFrameBuffer.mUploadCommands");
|
mTransferCommands->SetDebugName("VulkanFrameBuffer.mTransferCommands");
|
||||||
mUploadCommands->begin();
|
mTransferCommands->begin();
|
||||||
}
|
}
|
||||||
return mUploadCommands.get();
|
return mTransferCommands.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
VulkanCommandBuffer *VulkanFrameBuffer::GetPreDrawCommands()
|
||||||
|
{
|
||||||
|
if (!mPreDrawCommands)
|
||||||
|
{
|
||||||
|
mPreDrawCommands = mGraphicsCommandPool->createBuffer();
|
||||||
|
mPreDrawCommands->SetDebugName("VulkanFrameBuffer.mPreDrawCommands");
|
||||||
|
mPreDrawCommands->begin();
|
||||||
|
}
|
||||||
|
return mPreDrawCommands.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanCommandBuffer *VulkanFrameBuffer::GetDrawCommands()
|
VulkanCommandBuffer *VulkanFrameBuffer::GetDrawCommands()
|
||||||
|
|
|
@ -25,7 +25,8 @@ public:
|
||||||
std::unique_ptr<VulkanSwapChain> swapChain;
|
std::unique_ptr<VulkanSwapChain> swapChain;
|
||||||
uint32_t presentImageIndex = 0;
|
uint32_t presentImageIndex = 0;
|
||||||
|
|
||||||
VulkanCommandBuffer *GetUploadCommands();
|
VulkanCommandBuffer *GetTransferCommands();
|
||||||
|
VulkanCommandBuffer *GetPreDrawCommands();
|
||||||
VulkanCommandBuffer *GetDrawCommands();
|
VulkanCommandBuffer *GetDrawCommands();
|
||||||
VkShaderManager *GetShaderManager() { return mShaderManager.get(); }
|
VkShaderManager *GetShaderManager() { return mShaderManager.get(); }
|
||||||
VkSamplerManager *GetSamplerManager() { return mSamplerManager.get(); }
|
VkSamplerManager *GetSamplerManager() { return mSamplerManager.get(); }
|
||||||
|
@ -114,9 +115,12 @@ private:
|
||||||
std::unique_ptr<VkPostprocess> mPostprocess;
|
std::unique_ptr<VkPostprocess> mPostprocess;
|
||||||
std::unique_ptr<VkRenderPassManager> mRenderPassManager;
|
std::unique_ptr<VkRenderPassManager> mRenderPassManager;
|
||||||
std::unique_ptr<VulkanCommandPool> mGraphicsCommandPool;
|
std::unique_ptr<VulkanCommandPool> mGraphicsCommandPool;
|
||||||
std::unique_ptr<VulkanCommandBuffer> mUploadCommands;
|
std::unique_ptr<VulkanCommandPool> mTransferCommandPool;
|
||||||
|
std::unique_ptr<VulkanCommandBuffer> mTransferCommands;
|
||||||
|
std::unique_ptr<VulkanCommandBuffer> mPreDrawCommands;
|
||||||
std::unique_ptr<VulkanCommandBuffer> mDrawCommands;
|
std::unique_ptr<VulkanCommandBuffer> mDrawCommands;
|
||||||
std::unique_ptr<VulkanSemaphore> mUploadSemaphore;
|
std::unique_ptr<VulkanSemaphore> mTransferSemaphore;
|
||||||
|
std::unique_ptr<VulkanSemaphore> mPreDrawSemaphore;
|
||||||
std::unique_ptr<VkRenderState> mRenderState;
|
std::unique_ptr<VkRenderState> mRenderState;
|
||||||
|
|
||||||
std::unique_ptr<VulkanSemaphore> mSwapChainImageAvailableSemaphore;
|
std::unique_ptr<VulkanSemaphore> mSwapChainImageAvailableSemaphore;
|
||||||
|
|
|
@ -195,7 +195,7 @@ void VkHardwareTexture::CreateImage(FTexture *tex, int translation, int flags)
|
||||||
mImageView = viewbuilder.create(fb->device);
|
mImageView = viewbuilder.create(fb->device);
|
||||||
mImageView->SetDebugName("VkHardwareTexture.mImageView");
|
mImageView->SetDebugName("VkHardwareTexture.mImageView");
|
||||||
|
|
||||||
auto cmdbuffer = fb->GetUploadCommands();
|
auto cmdbuffer = fb->GetPreDrawCommands();
|
||||||
|
|
||||||
PipelineBarrier imageTransition;
|
PipelineBarrier imageTransition;
|
||||||
imageTransition.addImage(mImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0, VK_ACCESS_SHADER_READ_BIT);
|
imageTransition.addImage(mImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0, VK_ACCESS_SHADER_READ_BIT);
|
||||||
|
@ -231,7 +231,7 @@ void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat form
|
||||||
mImageView = viewbuilder.create(fb->device);
|
mImageView = viewbuilder.create(fb->device);
|
||||||
mImageView->SetDebugName("VkHardwareTexture.mImageView");
|
mImageView->SetDebugName("VkHardwareTexture.mImageView");
|
||||||
|
|
||||||
auto cmdbuffer = fb->GetUploadCommands();
|
auto cmdbuffer = fb->GetTransferCommands();
|
||||||
|
|
||||||
PipelineBarrier imageTransition0;
|
PipelineBarrier imageTransition0;
|
||||||
imageTransition0.addImage(mImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT);
|
imageTransition0.addImage(mImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||||
|
@ -289,6 +289,15 @@ void VkHardwareTexture::GenerateMipmaps(VulkanImage *image, VulkanCommandBuffer
|
||||||
PipelineBarrier barrier2;
|
PipelineBarrier barrier2;
|
||||||
barrier2.addImage(image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i - 1);
|
barrier2.addImage(image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i - 1);
|
||||||
barrier2.execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
barrier2.execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
|
||||||
|
auto fb = GetVulkanFrameBuffer();
|
||||||
|
if (fb->device->transferFamily != fb->device->graphicsFamily)
|
||||||
|
{
|
||||||
|
PipelineBarrier transfer;
|
||||||
|
transfer.addQueueTransfer(fb->device->transferFamily, fb->device->graphicsFamily, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT, 0, GetMipLevels(image->width, image->height));
|
||||||
|
transfer.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
transfer.execute(fb->GetPreDrawCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int VkHardwareTexture::GetMipLevels(int w, int h)
|
int VkHardwareTexture::GetMipLevels(int w, int h)
|
||||||
|
@ -326,7 +335,7 @@ void VkHardwareTexture::AllocateBuffer(int w, int h, int texelsize)
|
||||||
mImageView = viewbuilder.create(fb->device);
|
mImageView = viewbuilder.create(fb->device);
|
||||||
mImageView->SetDebugName("VkHardwareTexture.mImageView");
|
mImageView->SetDebugName("VkHardwareTexture.mImageView");
|
||||||
|
|
||||||
auto cmdbuffer = fb->GetUploadCommands();
|
auto cmdbuffer = fb->GetPreDrawCommands();
|
||||||
|
|
||||||
PipelineBarrier imageTransition;
|
PipelineBarrier imageTransition;
|
||||||
imageTransition.addImage(mImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, mImageLayout, 0, VK_ACCESS_SHADER_READ_BIT);
|
imageTransition.addImage(mImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, mImageLayout, 0, VK_ACCESS_SHADER_READ_BIT);
|
||||||
|
|
Loading…
Reference in a new issue