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.
592{
594 vk::ImageMemoryBarrier barrier {};
595 barrier.oldLayout = old_layout;
596 barrier.newLayout = new_layout;
597 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
598 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
599 barrier.image =
image;
600 barrier.subresourceRange.aspectMask = aspect_flags;
601 barrier.subresourceRange.baseMipLevel = 0;
602 barrier.subresourceRange.levelCount = mip_levels;
603 barrier.subresourceRange.baseArrayLayer = 0;
604 barrier.subresourceRange.layerCount = array_layers;
605
606 vk::PipelineStageFlags src_stage;
607 vk::PipelineStageFlags dst_stage;
608
609 if (old_layout == vk::ImageLayout::eUndefined && new_layout == vk::ImageLayout::eTransferDstOptimal) {
610 barrier.srcAccessMask = vk::AccessFlags {};
611 barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
612 src_stage = vk::PipelineStageFlagBits::eTopOfPipe;
613 dst_stage = vk::PipelineStageFlagBits::eTransfer;
614 } else if (old_layout == vk::ImageLayout::eTransferDstOptimal && new_layout == vk::ImageLayout::eShaderReadOnlyOptimal) {
615 barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
616 barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
617 src_stage = vk::PipelineStageFlagBits::eTransfer;
618 dst_stage = vk::PipelineStageFlagBits::eFragmentShader;
619 } else if (old_layout == vk::ImageLayout::eUndefined && new_layout == vk::ImageLayout::eShaderReadOnlyOptimal) {
620 barrier.srcAccessMask = vk::AccessFlags {};
621 barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
622 src_stage = vk::PipelineStageFlagBits::eTopOfPipe;
623 dst_stage = vk::PipelineStageFlagBits::eFragmentShader;
624 } else if (old_layout == vk::ImageLayout::eUndefined && new_layout == vk::ImageLayout::eColorAttachmentOptimal) {
625 barrier.srcAccessMask = vk::AccessFlags {};
626 barrier.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
627 src_stage = vk::PipelineStageFlagBits::eTopOfPipe;
628 dst_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
629 } else if (old_layout == vk::ImageLayout::eUndefined && new_layout == vk::ImageLayout::eDepthStencilAttachmentOptimal) {
630 barrier.srcAccessMask = vk::AccessFlags {};
631 barrier.dstAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
632 src_stage = vk::PipelineStageFlagBits::eTopOfPipe;
633 dst_stage = vk::PipelineStageFlagBits::eEarlyFragmentTests;
634 } else if (old_layout == vk::ImageLayout::eUndefined && new_layout == vk::ImageLayout::eGeneral) {
635 barrier.srcAccessMask = vk::AccessFlags {};
636 barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite;
637 src_stage = vk::PipelineStageFlagBits::eTopOfPipe;
638 dst_stage = vk::PipelineStageFlagBits::eComputeShader;
639 } else if (old_layout == vk::ImageLayout::eGeneral && new_layout == vk::ImageLayout::eShaderReadOnlyOptimal) {
640 barrier.srcAccessMask = vk::AccessFlagBits::eShaderWrite;
641 barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
642 src_stage = vk::PipelineStageFlagBits::eComputeShader;
643 dst_stage = vk::PipelineStageFlagBits::eComputeShader;
644 } else if (old_layout == vk::ImageLayout::eShaderReadOnlyOptimal && new_layout == vk::ImageLayout::eGeneral) {
645 barrier.srcAccessMask = vk::AccessFlagBits::eShaderRead;
646 barrier.dstAccessMask = vk::AccessFlagBits::eShaderWrite;
647 src_stage = vk::PipelineStageFlagBits::eComputeShader;
648 dst_stage = vk::PipelineStageFlagBits::eComputeShader;
649 } else {
650 barrier.srcAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite;
651 barrier.dstAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite;
652 src_stage = vk::PipelineStageFlagBits::eAllCommands;
653 dst_stage = vk::PipelineStageFlagBits::eAllCommands;
654
656 "Using generic image layout transition");
657 }
658
660 src_stage, dst_stage,
661 vk::DependencyFlags {},
662 0, nullptr,
663 0, nullptr,
664 1, &barrier
665 );
666 });
667
669 "Image layout transitioned: {} -> {}",
670 vk::to_string(old_layout), vk::to_string(new_layout));
671}
#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.