Layout transitions for resolve attachments / multisampling

Greetings,

I currently have a setup with one one sample offscreen render target. The render pass where this target is rendered to transitions the image from VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL. Then the offscreen target is used as an input texture. When the target is bound again as render target a manual transition from VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL is done and so on.

Now I add a color resolve target subpass.pResolveAttachments for multisampling. The resolve target has one sample while the original offscreen target gets 4 samples.

My question now is: How should the finalLayout of the original offscreen target be modified? I assume that the target becomes an input to the resolve step and that the layout has to fit that. Or can/should it stay in VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL forever? And the resolve attachment flip-flops between VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL and VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL as the original target did?

Regards.

The multisample offscreen target is very likely used transiently. So the initialLayout should be VK_IMAGE_LAYOUT_UNDEFINED. VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL is appropriate for color attachment (as well as resolve reads). Then on, there is no reason to change the layout with finalLayout if the image is never used for anything else.

To complement this, you could also additionally use lazily allocated memory (assuming the device offers any such memory type).

Resolve writes have pretty much the same parameters as color attachment. So the resolve attachment would likely take over the settings of the original setup.

Thank you.

Do I see right that you leave the color and resolve attachment in VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL for output? That means you make the transition manually later on if you use them as input, right?

I assume my synchronization is right as it worked when I only had the color attachment with one sample.

Do you know a good vulkan command tracer for Linux? I tried Nsight but it only starts after first frame and I need to dump what happens before.

No. Make sure you are binding the right image. And check your sync.

PS: I conveniently have a diff of what you need to do in a similar situation.

1 Like

I accidentally overwrote my previous comment, sorry.

Thank you.

Do I see right that you leave the color and resolve attachment in VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL for output? That means you make the transition manually later on if you use them as input, right?

I assume my synchronization is right as it worked when I only had the color attachment with one sample.

Do you know a good vulkan command tracer for Linux? I tried Nsight but it only starts after first frame and I need to dump what happens before.

Well no. The color stays VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL. The resolve attachment is wired to swapchain, so it is changed to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR. In your case you use it as texture, so it would be the shader read layout, and also have appropriate Subpass Dependency with it.

I don’t like complicated tools if I don’t need them. I try to pre-empt making mistakes. Otherwise most of the time VK_LAYER_LUNARG_api_dump is sufficient for my uses, though it is extremely basic (just makes a console log of the API calls). There’s also RenderDoc which used to be packaged with the SDK.

It’s gotta be some trivial mistake. Also make sure you are referencing the right Image (View) in the render pass. If you post the api dump, could check it out.

Also keep in mind undefined behavior is undefined. That something seemed to work does not imply it is correct.

1 Like

Ok, I have a log now. It is until the first queue present that produces the validation error. General method:

  • Before the render pass the image is transferred from VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
  • The render pass attaches the resolve image at index 2. It has initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL and finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL. Thus when the render pass ends I would expect the resolve image to be in VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.
  • Finally vkUpdateDescriptorSets is called and makes the image a shader input. This seems to produce an UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout complaining that the image is in VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL when it should be in VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.

I had to trim the log because txt upload is not allowed. The excerpt should include the calls that have to do with the resolve image, its view, the framebuffer and render pass. I know that the loadops etc. are suboptimal, I want to get rid of the validation error first.

VkImage 0x5555581deb58   (Resolve image)
VkImageView 0x5555581e1dd8
VkFramebuffer 0x5555581c3108
VkRenderPass 0x5555581c2f68

