- implement queue family transfers

This commit is contained in:
Magnus Norddahl 2019-03-24 18:03:10 +01:00
parent 651d749eea
commit 88355393df
6 changed files with 201 additions and 66 deletions

View file

@ -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, &region); fb->GetTransferCommands()->copyBufferToImage(Staging->buffer, Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
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;
} }
} }

View file

@ -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
{ {

View file

@ -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);

View file

@ -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()

View file

@ -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;

View file

@ -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);