Add pipeline barriers flushing buffer data to host
authorPanagiotis Apostolou <panagiotis.apostolou@arm.com>
Thu, 25 Jul 2019 10:29:18 +0000 (12:29 +0200)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Thu, 22 Aug 2019 11:24:22 +0000 (07:24 -0400)
This commit adds a few buffer pipeline barriers whose purpose is to flush
gpu caches, making the buffer data visible to the host.

Affects:
dEQP-VK.pipeline.push_constant.compute_pipeline.simple_test
dEQP-VK.glsl.builtin.precision.*
dEQP-VK.glsl.builtin.function.*
dEQP-VK.api.command_buffers.record_simul_use_secondary_one_primary
dEQP-VK.synchronization.op.single_queue.*
dEQP-VK.query_pool.occlusion_query.*

Components: Vulkan

VK-GL-CTS issue: 1898

Change-Id: Ic6a467b4d1db6cebebf34c8d386e519016fc3fe9

external/vulkancts/modules/vulkan/api/vktApiCommandBuffersTests.cpp
external/vulkancts/modules/vulkan/draw/vktDrawBufferObjectUtil.cpp
external/vulkancts/modules/vulkan/draw/vktDrawBufferObjectUtil.hpp
external/vulkancts/modules/vulkan/pipeline/vktPipelinePushConstantTests.cpp
external/vulkancts/modules/vulkan/query_pool/vktQueryPoolOcclusionTests.cpp
external/vulkancts/modules/vulkan/shaderexecutor/vktShaderExecutor.cpp
external/vulkancts/modules/vulkan/synchronization/vktSynchronizationOperation.cpp

index 5cf131c..f65926a 100644 (file)
@@ -2035,6 +2035,19 @@ tcu::TestStatus simultaneousUseSecondaryBufferOnePrimaryBufferTest(Context& cont
                0u,                                                                                                                     // basePipelineIndex
        };
 
+       const VkBufferMemoryBarrier                             bufferBarrier =
+       {
+               VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                                        // sType
+               DE_NULL,                                                                                                        // pNext
+               VK_ACCESS_SHADER_WRITE_BIT,                                                                     // srcAccessMask
+               VK_ACCESS_HOST_READ_BIT,                                                                        // dstAccessMask
+               VK_QUEUE_FAMILY_IGNORED,                                                                        // srcQueueFamilyIndex
+               VK_QUEUE_FAMILY_IGNORED,                                                                        // destQueueFamilyIndex
+               *buffer,                                                                                                        // buffer
+               (VkDeviceSize)0u,                                                                                       // offset
+               (VkDeviceSize)VK_WHOLE_SIZE,                                                            // size
+       };
+
        const Unique<VkPipeline>                                pipeline(createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo));
 
        // record secondary command buffer
@@ -2043,6 +2056,10 @@ tcu::TestStatus simultaneousUseSecondaryBufferOnePrimaryBufferTest(Context& cont
                vk.cmdBindPipeline(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
                vk.cmdBindDescriptorSets(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, 0, 0);
                vk.cmdDispatch(*secCmdBuf, 1u, 1u, 1u);
+               vk.cmdPipelineBarrier(*secCmdBuf, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
+                                                 0, (const VkMemoryBarrier*)DE_NULL,
+                                                 1, &bufferBarrier,
+                                                 0, (const VkImageMemoryBarrier*)DE_NULL);
        }
        // end recording of secondary buffer
        endCommandBuffer(vk, *secCmdBuf);
index 7d8ace1..06e0628 100644 (file)
@@ -68,5 +68,28 @@ de::SharedPtr<Buffer> Buffer::create (const vk::DeviceInterface& vk,
        return de::SharedPtr<Buffer>(new Buffer(vk, device, vk::createBuffer(vk, device, &createInfo)));
 }
 
+void bufferBarrier (const vk::DeviceInterface& vk,
+                                       vk::VkCommandBuffer                     cmdBuffer,
+                                       vk::VkBuffer                            buffer,
+                                       vk::VkAccessFlags                       srcAccessMask,
+                                       vk::VkAccessFlags                       dstAccessMask,
+                                       vk::VkPipelineStageFlags        srcStageMask,
+                                       vk::VkPipelineStageFlags        dstStageMask)
+{
+       vk::VkBufferMemoryBarrier barrier;
+       barrier.sType                           = vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
+       barrier.pNext                           = DE_NULL;
+       barrier.srcAccessMask           = srcAccessMask;
+       barrier.dstAccessMask           = dstAccessMask;
+       barrier.srcQueueFamilyIndex     = VK_QUEUE_FAMILY_IGNORED;
+       barrier.dstQueueFamilyIndex     = VK_QUEUE_FAMILY_IGNORED;
+       barrier.buffer                          = buffer;
+       barrier.offset                          = 0;
+       barrier.size                            = VK_WHOLE_SIZE;
+
+       vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL,
+                                                 1, &barrier, 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
+}
+
 } // Draw
 } // vkt
