Fix back-to-back transfer command synchronization hazards
authorJeremy Gebben <jeremyg@lunarg.com>
Wed, 9 Dec 2020 15:12:25 +0000 (08:12 -0700)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Fri, 18 Dec 2020 08:11:17 +0000 (08:11 +0000)
If 2 transfer commands use the same memory, they need a pipeline barrier
between them.

VK-GL-CTS Issue: 2693

Affects Tests:
dEQP-VK.api.image_clearing.core.clear_depth_stencil_image.remaining_array_layers_twostep.*
dEQP-VK.pipeline.timestamp.transfer_tests.*
dEQP-VK.ycbcr.copy_dimensions.*

Components: Vulkan

Change-Id: I91bf74c63275f6e3dd6c383f59d1f4e9c1aa0982

external/vulkancts/modules/vulkan/api/vktApiImageClearingTests.cpp
external/vulkancts/modules/vulkan/pipeline/vktPipelineTimestampTests.cpp
external/vulkancts/modules/vulkan/ycbcr/vktYCbCrCopyTests.cpp

index 68ffb95..4a0c82e 100644 (file)
@@ -1548,8 +1548,16 @@ TestStatus ClearDepthStencilImageTestInstance::iterate (void)
 
        m_vkd.cmdClearDepthStencilImage(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_params.clearValue[0].depthStencil, 1, &subresourceRange);
 
-       if (m_twoStep)
+       if (m_twoStep) {
+               pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,                            // VkPipelineStageFlags         srcStageMask
+                                                        VK_PIPELINE_STAGE_TRANSFER_BIT,                                // VkPipelineStageFlags         dstStageMask
+                                                        VK_ACCESS_TRANSFER_WRITE_BIT,                                  // VkAccessFlags                        srcAccessMask
+                                                        VK_ACCESS_TRANSFER_WRITE_BIT,                                  // VkAccessFlags                        dstAccessMask
+                                                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                  // VkImageLayout                        oldLayout;
+                                                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);                 // VkImageLayout                        newLayout;
+
                m_vkd.cmdClearDepthStencilImage(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_params.clearValue[0].depthStencil, 1, &steptwoRange);
+    }
 
        pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,                                    // VkPipelineStageFlags         srcStageMask
                                                 VK_PIPELINE_STAGE_TRANSFER_BIT,                                        // VkPipelineStageFlags         dstStageMask
index 65ea4f0..98c785c 100644 (file)
@@ -2407,6 +2407,16 @@ void TransferTestInstance::configCommandBuffer (void)
        vk.cmdClearColorImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRangeColor);
        vk.cmdClearColorImage(*m_cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, &dstClearValue, 1u, &subRangeColor);
 
+       // synchronize the Clear commands before starting any copy
+       const vk::VkMemoryBarrier barrier =
+       {
+               vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,                                                   // VkStructureType      sType;
+               DE_NULL,                                                                                                                // const void*          pNext;
+               vk::VK_ACCESS_TRANSFER_WRITE_BIT,                                                               // VkAccessFlags        srcAccessMask;
+               vk::VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags        dstAccessMask;
+       };
+       vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1u, &barrier, 0u, DE_NULL, 0u, DE_NULL);
+
        if (!m_hostQueryReset)
                vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
 
@@ -2427,21 +2437,6 @@ void TransferTestInstance::configCommandBuffer (void)
        {
                case TRANSFER_METHOD_COPY_BUFFER:
                        {
-                               const vk::VkBufferMemoryBarrier bufferBarrier =
-                                       {
-                                               vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,    // VkStructureType      sType;
-                                               DE_NULL,                                                                                // const void*          pNext;
-                                               vk::VK_ACCESS_TRANSFER_WRITE_BIT,                               // VkAccessFlags        srcAccessMask;
-                                               vk::VK_ACCESS_TRANSFER_WRITE_BIT,                               // VkAccessFlags        dstAccessMask;
-                                               VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     srcQueueFamilyIndex;
-                                               VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     dstQueueFamilyIndex;
-                                               *m_dstBuffer,                                                                   // VkBuffer                     buffer;
-                                               0ull,                                                                                   // VkDeviceSize         offset;
-                                               VK_WHOLE_SIZE                                                                   // VkDeviceSize         size;
-                                       };
-
-                               vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
-
                                const VkBufferCopy  copyBufRegion =
                                        {
                                                0u,                     // VkDeviceSize    srcOffset;
@@ -2586,6 +2581,7 @@ void TransferTestInstance::configCommandBuffer (void)
 
                                initialImageTransition(*m_cmdBuffer, *m_msImage, subRangeColor, VK_IMAGE_LAYOUT_GENERAL);
                                vk.cmdClearColorImage(*m_cmdBuffer, *m_msImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRangeColor);
+                               vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1u, &barrier, 0u, DE_NULL, 0u, DE_NULL);
                                vk.cmdResolveImage(*m_cmdBuffer, *m_msImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &imageResolve);
                                break;
                        }
index 98b0642..58e2cfc 100644 (file)
@@ -640,7 +640,7 @@ tcu::TestStatus imageCopyTest (Context& context, const TestConfig config)
                                                vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
                                                DE_NULL,
                                                vk::VK_ACCESS_TRANSFER_WRITE_BIT,
-                                               vk::VK_ACCESS_TRANSFER_WRITE_BIT,
+                                               vk::VK_ACCESS_TRANSFER_READ_BIT | vk::VK_ACCESS_TRANSFER_WRITE_BIT,
                                                vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                                                vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                                                VK_QUEUE_FAMILY_IGNORED,