4092:
Thread 0, Frame 0:
vkCreateImage(device, pCreateInfo, pAllocator, pImage) returns VkResult VK_SUCCESS (0):
    device:                         VkDevice = 0x555557b9a8f8
    pCreateInfo:                    const VkImageCreateInfo* = 0x7fffffffb450:
        sType:                          VkStructureType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO (14)
        pNext:                          const void* = NULL
        flags:                          VkImageCreateFlags = 0
        imageType:                      VkImageType = VK_IMAGE_TYPE_2D (1)
        format:                         VkFormat = VK_FORMAT_R8G8B8A8_UNORM (37)
        extent:                         VkExtent3D = 0x7fffffffb46c:
            width:                          uint32_t = 1000
            height:                         uint32_t = 800
            depth:                          uint32_t = 1
        mipLevels:                      uint32_t = 1
        arrayLayers:                    uint32_t = 1
        samples:                        VkSampleCountFlagBits = 1 (VK_SAMPLE_COUNT_1_BIT)
        tiling:                         VkImageTiling = VK_IMAGE_TILING_OPTIMAL (0)
        usage:                          VkImageUsageFlags = 20 (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
        sharingMode:                    VkSharingMode = VK_SHARING_MODE_EXCLUSIVE (0)
        queueFamilyIndexCount:          uint32_t = 0
        pQueueFamilyIndices:            const uint32_t* = UNUSED
        initialLayout:                  VkImageLayout = VK_IMAGE_LAYOUT_UNDEFINED (0)
    pAllocator:                     const VkAllocationCallbacks* = NULL
    pImage:                         VkImage* = 0x5555581deb58


4117:
Thread 0, Frame 0:
vkGetImageMemoryRequirements(device, image, pMemoryRequirements) returns void:
    device:                         VkDevice = 0x555557b9a8f8
    image:                          VkImage = 0x5555581deb58
    pMemoryRequirements:            VkMemoryRequirements* = 0x5555581df240:
        size:                           VkDeviceSize = 3612672
        alignment:                      VkDeviceSize = 65536
        memoryTypeBits:                 uint32_t = 130


4135:
Thread 0, Frame 0:
vkGetImageMemoryRequirements(device, image, pMemoryRequirements) returns void:
    device:                         VkDevice = 0x555557b9a8f8
    image:                          VkImage = 0x5555581deb58
    pMemoryRequirements:            VkMemoryRequirements* = 0x7fffffffb5f0:
        size:                           VkDeviceSize = 3612672
        alignment:                      VkDeviceSize = 65536
        memoryTypeBits:                 uint32_t = 130

4155:
Thread 0, Frame 0:
vkBindImageMemory(device, image, memory, memoryOffset) returns VkResult VK_SUCCESS (0):
    device:                         VkDevice = 0x555557b9a8f8
    image:                          VkImage = 0x5555581deb58
    memory:                         VkDeviceMemory = 0x5555581df768
    memoryOffset:                   VkDeviceSize = 0

4183:
Thread 0, Frame 0:
vkCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers) returns void:
    commandBuffer:                  VkCommandBuffer = 0x5555581c6a58
    srcStageMask:                   VkPipelineStageFlags = 1 (VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
    dstStageMask:                   VkPipelineStageFlags = 1024 (VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)
    dependencyFlags:                VkDependencyFlags = 0
    memoryBarrierCount:             uint32_t = 0
    pMemoryBarriers:                const VkMemoryBarrier* = NULL
    bufferMemoryBarrierCount:       uint32_t = 0
    pBufferMemoryBarriers:          const VkBufferMemoryBarrier* = NULL
    imageMemoryBarrierCount:        uint32_t = 1
    pImageMemoryBarriers:           const VkImageMemoryBarrier* = 0x7fffe40076f8
        pImageMemoryBarriers[0]:        const VkImageMemoryBarrier = 0x7fffe40076f8:
            sType:                          VkStructureType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER (45)
            pNext:                          const void* = NULL
            srcAccessMask:                  VkAccessFlags = 0
            dstAccessMask:                  VkAccessFlags = 384 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)
            oldLayout:                      VkImageLayout = VK_IMAGE_LAYOUT_UNDEFINED (0)
            newLayout:                      VkImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (2)
            srcQueueFamilyIndex:            uint32_t = 4294967295
            dstQueueFamilyIndex:            uint32_t = 4294967295
            image:                          VkImage = 0x5555581deb58
            subresourceRange:               VkImageSubresourceRange = 0x7fffe4007728:
                aspectMask:                     VkImageAspectFlags = 1 (VK_IMAGE_ASPECT_COLOR_BIT)
                baseMipLevel:                   uint32_t = 0
                levelCount:                     uint32_t = 1
                baseArrayLayer:                 uint32_t = 0
                layerCount:                     uint32_t = 1

