From 17fa2b92f7f63c6922efbcd2a9b48e321a7b9b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20S=C3=BC=C3=9Fenbach?= Date: Thu, 24 Aug 2023 08:32:15 +0200 Subject: [PATCH] Resolve synchronization issue in [RAII_]Samples/InputAttachment. (#1644) --- .../InputAttachment/InputAttachment.cpp | 25 ++++++++++----- samples/InputAttachment/InputAttachment.cpp | 32 ++++++++++++------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/RAII_Samples/InputAttachment/InputAttachment.cpp b/RAII_Samples/InputAttachment/InputAttachment.cpp index 8e01fbf..8d3e5a0 100644 --- a/RAII_Samples/InputAttachment/InputAttachment.cpp +++ b/RAII_Samples/InputAttachment/InputAttachment.cpp @@ -65,7 +65,8 @@ void main() outColor = subpassLoad(inputAttachment); } )"; -int main( int /*argc*/, char ** /*argv*/ ) + +int main( int /*argc*/, char ** /*argv*/ ) { try { @@ -89,7 +90,7 @@ int main( int /*argc*/, char ** /*argv*/ ) vk::raii::su::findGraphicsAndPresentQueueFamilyIndex( physicalDevice, surfaceData.surface ); vk::raii::Device device = vk::raii::su::makeDevice( physicalDevice, graphicsAndPresentQueueFamilyIndex.first, vk::su::getDeviceExtensions() ); - vk::raii::CommandPool commandPool = vk::raii::CommandPool( device, { {}, graphicsAndPresentQueueFamilyIndex.first } ); + vk::raii::CommandPool commandPool = vk::raii::CommandPool( device, { {}, graphicsAndPresentQueueFamilyIndex.first } ); vk::raii::CommandBuffer commandBuffer = vk::raii::su::makeCommandBuffer( device, commandPool ); vk::raii::Queue graphicsQueue( device, graphicsAndPresentQueueFamilyIndex.first, 0 ); @@ -141,9 +142,8 @@ int main( int /*argc*/, char ** /*argv*/ ) { std::array( { { 1.0f, 1.0f, 0.0f, 0.0f } } ) }, { { vk::ImageAspectFlagBits::eColor, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS } } ); - // Set the image layout to SHADER_READONLY_OPTIMAL for use by the shaders - vk::raii::su::setImageLayout( - commandBuffer, *inputImage, swapChainData.colorFormat, vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ); + // Transitioning the layout of the inputImage from TransferDstOptimal to ShaderReadOnlyOptimal is implicitly done by a subpassDependency in the + // RenderPassCreateInfo below vk::ImageViewCreateInfo imageViewCreateInfo( {}, *inputImage, vk::ImageViewType::e2D, swapChainData.colorFormat, {}, { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } ); @@ -178,13 +178,22 @@ int main( int /*argc*/, char ** /*argv*/ ) vk::AttachmentStoreOp::eDontCare, vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, - vk::ImageLayout::eShaderReadOnlyOptimal, + vk::ImageLayout::eTransferDstOptimal, // transition layout from TransferDstOptimal to ShaderReadOnlyOptimal vk::ImageLayout::eShaderReadOnlyOptimal ) }; vk::AttachmentReference colorReference( 0, vk::ImageLayout::eColorAttachmentOptimal ); vk::AttachmentReference inputReference( 1, vk::ImageLayout::eShaderReadOnlyOptimal ); - vk::SubpassDescription subPass( {}, vk::PipelineBindPoint::eGraphics, inputReference, colorReference ); - vk::RenderPassCreateInfo renderPassCreateInfo( {}, attachments, subPass ); + vk::SubpassDescription subpassDescription( {}, vk::PipelineBindPoint::eGraphics, inputReference, colorReference ); + vk::SubpassDependency subpassDependency( VK_SUBPASS_EXTERNAL, + 0, + vk::PipelineStageFlagBits::eTransfer, + vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eFragmentShader, + vk::AccessFlagBits::eTransferWrite, + vk::AccessFlagBits::eColorAttachmentWrite // needed for first attachment + | vk::AccessFlagBits::eInputAttachmentRead | vk::AccessFlagBits::eShaderRead | + vk::AccessFlagBits::eColorAttachmentRead // needed for second attachment + ); + vk::RenderPassCreateInfo renderPassCreateInfo( {}, attachments, subpassDescription, subpassDependency ); vk::raii::RenderPass renderPass( device, renderPassCreateInfo ); glslang::InitializeProcess(); diff --git a/samples/InputAttachment/InputAttachment.cpp b/samples/InputAttachment/InputAttachment.cpp index e1ee0f3..a317844 100644 --- a/samples/InputAttachment/InputAttachment.cpp +++ b/samples/InputAttachment/InputAttachment.cpp @@ -65,7 +65,8 @@ void main() outColor = subpassLoad(inputAttachment); } )"; -int main( int /*argc*/, char ** /*argv*/ ) + +int main( int /*argc*/, char ** /*argv*/ ) { try { @@ -137,9 +138,8 @@ int main( int /*argc*/, char ** /*argv*/ ) vk::ClearColorValue( 1.0f, 1.0f, 0.0f, 0.0f ), vk::ImageSubresourceRange( vk::ImageAspectFlagBits::eColor, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS ) ); - // Set the image layout to SHADER_READONLY_OPTIMAL for use by the shaders - vk::su::setImageLayout( - commandBuffer, inputImage, swapChainData.colorFormat, vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ); + // Transitioning the layout of the inputImage from TransferDstOptimal to ShaderReadOnlyOptimal is implicitly done by a subpassDependency in the + // RenderPassCreateInfo below vk::ImageViewCreateInfo imageViewCreateInfo( {}, inputImage, vk::ImageViewType::e2D, swapChainData.colorFormat, {}, { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } ); @@ -173,13 +173,23 @@ int main( int /*argc*/, char ** /*argv*/ ) vk::AttachmentStoreOp::eDontCare, vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, - vk::ImageLayout::eShaderReadOnlyOptimal, + vk::ImageLayout::eTransferDstOptimal, // transition layout from TransferDstOptimal to ShaderReadOnlyOptimal vk::ImageLayout::eShaderReadOnlyOptimal ) }; - vk::AttachmentReference colorReference( 0, vk::ImageLayout::eColorAttachmentOptimal ); - vk::AttachmentReference inputReference( 1, vk::ImageLayout::eShaderReadOnlyOptimal ); - vk::SubpassDescription subPass( vk::SubpassDescriptionFlags(), vk::PipelineBindPoint::eGraphics, inputReference, colorReference ); - vk::RenderPass renderPass = device.createRenderPass( vk::RenderPassCreateInfo( vk::RenderPassCreateFlags(), attachments, subPass ) ); + vk::AttachmentReference colorReference( 0, vk::ImageLayout::eColorAttachmentOptimal ); + vk::AttachmentReference inputReference( 1, vk::ImageLayout::eShaderReadOnlyOptimal ); + vk::SubpassDescription subpassDescription( {}, vk::PipelineBindPoint::eGraphics, inputReference, colorReference ); + vk::SubpassDependency subpassDependency( VK_SUBPASS_EXTERNAL, + 0, + vk::PipelineStageFlagBits::eTransfer, + vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eFragmentShader, + vk::AccessFlagBits::eTransferWrite, + vk::AccessFlagBits::eColorAttachmentWrite // needed for first attachment + | vk::AccessFlagBits::eInputAttachmentRead | vk::AccessFlagBits::eShaderRead | + vk::AccessFlagBits::eColorAttachmentRead // needed for second attachment + ); + vk::RenderPassCreateInfo renderPassCreateInfo( {}, attachments, subpassDescription, subpassDependency ); + vk::RenderPass renderPass = device.createRenderPass( renderPassCreateInfo ); glslang::InitializeProcess(); vk::ShaderModule vertexShaderModule = vk::su::createShaderModule( device, vk::ShaderStageFlagBits::eVertex, vertexShaderText ); @@ -206,7 +216,7 @@ int main( int /*argc*/, char ** /*argv*/ ) std::make_pair( vertexShaderModule, nullptr ), std::make_pair( fragmentShaderModule, nullptr ), 0, - {}, + {}, vk::FrontFace::eClockwise, false, pipelineLayout, @@ -263,7 +273,7 @@ int main( int /*argc*/, char ** /*argv*/ ) device.destroyPipelineLayout( pipelineLayout ); device.destroyDescriptorSetLayout( descriptorSetLayout ); device.destroyImageView( inputAttachmentView ); - device.destroyImage( inputImage ); // destroy the inputImage before freeing the bound inputMemory ! + device.destroyImage( inputImage ); // destroy the inputImage before freeing the bound inputMemory ! device.freeMemory( inputMemory ); swapChainData.clear( device ); device.freeCommandBuffers( commandPool, commandBuffer );