KhronosGroup/Vulkan-LoaderAndValidationLayers

Duplicate image memory barriers are not reported.

DominikWitczakAMD opened this issue · 3 comments

The following command does not raise validation errors, in spite of duplicate image memory barriers being specified ([0] = [2], [1] = [3]):

vkCmdWaitEvents(commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers) returns void:
    commandBuffer:                  VkCommandBuffer = 00000000123939A0
    eventCount:                     uint32_t = 2
    pEvents:                        const VkEvent* = 0000000004548590
        pEvents[0]:                     const VkEvent = 00000000056D8770
        pEvents[1]:                     const VkEvent = 00000000056D91F0
    srcStageMask:                   VkPipelineStageFlags = 98304 (VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)
    dstStageMask:                   VkPipelineStageFlags = 65536 (VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)
    memoryBarrierCount:             uint32_t = 0
    pMemoryBarriers:                const VkMemoryBarrier* = NULL
    bufferMemoryBarrierCount:       uint32_t = 0
    pBufferMemoryBarriers:          const VkBufferMemoryBarrier* = NULL
    imageMemoryBarrierCount:        uint32_t = 4
    pImageMemoryBarriers:           const VkImageMemoryBarrier* = 0000000005C8B970
        pImageMemoryBarriers[0]:        const VkImageMemoryBarrier = 0000000005C8B970:
            sType:                          VkStructureType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER (45)
            pNext:                          const void* = NULL
            srcAccessMask:                  VkAccessFlags = 256 (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)
            dstAccessMask:                  VkAccessFlags = 32 (VK_ACCESS_SHADER_READ_BIT)
            oldLayout:                      VkImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (2)
            newLayout:                      VkImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL (5)
            srcQueueFamilyIndex:            uint32_t = 0
            dstQueueFamilyIndex:            uint32_t = 0
            image:                          VkImage = 00000000060152F0
            subresourceRange:               VkImageSubresourceRange = 0000000005C8B9A0:
                aspectMask:                     VkImageAspectFlags = 1 (VK_IMAGE_ASPECT_COLOR_BIT)
                baseMipLevel:                   uint32_t = 0
                levelCount:                     uint32_t = 1
                baseArrayLayer:                 uint32_t = 0
                layerCount:                     uint32_t = 1
        pImageMemoryBarriers[1]:        const VkImageMemoryBarrier = 0000000005C8B9B8:
            sType:                          VkStructureType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER (45)
            pNext:                          const void* = NULL
            srcAccessMask:                  VkAccessFlags = 256 (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)
            dstAccessMask:                  VkAccessFlags = 32 (VK_ACCESS_SHADER_READ_BIT)
            oldLayout:                      VkImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (2)
            newLayout:                      VkImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL (5)
            srcQueueFamilyIndex:            uint32_t = 0
            dstQueueFamilyIndex:            uint32_t = 0
            image:                          VkImage = 00000000060152F0
            subresourceRange:               VkImageSubresourceRange = 0000000005C8B9E8:
                aspectMask:                     VkImageAspectFlags = 1 (VK_IMAGE_ASPECT_COLOR_BIT)
                baseMipLevel:                   uint32_t = 0
                levelCount:                     uint32_t = 1
                baseArrayLayer:                 uint32_t = 2047
                layerCount:                     uint32_t = 1
        pImageMemoryBarriers[2]:        const VkImageMemoryBarrier = 0000000005C8BA00:
            sType:                          VkStructureType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER (45)
            pNext:                          const void* = NULL
            srcAccessMask:                  VkAccessFlags = 256 (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)
            dstAccessMask:                  VkAccessFlags = 32 (VK_ACCESS_SHADER_READ_BIT)
            oldLayout:                      VkImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (2)
            newLayout:                      VkImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL (5)
            srcQueueFamilyIndex:            uint32_t = 0
            dstQueueFamilyIndex:            uint32_t = 0
            image:                          VkImage = 00000000060152F0
            subresourceRange:               VkImageSubresourceRange = 0000000005C8BA30:
               aspectMask:                     VkImageAspectFlags = 1 (VK_IMAGE_ASPECT_COLOR_BIT)
                baseMipLevel:                   uint32_t = 0
                levelCount:                     uint32_t = 1
                baseArrayLayer:                 uint32_t = 0
                layerCount:                     uint32_t = 1
        pImageMemoryBarriers[3]:        const VkImageMemoryBarrier = 0000000005C8BA48:
            sType:                          VkStructureType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER (45)
            pNext:                          const void* = NULL
            srcAccessMask:                  VkAccessFlags = 256 (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)
            dstAccessMask:                  VkAccessFlags = 32 (VK_ACCESS_SHADER_READ_BIT)
            oldLayout:                      VkImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (2)
            newLayout:                      VkImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL (5)
            srcQueueFamilyIndex:            uint32_t = 0
            dstQueueFamilyIndex:            uint32_t = 0
            image:                          VkImage = 00000000060152F0
            subresourceRange:               VkImageSubresourceRange = 0000000005C8BA78:
                aspectMask:                     VkImageAspectFlags = 1 (VK_IMAGE_ASPECT_COLOR_BIT)
                baseMipLevel:                   uint32_t = 0
                levelCount:                     uint32_t = 1
                baseArrayLayer:                 uint32_t = 2047
                layerCount:                     uint32_t = 1

Can't find anywhere in the spec that duplicated barriers are not allowed, though neither are contradictory ones (imagine if 0 and 2 specified different layout transitions, or specified overlapping sub-resources with different layout transitions, or queue ownership or ...).

However, in order to handle duplicate barriers (especially ones with layout transitions) would be likely require driver overhead, I can see where valid usage disallowing barriers for the same image with overlapping sub-resource ranges (and buffer with overlapping ranges) would be desirable.

Assuming X != Y, in a scenario where layouts X and Y correspond to different image data layouts, duplicate barriers would likely introduce data corruption, wouldn't they?

Opening an issue with the working group. I can't see how duplicate (or contradictory) barriers could be valid, but I'd like guidance as to the correct valid usage.