index f842333..b913695 100644 (file)
@@ -65,6 +65,13 @@ private:
        vk::VkDevice                                    m_device;
 };
 
+void bufferBarrier (const vk::DeviceInterface& vk,
+                                       vk::VkCommandBuffer                     cmdBuffer,
+                                       vk::VkBuffer                            buffer,
+                                       vk::VkAccessFlags                       srcAccessMask,
+                                       vk::VkAccessFlags                       dstAccessMask,
+                                       vk::VkPipelineStageFlags        srcStageMask,
+                                       vk::VkPipelineStageFlags        dstStageMask);
 } // Draw
 } // vkt
 
index 2ded738..7c646ef 100644 (file)
@@ -1842,6 +1842,21 @@ PushConstantComputeTestInstance::PushConstantComputeTestInstance (Context&                                       c
 
                vk.cmdDispatch(*m_cmdBuffer, 8, 1, 1);
 
+               const VkBufferMemoryBarrier buf_barrier =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                                //    VkStructureType    sType;
+                       DE_NULL,                                                                                                //    const void*        pNext;
+                       VK_ACCESS_SHADER_WRITE_BIT,                                                             //    VkAccessFlags      srcAccessMask;
+                       VK_ACCESS_HOST_READ_BIT,                                                                //    VkAccessFlags      dstAccessMask;
+                       VK_QUEUE_FAMILY_IGNORED,                                                                //    uint32_t           srcQueueFamilyIndex;
+                       VK_QUEUE_FAMILY_IGNORED,                                                                //    uint32_t           dstQueueFamilyIndex;
+                       *m_outBuffer,                                                                                   //    VkBuffer           buffer;
+                       0,                                                                                                              //    VkDeviceSize       offset;
+                       VK_WHOLE_SIZE                                                                                   //    VkDeviceSize       size;
+               };
+
+               vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, DE_NULL, 1, &buf_barrier, 0, DE_NULL);
+
                endCommandBuffer(vk, *m_cmdBuffer);
        }
 }