4255:
Thread 0, Frame 0:
vkCreateImageView(device, pCreateInfo, pAllocator, pView) returns VkResult VK_SUCCESS (0):
    device:                         VkDevice = 0x555557b9a8f8
    pCreateInfo:                    const VkImageViewCreateInfo* = 0x7fffffffb450:
        sType:                          VkStructureType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO (15)
        pNext:                          const void* = NULL
        flags:                          VkImageViewCreateFlags = 0
        image:                          VkImage = 0x5555581deb58
        viewType:                       VkImageViewType = VK_IMAGE_VIEW_TYPE_2D (1)
        format:                         VkFormat = VK_FORMAT_R8G8B8A8_UNORM (37)
        components:                     VkComponentMapping = 0x7fffffffb478:
            r:                              VkComponentSwizzle = VK_COMPONENT_SWIZZLE_IDENTITY (0)
            g:                              VkComponentSwizzle = VK_COMPONENT_SWIZZLE_IDENTITY (0)
            b:                              VkComponentSwizzle = VK_COMPONENT_SWIZZLE_IDENTITY (0)
            a:                              VkComponentSwizzle = VK_COMPONENT_SWIZZLE_IDENTITY (0)
        subresourceRange:               VkImageSubresourceRange = 0x7fffffffb488:
            aspectMask:                     VkImageAspectFlags = 1 (VK_IMAGE_ASPECT_COLOR_BIT)
            baseMipLevel:                   uint32_t = 0
            levelCount:                     uint32_t = 1
            baseArrayLayer:                 uint32_t = 0
            layerCount:                     uint32_t = 1
    pAllocator:                     const VkAllocationCallbacks* = NULL
    pView:                          VkImageView* = 0x5555581e1dd8

4366:
Thread 0, Frame 0:
vkCreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass) returns VkResult VK_SUCCESS (0):
    device:                         VkDevice = 0x555557b9a8f8
    pCreateInfo:                    const VkRenderPassCreateInfo* = 0x7fffffffb810:
        sType:                          VkStructureType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO (38)
        pNext:                          const void* = NULL
        flags:                          VkRenderPassCreateFlags = 0
        attachmentCount:                uint32_t = 3
        pAttachments:                   const VkAttachmentDescription* = 0x7fffffffb8e0
            pAttachments[0]:                const VkAttachmentDescription = 0x7fffffffb8e0:
                flags:                          VkAttachmentDescriptionFlags = 0
                format:                         VkFormat = VK_FORMAT_R8G8B8A8_UNORM (37)
                samples:                        VkSampleCountFlagBits = 4 (VK_SAMPLE_COUNT_4_BIT)
                loadOp:                         VkAttachmentLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD (0)
                storeOp:                        VkAttachmentStoreOp = VK_ATTACHMENT_STORE_OP_STORE (0)
                stencilLoadOp:                  VkAttachmentLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE (2)
                stencilStoreOp:                 VkAttachmentStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE (1)
                initialLayout:                  VkImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (2)
                finalLayout:                    VkImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (2)
            pAttachments[1]:                const VkAttachmentDescription = 0x7fffffffb904:
                flags:                          VkAttachmentDescriptionFlags = 0
                format:                         VkFormat = VK_FORMAT_D24_UNORM_S8_UINT (129)
                samples:                        VkSampleCountFlagBits = 4 (VK_SAMPLE_COUNT_4_BIT)
                loadOp:                         VkAttachmentLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD (0)
                storeOp:                        VkAttachmentStoreOp = VK_ATTACHMENT_STORE_OP_STORE (0)
                stencilLoadOp:                  VkAttachmentLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD (0)
                stencilStoreOp:                 VkAttachmentStoreOp = VK_ATTACHMENT_STORE_OP_STORE (0)
                initialLayout:                  VkImageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL (3)
                finalLayout:                    VkImageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL (3)
            pAttachments[2]:                const VkAttachmentDescription = 0x7fffffffb928:
                flags:                          VkAttachmentDescriptionFlags = 0
                format:                         VkFormat = VK_FORMAT_R8G8B8A8_UNORM (37)
                samples:                        VkSampleCountFlagBits = 1 (VK_SAMPLE_COUNT_1_BIT)
                loadOp:                         VkAttachmentLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE (2)
                storeOp:                        VkAttachmentStoreOp = VK_ATTACHMENT_STORE_OP_STORE (0)
                stencilLoadOp:                  VkAttachmentLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE (2)
                stencilStoreOp:                 VkAttachmentStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE (1)
                initialLayout:                  VkImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (2)
                finalLayout:                    VkImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL (5)
        subpassCount:                   uint32_t = 1
        pSubpasses:                     const VkSubpassDescription* = 0x7fffffffb890
            pSubpasses[0]:                  const VkSubpassDescription = 0x7fffffffb890:
                flags:                          VkSubpassDescriptionFlags = 0
                pipelineBindPoint:              VkPipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS (0)
                inputAttachmentCount:           uint32_t = 0
                pInputAttachments:              const VkAttachmentReference* = NULL
                colorAttachmentCount:           uint32_t = 1
                pColorAttachments:              const VkAttachmentReference* = 0x7fffffffb7b8
                    pColorAttachments[0]:           const VkAttachmentReference = 0x7fffffffb7b8:
                        attachment:                     uint32_t = 0
                        layout:                         VkImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (2)
                pResolveAttachments:            const VkAttachmentReference* = 0x7fffffffb7c8
                    pResolveAttachments[0]:         const VkAttachmentReference = 0x7fffffffb7c8:
                        attachment:                     uint32_t = 2
                        layout:                         VkImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (2)
                pDepthStencilAttachment:        const VkAttachmentReference* = 0x7fffffffb7c0:
                    attachment:                     uint32_t = 1
                    layout:                         VkImageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL (3)
                preserveAttachmentCount:        uint32_t = 0
                pPreserveAttachments:           const uint32_t* = NULL
        dependencyCount:                uint32_t = 2
        pDependencies:                  const VkSubpassDependency* = 0x5555581c8610
            pDependencies[0]:               const VkSubpassDependency = 0x5555581c8610:
                srcSubpass:                     uint32_t = 4294967295
                dstSubpass:                     uint32_t = 0
                srcStageMask:                   VkPipelineStageFlags = 8192 (VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT)
                dstStageMask:                   VkPipelineStageFlags = 1024 (VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)
                srcAccessMask:                  VkAccessFlags = 32768 (VK_ACCESS_MEMORY_READ_BIT)
                dstAccessMask:                  VkAccessFlags = 256 (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)
                dependencyFlags:                VkDependencyFlags = 1 (VK_DEPENDENCY_BY_REGION_BIT)
            pDependencies[1]:               const VkSubpassDependency = 0x5555581c862c:
                srcSubpass:                     uint32_t = 0
                dstSubpass:                     uint32_t = 4294967295
                srcStageMask:                   VkPipelineStageFlags = 1024 (VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)
                dstStageMask:                   VkPipelineStageFlags = 8192 (VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT)
                srcAccessMask:                  VkAccessFlags = 256 (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)
                dstAccessMask:                  VkAccessFlags = 32768 (VK_ACCESS_MEMORY_READ_BIT)
                dependencyFlags:                VkDependencyFlags = 1 (VK_DEPENDENCY_BY_REGION_BIT)
    pAllocator:                     const VkAllocationCallbacks* = NULL
    pRenderPass:                    VkRenderPass* = 0x5555581c2f68

