diff --git a/src/mln/vulkan/renderable_resource.cpp b/src/mln/vulkan/renderable_resource.cpp index c3c4914f6..1133205b2 100644 --- a/src/mln/vulkan/renderable_resource.cpp +++ b/src/mln/vulkan/renderable_resource.cpp @@ -510,22 +510,23 @@ void SurfaceRenderableResource::copySurfaceToReadTexture() { auto& commandBuffer = contextImpl.getCommandBuffer(); const auto oldLayout = surface ? vk::ImageLayout::ePresentSrcKHR : vk::ImageLayout::eTransferSrcOptimal; - const auto srcStage = vk::PipelineStageFlagBits::eColorAttachmentOutput; - const vk::AccessFlags srcAccess = vk::AccessFlagBits::eColorAttachmentWrite; - const vk::AccessFlags dstAccess = vk::AccessFlagBits::eTransferRead; - const auto readBarrier = vk::ImageMemoryBarrier() .setImage(swapchainImage) .setOldLayout(oldLayout) .setNewLayout(vk::ImageLayout::eTransferSrcOptimal) - .setSrcAccessMask(srcAccess) - .setDstAccessMask(dstAccess) + .setSrcAccessMask(vk::AccessFlagBits::eColorAttachmentWrite) + .setDstAccessMask(vk::AccessFlagBits::eTransferRead) .setSrcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED) .setDstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED) .setSubresourceRange({vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}); - commandBuffer->pipelineBarrier( - srcStage, vk::PipelineStageFlagBits::eTransfer, {}, nullptr, nullptr, readBarrier, dispatcher); + commandBuffer->pipelineBarrier(vk::PipelineStageFlagBits::eColorAttachmentOutput, + vk::PipelineStageFlagBits::eTransfer, + {}, + nullptr, + nullptr, + readBarrier, + dispatcher); bool useBlit = surface && @@ -545,14 +546,14 @@ void SurfaceRenderableResource::copySurfaceToReadTexture() { .setImage(swapchainImage) .setOldLayout(vk::ImageLayout::eTransferSrcOptimal) .setNewLayout(vk::ImageLayout::ePresentSrcKHR) - .setSrcAccessMask(vk::AccessFlagBits::eMemoryRead) - .setDstAccessMask(vk::AccessFlagBits::eTransferWrite) + .setSrcAccessMask(vk::AccessFlagBits::eTransferRead) + .setDstAccessMask({}) .setSrcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED) .setDstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED) .setSubresourceRange({vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}); - commandBuffer->pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, - vk::PipelineStageFlagBits::eTransfer, + commandBuffer->pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, + vk::PipelineStageFlagBits::eBottomOfPipe, {}, nullptr, nullptr, diff --git a/src/mln/vulkan/texture2d.cpp b/src/mln/vulkan/texture2d.cpp index cc6f48862..66d0e4555 100644 --- a/src/mln/vulkan/texture2d.cpp +++ b/src/mln/vulkan/texture2d.cpp @@ -466,17 +466,32 @@ void Texture2D::destroySampler(bool deferred) { } void Texture2D::transitionToTransferWriteLayout(const vk::UniqueCommandBuffer& buffer) { - const auto barrier = vk::ImageMemoryBarrier() - .setImage(imageAllocation->image) - .setOldLayout(imageLayout) - .setNewLayout(vk::ImageLayout::eTransferDstOptimal) - .setSrcAccessMask({}) - .setDstAccessMask(vk::AccessFlagBits::eTransferWrite) - .setSrcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED) - .setDstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED) - .setSubresourceRange({vk::ImageAspectFlagBits::eColor, 0, getMipLevels(), 0, 1}); + auto barrier = vk::ImageMemoryBarrier() + .setImage(imageAllocation->image) + .setOldLayout(imageLayout) + .setNewLayout(vk::ImageLayout::eTransferDstOptimal) + .setSrcAccessMask({}) + .setDstAccessMask(vk::AccessFlagBits::eTransferWrite) + .setSrcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED) + .setDstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED) + .setSubresourceRange({vk::ImageAspectFlagBits::eColor, 0, getMipLevels(), 0, 1}); - buffer->pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, + vk::PipelineStageFlags srcMask = vk::PipelineStageFlagBits::eTopOfPipe; + + if (imageLayout == vk::ImageLayout::eUndefined) { + barrier.setSrcAccessMask({}); + srcMask = vk::PipelineStageFlagBits::eTopOfPipe; + } else if (imageLayout == vk::ImageLayout::eShaderReadOnlyOptimal) { + barrier.setSrcAccessMask(vk::AccessFlagBits::eShaderRead); + srcMask = vk::PipelineStageFlagBits::eFragmentShader; + } else if (imageLayout == vk::ImageLayout::eGeneral) { + barrier.setSrcAccessMask(vk::AccessFlagBits::eTransferWrite); + srcMask = vk::PipelineStageFlagBits::eTransfer; + } else { + assert(false); + } + + buffer->pipelineBarrier(srcMask, vk::PipelineStageFlagBits::eTransfer, {}, nullptr, @@ -488,6 +503,8 @@ void Texture2D::transitionToTransferWriteLayout(const vk::UniqueCommandBuffer& b } void Texture2D::transitionToTransferReadLayout(const vk::UniqueCommandBuffer& buffer) { + assert(imageLayout == vk::ImageLayout::eTransferDstOptimal); + const auto barrier = vk::ImageMemoryBarrier() .setImage(imageAllocation->image) .setOldLayout(imageLayout) @@ -510,6 +527,8 @@ void Texture2D::transitionToTransferReadLayout(const vk::UniqueCommandBuffer& bu } void Texture2D::transitionToShaderReadLayout(const vk::UniqueCommandBuffer& buffer) { + assert(imageLayout == vk::ImageLayout::eTransferSrcOptimal || imageLayout == vk::ImageLayout::eTransferDstOptimal); + const auto srcAccessMask = imageLayout == vk::ImageLayout::eTransferSrcOptimal ? vk::AccessFlagBits::eTransferRead : vk::AccessFlagBits::eTransferWrite; @@ -535,6 +554,8 @@ void Texture2D::transitionToShaderReadLayout(const vk::UniqueCommandBuffer& buff } void Texture2D::transitionToGeneralLayout(const vk::UniqueCommandBuffer& buffer) { + assert(imageLayout == vk::ImageLayout::eTransferDstOptimal); + const auto barrier = vk::ImageMemoryBarrier() .setImage(imageAllocation->image) .setOldLayout(imageLayout)