index 2f10d68..355cfc3 100644 (file)
@@ -821,6 +821,7 @@ vk::Move<vk::VkCommandBuffer> OcclusionQueryTestInstance::recordRender (vk::VkCo
        if (m_testVector.queryResultsMode == RESULTS_MODE_COPY && !hasSeparateCopyCmdBuf())
        {
                vk.cmdCopyQueryPoolResults(*cmdBuffer, m_queryPool, 0, NUM_QUERIES_IN_POOL, m_queryPoolResultsBuffer->object(), /*dstOffset*/ 0, m_testVector.queryResultsStride, m_queryResultFlags);
+               bufferBarrier(vk, *cmdBuffer, m_queryPoolResultsBuffer->object(), vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT);
        }
 
        transition2DImage(vk, *cmdBuffer, m_stateObjects->m_colorAttachmentImage->object(), vk::VK_IMAGE_ASPECT_COLOR_BIT, vk::VK_IMAGE_LAYOUT_GENERAL,
@@ -841,6 +842,7 @@ vk::Move<vk::VkCommandBuffer> OcclusionQueryTestInstance::recordCopyResults (vk:
 
        beginCommandBuffer(vk, *cmdBuffer);
        vk.cmdCopyQueryPoolResults(*cmdBuffer, m_queryPool, 0, NUM_QUERIES_IN_POOL, m_queryPoolResultsBuffer->object(), /*dstOffset*/ 0, m_testVector.queryResultsStride, m_queryResultFlags);
+       bufferBarrier(vk, *cmdBuffer, m_queryPoolResultsBuffer->object(), vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT);
        endCommandBuffer(vk, *cmdBuffer);
 
        return cmdBuffer;
index 2bd1b65..669608b 100644 (file)
@@ -1344,6 +1344,28 @@ void FragmentOutExecutor::execute (int numValues, const void* const* inputs, voi
 
                                        beginCommandBuffer(vk, *copyCmdBuffer);
                                        vk.cmdCopyImageToBuffer(*copyCmdBuffer, colorImages[outLocation + locNdx].get()->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, &copyParams);
+
+                                       // Insert a barrier so data written by the transfer is available to the host
+                                       {
+                                               const VkBufferMemoryBarrier barrier =
+                                               {
+                                                       VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType    sType;
+                                                       DE_NULL,                                                                        // const void*        pNext;
+                                                       VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags      srcAccessMask;
+                                                       VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags      dstAccessMask;
+                                                       VK_QUEUE_FAMILY_IGNORED,                                        // uint32_t           srcQueueFamilyIndex;
+                                                       VK_QUEUE_FAMILY_IGNORED,                                        // uint32_t           dstQueueFamilyIndex;
+                                                       *readImageBuffer,                                                       // VkBuffer           buffer;
+                                                       0,                                                                                      // VkDeviceSize       offset;
+                                                       VK_WHOLE_SIZE,                                                          // VkDeviceSize       size;
+                                               };
+
+                                               vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
+                                                                                       0, (const VkMemoryBarrier*)DE_NULL,
+                                                                                       1, &barrier,
+                                                                                       0, (const VkImageMemoryBarrier*)DE_NULL);
+                                       }
+
                                        endCommandBuffer(vk, *copyCmdBuffer);
 
                                        submitCommandsAndWait(vk, vkDevice, queue, copyCmdBuffer.get());
@@ -2474,6 +2496,27 @@ void ComputeShaderExecutor::execute (int numValues, const void* const* inputs, v
 
                vk.cmdDispatch(*cmdBuffer, numToExec, 1, 1);
 
+               // Insert a barrier so data written by the shader is available to the host
+               {
+                       const VkBufferMemoryBarrier bufferBarrier =
+                       {
+                               VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType    sType;
+                               DE_NULL,                                                                        // const void*        pNext;
+                               VK_ACCESS_SHADER_WRITE_BIT,                                     // VkAccessFlags      srcAccessMask;
+                               VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags      dstAccessMask;
+                               VK_QUEUE_FAMILY_IGNORED,                                        // uint32_t           srcQueueFamilyIndex;
+                               VK_QUEUE_FAMILY_IGNORED,                                        // uint32_t           dstQueueFamilyIndex;
+                               *m_outputBuffer,                                                        // VkBuffer           buffer;
+                               0,                                                                                      // VkDeviceSize       offset;
+                               VK_WHOLE_SIZE,                                                          // VkDeviceSize       size;
+                       };
+
+                       vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
+                                                               0, (const VkMemoryBarrier*)DE_NULL,
+                                                               1, &bufferBarrier,
+                                                               0, (const VkImageMemoryBarrier*)DE_NULL);
+               }
+
                endCommandBuffer(vk, *cmdBuffer);
 
                curOffset += numToExec;
@@ -2829,6 +2872,28 @@ void TessellationExecutor::renderTess (deUint32 numValues, deUint32 vertexCount,
                vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
 
                endRenderPass(vk, *cmdBuffer);
+
+               // Insert a barrier so data written by the shader is available to the host
+               {
+                       const VkBufferMemoryBarrier bufferBarrier =
+                       {
+                               VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType    sType;
+                               DE_NULL,                                                                        // const void*        pNext;
+                               VK_ACCESS_SHADER_WRITE_BIT,                                     // VkAccessFlags      srcAccessMask;
+                               VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags      dstAccessMask;
+                               VK_QUEUE_FAMILY_IGNORED,                                        // uint32_t           srcQueueFamilyIndex;
+                               VK_QUEUE_FAMILY_IGNORED,                                        // uint32_t           dstQueueFamilyIndex;
+                               *m_outputBuffer,                                                        // VkBuffer           buffer;
+                               0,                                                                                      // VkDeviceSize       offset;
+                               VK_WHOLE_SIZE,                                                          // VkDeviceSize       size;
+                       };
+
+                       vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
+                                                                 0, (const VkMemoryBarrier*)DE_NULL,
+                                                                 1, &bufferBarrier,
+                                                                 0, (const VkImageMemoryBarrier*)DE_NULL);
+               }
+
                endCommandBuffer(vk, *cmdBuffer);
        }
 
index 031596b..15c4644 100644 (file)
@@ -1418,8 +1418,8 @@ public:
 
                        // Insert a barrier so data written by the shader is available to the host
                        {
-                               const VkBufferMemoryBarrier     barrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_hostBufferSizeBytes);
-                               vk.cmdPipelineBarrier(cmdBuffer, m_pipelineStage, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
+                               const VkBufferMemoryBarrier     barrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, m_hostBufferSizeBytes);
+                               vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
                        }
                }
        }
@@ -2068,6 +2068,12 @@ public:
                const VkBufferImageCopy copyRegion      = makeBufferImageCopy(m_resource.getImage().subresourceLayers, m_resource.getImage().extent);
 
                vk.cmdCopyImageToBuffer(cmdBuffer, m_resource.getImage().handle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_hostBuffer, 1u, &copyRegion);
+
+               // Insert a barrier so data written by the transfer is available to the host
+               {
+                       const VkBufferMemoryBarrier     barrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, **m_hostBuffer, 0u, VK_WHOLE_SIZE);
+                       vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
+               }
        }
 
        SyncInfo getSyncInfo (void) const