4447:
Thread 0, Frame 0:
vkCreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer) returns VkResult VK_SUCCESS (0):
    device:                         VkDevice = 0x555557b9a8f8
    pCreateInfo:                    const VkFramebufferCreateInfo* = 0x7fffffffb630:
        sType:                          VkStructureType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO (37)
        pNext:                          const void* = NULL
        flags:                          VkFramebufferCreateFlags = 0
        renderPass:                     VkRenderPass = 0x5555581c2f68
        attachmentCount:                uint32_t = 3
        pAttachments:                   const VkImageView* = 0x55555818e4b0
            pAttachments[0]:                const VkImageView = 0x555558141f98
            pAttachments[1]:                const VkImageView = 0x555558140ae8
            pAttachments[2]:                const VkImageView = 0x5555581e1dd8
        width:                          uint32_t = 1000
        height:                         uint32_t = 800
        layers:                         uint32_t = 1
    pAllocator:                     const VkAllocationCallbacks* = NULL
    pFramebuffer:                   VkFramebuffer* = 0x5555581c3108

4493:
Thread 0, Frame 0:
vkCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers) returns void:
    commandBuffer:                  VkCommandBuffer = 0x55555809a828
    srcStageMask:                   VkPipelineStageFlags = 128 (VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT)
    dstStageMask:                   VkPipelineStageFlags = 1024 (VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)
    dependencyFlags:                VkDependencyFlags = 0
    memoryBarrierCount:             uint32_t = 0
    pMemoryBarriers:                const VkMemoryBarrier* = NULL
    bufferMemoryBarrierCount:       uint32_t = 0
    pBufferMemoryBarriers:          const VkBufferMemoryBarrier* = NULL
    imageMemoryBarrierCount:        uint32_t = 1
    pImageMemoryBarriers:           const VkImageMemoryBarrier* = 0x7fffe40076f8
        pImageMemoryBarriers[0]:        const VkImageMemoryBarrier = 0x7fffe40076f8:
            sType:                          VkStructureType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER (45)
            pNext:                          const void* = NULL
            srcAccessMask:                  VkAccessFlags = 32 (VK_ACCESS_SHADER_READ_BIT)
            dstAccessMask:                  VkAccessFlags = 384 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)
            oldLayout:                      VkImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL (5)
            newLayout:                      VkImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (2)
            srcQueueFamilyIndex:            uint32_t = 4294967295
            dstQueueFamilyIndex:            uint32_t = 4294967295
            image:                          VkImage = 0x5555581deb58
            subresourceRange:               VkImageSubresourceRange = 0x7fffe4007728:
                aspectMask:                     VkImageAspectFlags = 1 (VK_IMAGE_ASPECT_COLOR_BIT)
                baseMipLevel:                   uint32_t = 0
                levelCount:                     uint32_t = 1
                baseArrayLayer:                 uint32_t = 0
                layerCount:                     uint32_t = 1


