From e50028952fcbc13708c6b4b618da3a2dded8aca4 Mon Sep 17 00:00:00 2001 From: Sylvain Doremus Date: Tue, 7 Feb 2023 17:52:29 +0100 Subject: [PATCH] Added a finalOutputLayout for ImageCopy, to place output views in that layout. --- .../RenderGraph/RunnablePasses/ImageCopy.hpp | 9 +++ .../RenderGraph/RunnablePasses/ImageCopy.cpp | 77 ++++++++++++++----- 2 files changed, 68 insertions(+), 18 deletions(-) diff --git a/include/RenderGraph/RunnablePasses/ImageCopy.hpp b/include/RenderGraph/RunnablePasses/ImageCopy.hpp index 95d175e..b426822 100644 --- a/include/RenderGraph/RunnablePasses/ImageCopy.hpp +++ b/include/RenderGraph/RunnablePasses/ImageCopy.hpp @@ -18,6 +18,14 @@ namespace crg , ru::Config ruConfig = {} , GetPassIndexCallback passIndex = GetPassIndexCallback( [](){ return 0u; } ) , IsEnabledCallback isEnabled = IsEnabledCallback( [](){ return true; } ) ); + CRG_API ImageCopy( FramePass const & pass + , GraphContext & context + , RunnableGraph & graph + , VkExtent3D copySize + , VkImageLayout finalOutputLayout + , ru::Config ruConfig = {} + , GetPassIndexCallback passIndex = GetPassIndexCallback( [](){ return 0u; } ) + , IsEnabledCallback isEnabled = IsEnabledCallback( [](){ return true; } ) ); private: void doInitialise(); @@ -27,5 +35,6 @@ namespace crg private: VkExtent3D m_copySize; + VkImageLayout m_finalOutputLayout; }; } diff --git a/source/RenderGraph/RunnablePasses/ImageCopy.cpp b/source/RenderGraph/RunnablePasses/ImageCopy.cpp index c39f663..d77c7c1 100644 --- a/source/RenderGraph/RunnablePasses/ImageCopy.cpp +++ b/source/RenderGraph/RunnablePasses/ImageCopy.cpp @@ -27,6 +27,7 @@ namespace crg , GraphContext & context , RunnableGraph & graph , VkExtent3D copySize + , VkImageLayout finalOutputLayout , ru::Config ruConfig , GetPassIndexCallback passIndex , IsEnabledCallback isEnabled ) @@ -40,8 +41,28 @@ namespace crg , isEnabled } , std::move( ruConfig ) } , m_copySize{std::move( copySize ) } + , m_finalOutputLayout{ finalOutputLayout } { - assert( pass.images.size() == 2u ); + assert( ( pass.images.size() % 2u ) == 0u ); + } + + ImageCopy::ImageCopy( FramePass const & pass + , GraphContext & context + , RunnableGraph & graph + , VkExtent3D copySize + , ru::Config ruConfig + , GetPassIndexCallback passIndex + , IsEnabledCallback isEnabled ) + : ImageCopy{ pass + , context + , graph + , copySize + , VK_IMAGE_LAYOUT_UNDEFINED + , std::move( ruConfig ) + , passIndex + , isEnabled } + { + assert( ( pass.images.size() % 2u ) == 0u ); } void ImageCopy::doInitialise() @@ -52,22 +73,42 @@ namespace crg , VkCommandBuffer commandBuffer , uint32_t index ) { - auto srcAttach{ m_pass.images.front().view( index ) }; - auto dstAttach{ m_pass.images.back().view( index ) }; - auto srcImage{ m_graph.createImage( srcAttach.data->image ) }; - auto dstImage{ m_graph.createImage( dstAttach.data->image ) }; - // Copy source to target. - VkImageCopy copyRegion{ imgCopy::convert( srcAttach.data->info.subresourceRange ) - , {} - , imgCopy::convert( dstAttach.data->info.subresourceRange ) - , {} - , m_copySize }; - m_context.vkCmdCopyImage( commandBuffer - , srcImage - , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL - , dstImage - , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL - , 1u - , ©Region ); + auto srcIt = m_pass.images.begin(); + auto dstIt = std::next( srcIt ); + + while ( srcIt != m_pass.images.end() ) + { + auto srcAttach{ srcIt->view( index ) }; + auto dstAttach{ dstIt->view( index ) }; + auto srcImage{ m_graph.createImage( srcAttach.data->image ) }; + auto dstImage{ m_graph.createImage( dstAttach.data->image ) }; + // Copy source to target. + VkImageCopy copyRegion{ imgCopy::convert( srcAttach.data->info.subresourceRange ) + , {} + , imgCopy::convert( dstAttach.data->info.subresourceRange ) + , {} + , m_copySize }; + m_context.vkCmdCopyImage( commandBuffer + , srcImage + , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL + , dstImage + , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL + , 1u + , ©Region ); + + if ( m_finalOutputLayout != VK_IMAGE_LAYOUT_UNDEFINED ) + { + context.memoryBarrier( commandBuffer + , dstAttach + , crg::makeLayoutState( m_finalOutputLayout ) ); + } + + srcIt = std::next( dstIt ); + + if ( srcIt != m_pass.images.end() ) + { + dstIt = std::next( srcIt ); + } + } } }