Transition image layout using a pipeline barrier.
Executes immediately on graphics queue. Use for initial setup and one-off transitions. For rendering, prefer manual barriers.
594{
596 vk::ImageMemoryBarrier barrier {};
597 barrier.oldLayout = old_layout;
598 barrier.newLayout = new_layout;
599 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
600 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
601 barrier.image =
image;
602 barrier.subresourceRange.aspectMask = aspect_flags;
603 barrier.subresourceRange.baseMipLevel = 0;
604 barrier.subresourceRange.levelCount = mip_levels;
605 barrier.subresourceRange.baseArrayLayer = 0;
606 barrier.subresourceRange.layerCount = array_layers;
607
608 vk::PipelineStageFlags src_stage;
609 vk::PipelineStageFlags dst_stage;
610
611 if (old_layout == vk::ImageLayout::eUndefined && new_layout == vk::ImageLayout::eTransferDstOptimal) {
612 barrier.srcAccessMask = vk::AccessFlags {};
613 barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
614 src_stage = vk::PipelineStageFlagBits::eTopOfPipe;
615 dst_stage = vk::PipelineStageFlagBits::eTransfer;
616 } else if (old_layout == vk::ImageLayout::eTransferDstOptimal && new_layout == vk::ImageLayout::eShaderReadOnlyOptimal) {
617 barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
618 barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
619 src_stage = vk::PipelineStageFlagBits::eTransfer;
620 dst_stage = vk::PipelineStageFlagBits::eFragmentShader;
621 } else if (old_layout == vk::ImageLayout::eUndefined && new_layout == vk::ImageLayout::eShaderReadOnlyOptimal) {
622 barrier.srcAccessMask = vk::AccessFlags {};
623 barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
624 src_stage = vk::PipelineStageFlagBits::eTopOfPipe;
625 dst_stage = vk::PipelineStageFlagBits::eFragmentShader;
626 } else if (old_layout == vk::ImageLayout::eUndefined && new_layout == vk::ImageLayout::eColorAttachmentOptimal) {
627 barrier.srcAccessMask = vk::AccessFlags {};
628 barrier.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
629 src_stage = vk::PipelineStageFlagBits::eTopOfPipe;
630 dst_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
631 } else if (old_layout == vk::ImageLayout::eUndefined && new_layout == vk::ImageLayout::eDepthStencilAttachmentOptimal) {
632 barrier.srcAccessMask = vk::AccessFlags {};
633 barrier.dstAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
634 src_stage = vk::PipelineStageFlagBits::eTopOfPipe;
635 dst_stage = vk::PipelineStageFlagBits::eEarlyFragmentTests;
636 } else if (old_layout == vk::ImageLayout::eUndefined && new_layout == vk::ImageLayout::eGeneral) {
637 barrier.srcAccessMask = vk::AccessFlags {};
638 barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite;
639 src_stage = vk::PipelineStageFlagBits::eTopOfPipe;
640 dst_stage = vk::PipelineStageFlagBits::eComputeShader;
641 } else if (old_layout == vk::ImageLayout::eGeneral && new_layout == vk::ImageLayout::eShaderReadOnlyOptimal) {
642 barrier.srcAccessMask = vk::AccessFlagBits::eShaderWrite;
643 barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
644 src_stage = vk::PipelineStageFlagBits::eComputeShader;
645 dst_stage = vk::PipelineStageFlagBits::eComputeShader;
646 } else if (old_layout == vk::ImageLayout::eShaderReadOnlyOptimal && new_layout == vk::ImageLayout::eGeneral) {
647 barrier.srcAccessMask = vk::AccessFlagBits::eShaderRead;
648 barrier.dstAccessMask = vk::AccessFlagBits::eShaderWrite;
649 src_stage = vk::PipelineStageFlagBits::eComputeShader;
650 dst_stage = vk::PipelineStageFlagBits::eComputeShader;
651 } else {
652 barrier.srcAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite;
653 barrier.dstAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite;
654 src_stage = vk::PipelineStageFlagBits::eAllCommands;
655 dst_stage = vk::PipelineStageFlagBits::eAllCommands;
656
658 "Using generic image layout transition");
659 }
660
662 src_stage, dst_stage,
663 vk::DependencyFlags {},
664 0, nullptr,
665 0, nullptr,
666 1, &barrier
667 );
668 });
669
671 "Image layout transitioned: {} -> {}",
672 vk::to_string(old_layout), vk::to_string(new_layout));
673}
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
void execute_immediate_commands(const std::function< void(vk::CommandBuffer)> &recorder)
Execute immediate command recording for buffer operations.
@ GraphicsBackend
Graphics/visual rendering backend (Vulkan, OpenGL)
@ Core
Core engine, backend, subsystems.