4522:
Thread 0, Frame 0:
vkCmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents) returns void:
    commandBuffer:                  VkCommandBuffer = 0x55555809a828
    pRenderPassBegin:               const VkRenderPassBeginInfo* = 0x7fffffffb860:
        sType:                          VkStructureType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO (43)
        pNext:                          const void* = NULL
        renderPass:                     VkRenderPass = 0x5555581c2f68
        framebuffer:                    VkFramebuffer = 0x5555581c3108
        renderArea:                     VkRect2D = 0x7fffffffb880:
            offset:                         VkOffset2D = 0x7fffffffb880:
                x:                              int32_t = 0
                y:                              int32_t = 0
            extent:                         VkExtent2D = 0x7fffffffb888:
                width:                          uint32_t = 1000
                height:                         uint32_t = 800
        clearValueCount:                uint32_t = 0
        pClearValues:                   const VkClearValue* = NULL
    contents:                       VkSubpassContents = VK_SUBPASS_CONTENTS_INLINE (0)

5326:
Thread 0, Frame 0:
vkCmdEndRenderPass(commandBuffer) returns void:
    commandBuffer:                  VkCommandBuffer = 0x55555809a828

5889:
Thread 0, Frame 0:
vkCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers) returns void:
    commandBuffer:                  VkCommandBuffer = 0x55555809a828
    srcStageMask:                   VkPipelineStageFlags = 128 (VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT)
    dstStageMask:                   VkPipelineStageFlags = 1024 (VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)
    dependencyFlags:                VkDependencyFlags = 0
    memoryBarrierCount:             uint32_t = 0
    pMemoryBarriers:                const VkMemoryBarrier* = NULL
    bufferMemoryBarrierCount:       uint32_t = 0
    pBufferMemoryBarriers:          const VkBufferMemoryBarrier* = NULL
    imageMemoryBarrierCount:        uint32_t = 1
    pImageMemoryBarriers:           const VkImageMemoryBarrier* = 0x555558de3f98
        pImageMemoryBarriers[0]:        const VkImageMemoryBarrier = 0x555558de3f98:
            sType:                          VkStructureType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER (45)
            pNext:                          const void* = NULL
            srcAccessMask:                  VkAccessFlags = 32 (VK_ACCESS_SHADER_READ_BIT)
            dstAccessMask:                  VkAccessFlags = 384 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)
            oldLayout:                      VkImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL (5)
            newLayout:                      VkImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (2)
            srcQueueFamilyIndex:            uint32_t = 4294967295
            dstQueueFamilyIndex:            uint32_t = 4294967295
            image:                          VkImage = 0x5555581deb58
            subresourceRange:               VkImageSubresourceRange = 0x555558de3fc8:
                aspectMask:                     VkImageAspectFlags = 1 (VK_IMAGE_ASPECT_COLOR_BIT)
                baseMipLevel:                   uint32_t = 0
                levelCount:                     uint32_t = 1
                baseArrayLayer:                 uint32_t = 0
                layerCount:                     uint32_t = 1

5918:
Thread 0, Frame 0:
vkCmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents) returns void:
    commandBuffer:                  VkCommandBuffer = 0x55555809a828
    pRenderPassBegin:               const VkRenderPassBeginInfo* = 0x7fffffffb270:
        sType:                          VkStructureType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO (43)
        pNext:                          const void* = NULL
        renderPass:                     VkRenderPass = 0x5555581c2f68
        framebuffer:                    VkFramebuffer = 0x5555581c3108
        renderArea:                     VkRect2D = 0x7fffffffb290:
            offset:                         VkOffset2D = 0x7fffffffb290:
                x:                              int32_t = 0
                y:                              int32_t = 0
            extent:                         VkExtent2D = 0x7fffffffb298:
                width:                          uint32_t = 1000
                height:                         uint32_t = 800
        clearValueCount:                uint32_t = 0
        pClearValues:                   const VkClearValue* = NULL
    contents:                       VkSubpassContents = VK_SUBPASS_CONTENTS_INLINE (0)

