diff --git a/base/vulkantools.cpp b/base/vulkantools.cpp index 46669d53..eafb999f 100644 --- a/base/vulkantools.cpp +++ b/base/vulkantools.cpp @@ -126,81 +126,94 @@ namespace vkTools imageMemoryBarrier.subresourceRange = subresourceRange; // Source layouts (old) - - // Undefined layout - // Only allowed as initial layout! - // Make sure any writes to the image have been finished - if (oldImageLayout == VK_IMAGE_LAYOUT_PREINITIALIZED) + // Source access mask controls actions that have to be finished on the old layout + // before it will be transitioned to the new layout + switch (oldImageLayout) { - imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; - } + case VK_IMAGE_LAYOUT_UNDEFINED: + // Image layout is undefined (or does not matter) + // Only valid as initial layout + // No flags required, listed only for completeness + imageMemoryBarrier.srcAccessMask = 0; + break; - // Old layout is color attachment - // Make sure any writes to the color buffer have been finished - if (oldImageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) - { - imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - } + case VK_IMAGE_LAYOUT_PREINITIALIZED: + // Image is preinitialized + // Only valid as initial layout for linear images, preserves memory contents + // Make sure host writes have been finished + imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; + break; - // Old layout is depth/stencil attachment - // Make sure any writes to the depth/stencil buffer have been finished - if (oldImageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) - { - imageMemoryBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - } + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + // Image is a color attachment + // Make sure any writes to the color buffer have been finished + imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + break; - // Old layout is transfer source - // Make sure any reads from the image have been finished - if (oldImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) - { - imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - } + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + // Image is a depth/stencil attachment + // Make sure any writes to the depth/stencil buffer have been finished + imageMemoryBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + break; - // Old layout is shader read (sampler, input attachment) - // Make sure any shader reads from the image have been finished - if (oldImageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) - { - imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + // Image is a transfer source + // Make sure any reads from the image have been finished + imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + break; + + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + // Image is a transfer destination + // Make sure any writes to the image have been finished + imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + break; + + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + // Image is read by a shader + // Make sure any shader reads from the image have been finished + imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; + break; } // Target layouts (new) - - // New layout is transfer destination (copy, blit) - // Make sure any copyies to the image have been finished - if (newImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) + // Destination access mask controls the dependency for the new image layout + switch (newImageLayout) { + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + // Image will be used as a transfer destination + // Make sure any writes to the image have been finished imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - } + break; - // New layout is transfer source (copy, blit) - // Make sure any reads from and writes to the image have been finished - if (newImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) - { + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + // Image will be used as a transfer source + // Make sure any reads from and writes to the image have been finished imageMemoryBarrier.srcAccessMask = imageMemoryBarrier.srcAccessMask | VK_ACCESS_TRANSFER_READ_BIT; imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - } + break; - // New layout is color attachment - // Make sure any writes to the color buffer hav been finished - if (newImageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) - { - imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + // Image will be used as a color attachment + // Make sure any writes to the color buffer have been finished imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - } + imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + break; - // New layout is depth attachment - // Make sure any writes to depth/stencil buffer have been finished - if (newImageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) - { + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + // Image layout will be used as a depth/stencil attachment + // Make sure any writes to depth/stencil buffer have been finished imageMemoryBarrier.dstAccessMask = imageMemoryBarrier.dstAccessMask | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - } + break; - // New layout is shader read (sampler, input attachment) - // Make sure any writes to the image have been finished - if (newImageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) - { - imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + // Image will be read in a shader (sampler, input attachment) + // Make sure any writes to the image have been finished + if (imageMemoryBarrier.srcAccessMask == 0) + { + imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; + } imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + break; } // Put barrier on top