6007:
Thread 0, Frame 0:
vkCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines) returns VkResult VK_SUCCESS (0):
    device:                         VkDevice = 0x555557b9a8f8
    pipelineCache:                  VkPipelineCache = 0
    createInfoCount:                uint32_t = 1
    pCreateInfos:                   const VkGraphicsPipelineCreateInfo* = 0x555558d6bce8
        pCreateInfos[0]:                const VkGraphicsPipelineCreateInfo = 0x555558d6bce8:
            sType:                          VkStructureType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO (28)
            pNext:                          const void* = NULL
            flags:                          VkPipelineCreateFlags = 0
            stageCount:                     uint32_t = 2
            pStages:                        const VkPipelineShaderStageCreateInfo* = 0x555558dd7678
                pStages[0]:                     const VkPipelineShaderStageCreateInfo = 0x555558dd7678:
                    sType:                          VkStructureType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO (18)
                    pNext:                          const void* = NULL
                    flags:                          VkPipelineShaderStageCreateFlags = 0
                    stage:                          VkShaderStageFlagBits = 1 (VK_SHADER_STAGE_VERTEX_BIT)
                    module:                         VkShaderModule = 0x555558327648
                    pName:                          const char* = "main"
                    pSpecializationInfo:            const VkSpecializationInfo* = NULL
                pStages[1]:                     const VkPipelineShaderStageCreateInfo = 0x555558dd76a8:
                    sType:                          VkStructureType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO (18)
                    pNext:                          const void* = NULL
                    flags:                          VkPipelineShaderStageCreateFlags = 0
                    stage:                          VkShaderStageFlagBits = 16 (VK_SHADER_STAGE_FRAGMENT_BIT)
                    module:                         VkShaderModule = 0x555558dd60c8
                    pName:                          const char* = "main"
                    pSpecializationInfo:            const VkSpecializationInfo* = NULL
            pVertexInputState:              const VkPipelineVertexInputStateCreateInfo* = 0x555558d72ed0:
                sType:                          VkStructureType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO (19)
                pNext:                          const void* = NULL
                flags:                          VkPipelineVertexInputStateCreateFlags = 0
                vertexBindingDescriptionCount:  uint32_t = 1
                pVertexBindingDescriptions:     const VkVertexInputBindingDescription* = 0x555558d704e0
                    pVertexBindingDescriptions[0]:  const VkVertexInputBindingDescription = 0x555558d704e0:
                        binding:                        uint32_t = 0
                        stride:                         uint32_t = 24
                        inputRate:                      VkVertexInputRate = VK_VERTEX_INPUT_RATE_VERTEX (0)
                vertexAttributeDescriptionCount: uint32_t = 1
                pVertexAttributeDescriptions:   const VkVertexInputAttributeDescription* = 0x555558d706a0
                    pVertexAttributeDescriptions[0]: const VkVertexInputAttributeDescription = 0x555558d706a0:
                        location:                       uint32_t = 0
                        binding:                        uint32_t = 0
                        format:                         VkFormat = VK_FORMAT_R32G32B32_SFLOAT (106)
                        offset:                         uint32_t = 0
            pInputAssemblyState:            const VkPipelineInputAssemblyStateCreateInfo* = 0x555558d70ca0:
                sType:                          VkStructureType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO (20)
                pNext:                          const void* = NULL
                flags:                          VkPipelineInputAssemblyStateCreateFlags = 0
                topology:                       VkPrimitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST (3)
                primitiveRestartEnable:         VkBool32 = 0
            pTessellationState:             const VkPipelineTessellationStateCreateInfo* = NULL
            pViewportState:                 const VkPipelineViewportStateCreateInfo* = 0x555558d708b0:
                sType:                          VkStructureType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO (22)
                pNext:                          const void* = NULL
                flags:                          VkPipelineViewportStateCreateFlags = 0
                viewportCount:                  uint32_t = 1
                pViewports:                     const VkViewport* = 0x555558d707a0
                    pViewports[0]:                  const VkViewport = 0x555558d707a0:
                        x:                              float = 0
                        y:                              float = 0
                        width:                          float = 1000
                        height:                         float = 800
                        minDepth:                       float = 0
                        maxDepth:                       float = 1
                scissorCount:                   uint32_t = 1
                pScissors:                      const VkRect2D* = 0x555558d708f0
                    pScissors[0]:                   const VkRect2D = 0x555558d708f0:
                        offset:                         VkOffset2D = 0x555558d708f0:
                            x:                              int32_t = 0
                            y:                              int32_t = 0
                        extent:                         VkExtent2D = 0x555558d708f8:
                            width:                          uint32_t = 1000
                            height:                         uint32_t = 800
            pRasterizationState:            const VkPipelineRasterizationStateCreateInfo* = 0x555558de3520:
                sType:                          VkStructureType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO (23)
                pNext:                          const void* = NULL
                flags:                          VkPipelineRasterizationStateCreateFlags = 0
                depthClampEnable:               VkBool32 = 0
                rasterizerDiscardEnable:        VkBool32 = 0
                polygonMode:                    VkPolygonMode = VK_POLYGON_MODE_FILL (0)
                cullMode:                       VkCullModeFlags = 1 (VK_CULL_MODE_FRONT_BIT)
                frontFace:                      VkFrontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE (0)
                depthBiasEnable:                VkBool32 = 0
                depthBiasConstantFactor:        float = 0
                depthBiasClamp:                 float = 0
                depthBiasSlopeFactor:           float = 0
                lineWidth:                      float = 1
            pMultisampleState:              const VkPipelineMultisampleStateCreateInfo* = 0x555558de3680:
                sType:                          VkStructureType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO (24)
                pNext:                          const void* = NULL
                flags:                          VkPipelineMultisampleStateCreateFlags = 0
                rasterizationSamples:           VkSampleCountFlagBits = 4 (VK_SAMPLE_COUNT_4_BIT)
                sampleShadingEnable:            VkBool32 = 0
                minSampleShading:               float = 0
                pSampleMask:                    const VkSampleMask* = NULL
                alphaToCoverageEnable:          VkBool32 = 0
                alphaToOneEnable:               VkBool32 = 0
            pDepthStencilState:             const VkPipelineDepthStencilStateCreateInfo* = 0x555558d72810:
                sType:                          VkStructureType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO (25)
                pNext:                          const void* = NULL
                flags:                          VkPipelineDepthStencilStateCreateFlags = 0
                depthTestEnable:                VkBool32 = 1
                depthWriteEnable:               VkBool32 = 0
                depthCompareOp:                 VkCompareOp = VK_COMPARE_OP_ALWAYS (7)
                depthBoundsTestEnable:          VkBool32 = 0
                stencilTestEnable:              VkBool32 = 0
                front:                          VkStencilOpState = 0x555558d72838:
                    failOp:                         VkStencilOp = VK_STENCIL_OP_KEEP (0)
                    passOp:                         VkStencilOp = VK_STENCIL_OP_KEEP (0)
                    depthFailOp:                    VkStencilOp = VK_STENCIL_OP_KEEP (0)
                    compareOp:                      VkCompareOp = VK_COMPARE_OP_ALWAYS (7)
                    compareMask:                    uint32_t = 255
                    writeMask:                      uint32_t = 4294967295
                    reference:                      uint32_t = 0
                back:                           VkStencilOpState = 0x555558d72854:
                    failOp:                         VkStencilOp = VK_STENCIL_OP_KEEP (0)
                    passOp:                         VkStencilOp = VK_STENCIL_OP_KEEP (0)
                    depthFailOp:                    VkStencilOp = VK_STENCIL_OP_KEEP (0)
                    compareOp:                      VkCompareOp = VK_COMPARE_OP_ALWAYS (7)
                    compareMask:                    uint32_t = 255
                    writeMask:                      uint32_t = 4294967295
                    reference:                      uint32_t = 0
                minDepthBounds:                 float = 0
                maxDepthBounds:                 float = 0
            pColorBlendState:               const VkPipelineColorBlendStateCreateInfo* = 0x555558de36c0:
                sType:                          VkStructureType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO (26)
                pNext:                          const void* = NULL
                flags:                          VkPipelineColorBlendStateCreateFlags = 0
                logicOpEnable:                  VkBool32 = 0
                logicOp:                        VkLogicOp = VK_LOGIC_OP_COPY (3)
                attachmentCount:                uint32_t = 1
                pAttachments:                   const VkPipelineColorBlendAttachmentState* = 0x555558de35d0
                    pAttachments[0]:                const VkPipelineColorBlendAttachmentState = 0x555558de35d0:
                        blendEnable:                    VkBool32 = 1
                        srcColorBlendFactor:            VkBlendFactor = VK_BLEND_FACTOR_ONE (1)
                        dstColorBlendFactor:            VkBlendFactor = VK_BLEND_FACTOR_ZERO (0)
                        colorBlendOp:                   VkBlendOp = VK_BLEND_OP_ADD (0)
                        srcAlphaBlendFactor:            VkBlendFactor = VK_BLEND_FACTOR_ONE (1)
                        dstAlphaBlendFactor:            VkBlendFactor = VK_BLEND_FACTOR_ZERO (0)
                        alphaBlendOp:                   VkBlendOp = VK_BLEND_OP_ADD (0)
                        colorWriteMask:                 VkColorComponentFlags = 15 (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT)
                blendConstants:                 float[4] = 0x555558de36e8
                    blendConstants[0]:              float = 0
                    blendConstants[1]:              float = 0
                    blendConstants[2]:              float = 0
                    blendConstants[3]:              float = 0
            pDynamicState:                  const VkPipelineDynamicStateCreateInfo* = NULL
            layout:                         VkPipelineLayout = 0x555558d6cf18
            renderPass:                     VkRenderPass = 0x5555581c2f68
            subpass:                        uint32_t = 0
            basePipelineHandle:             VkPipeline = 0
            basePipelineIndex:              int32_t = 0
    pAllocator:                     const VkAllocationCallbacks* = NULL
    pPipelines:                     VkPipeline* = 0x7fffffffaed0
        pPipelines[0]:                  VkPipeline = 0x555558324b88

7994:
Thread 0, Frame 0:
vkCmdEndRenderPass(commandBuffer) returns void:
    commandBuffer:                  VkCommandBuffer = 0x55555809a828

8553:
Thread 0, Frame 0:
vkUpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies) returns void:
    device:                         VkDevice = 0x555557b9a8f8
    descriptorWriteCount:           uint32_t = 1
    pDescriptorWrites:              const VkWriteDescriptorSet* = 0x555558247318
        pDescriptorWrites[0]:           const VkWriteDescriptorSet = 0x555558247318:
            sType:                          VkStructureType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET (35)
            pNext:                          const void* = NULL
            dstSet:                         VkDescriptorSet = 0x7fff5d451988
            dstBinding:                     uint32_t = 0
            dstArrayElement:                uint32_t = 0
            descriptorCount:                uint32_t = 1
            descriptorType:                 VkDescriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER (1)
            pImageInfo:                     const VkDescriptorImageInfo* = 0x555558322d60
                pImageInfo[0]:                  const VkDescriptorImageInfo = 0x555558322d60:
                    sampler:                        VkSampler = 0x55555824ac58
                    imageView:                      VkImageView = 0x5555581e1dd8
                    imageLayout:                    VkImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL (5)
            pBufferInfo:                    const VkDescriptorBufferInfo* = UNUSED
            pTexelBufferView:               const VkBufferView* = UNUSED
    descriptorCopyCount:            uint32_t = 0
    pDescriptorCopies:              const VkCopyDescriptorSet* = NULL


Avoid prose. Problem with prose is it shows your intentions. It almost never shows bugs (unless it was your intention to make some).

You could use Gist or something to make an untrimmed dump.

Anyway, what I actually see from this:

  1. Resolved Image get’s initial transition to LAYOUT_COLOR_ATTACHMENT. That is done in a separate cmdbuff. vkQueueSubmit got trimmed apparently, but you seem to set dstStageMask, so assumably it is submitted before all the other stuff to the same queue and it is synchronized by the barrier (and not something more forceful like semaphores or fences).

  2. Then the Resolved Image is transitioned again LAYOUT_SHADER_READ to LAYOUT_COLOR_ATTACHMENT. That already seems wrong. The layout does not match the previous barier in (1), nor does the stage masks match to make it ordered.

  3. Then the Render Pass Instance begins. It assumes initial LAYOUT_COLOR_ATTACHMENT, so that is consistent with the barrier (2). The incomming external Subpass Dependency is kinda confusing, but should be largely inconsequential because (2) allready does all the stuff.

  4. Neither of the images change layout in the subpass.

  5. The Resolved Image changes layout to LAYOUT_SHADER_READ_ONLY, and the outgoing external Dependency is dst = STAGE_BOTTOM_OF_PIPE_BIT (i.e. “synchronize with nothing”). Assumably that should instead sync with the texturing read.

  6. There is buncha important stuff trimmed here. And afterwards (2)-(5) seems just repeated for some reason.

  7. Then pipeline is created for the render pass we already used, which is pretty weird.

Ok, this is a full dump until the queue submit that produces the validation errors:
https://www.file-upload.net/download-14645776/vkapidumplog.txt.html

There’s lot of repetition that I cannot make heads or tails of. There other command buffers do not seem to be recorded, so I would assume you accidentally record all stuff to the same command buffer?

PS: Same with vkUpdateDescriptorSets. You first write one image to it, and immediately overwrite it with another.

Nevermind. It was a silly mistake that assumed the wrong image state producing an invalid memory barrier transition. Sorry for the inconvenience.