@@ -47,6 +47,22 @@ constexpr int kLineLoopDynamicIndirectBufferInitialSize = sizeof(VkDrawIndirectC
4747// This is an arbitrary max. We can change this later if necessary.
4848constexpr uint32_t kDefaultDescriptorPoolMaxSets = 128 ;
4949
50+ constexpr angle::PackedEnumMap<PipelineStage, VkPipelineStageFlagBits> kPipelineStageFlagBitMap = {
51+ {PipelineStage::TopOfPipe, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT},
52+ {PipelineStage::DrawIndirect, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT},
53+ {PipelineStage::VertexInput, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT},
54+ {PipelineStage::VertexShader, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT},
55+ {PipelineStage::GeometryShader, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT},
56+ {PipelineStage::TransformFeedback, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT},
57+ {PipelineStage::EarlyFragmentTest, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT},
58+ {PipelineStage::FragmentShader, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT},
59+ {PipelineStage::LateFragmentTest, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT},
60+ {PipelineStage::ColorAttachmentOutput, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT},
61+ {PipelineStage::ComputeShader, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT},
62+ {PipelineStage::Transfer, VK_PIPELINE_STAGE_TRANSFER_BIT},
63+ {PipelineStage::BottomOfPipe, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT},
64+ {PipelineStage::Host, VK_PIPELINE_STAGE_HOST_BIT}};
65+
5066struct ImageMemoryBarrierData
5167{
5268 // The Vk layout corresponding to the ImageLayout key.
@@ -455,12 +471,7 @@ VkImageLayout ConvertImageLayoutToVkImageLayout(ImageLayout imageLayout)
455471
456472// CommandBufferHelper implementation.
457473CommandBufferHelper::CommandBufferHelper (bool hasRenderPass)
458- : mImageBarrierSrcStageMask (0 ),
459- mImageBarrierDstStageMask (0 ),
460- mGlobalMemoryBarrierSrcAccess(0 ),
461- mGlobalMemoryBarrierDstAccess(0 ),
462- mGlobalMemoryBarrierSrcStages(0 ),
463- mGlobalMemoryBarrierDstStages(0 ),
474+ : mPipelineBarrier (),
464475 mCounter (0 ),
465476 mClearValues{},
466477 mRenderPassStarted (false ),
@@ -482,34 +493,29 @@ void CommandBufferHelper::initialize(angle::PoolAllocator *poolAllocator)
482493
483494void CommandBufferHelper::bufferRead (vk::ResourceUseList *resourceUseList,
484495 VkAccessFlags readAccessType,
485- VkPipelineStageFlags readStage,
496+ vk::PipelineStage readStage,
486497 vk::BufferHelper *buffer)
487498{
488499 buffer->retain (resourceUseList);
489- buffer->updateReadBarrier (readAccessType, &mGlobalMemoryBarrierSrcAccess ,
490- &mGlobalMemoryBarrierDstAccess , readStage,
491- &mGlobalMemoryBarrierSrcStages , &mGlobalMemoryBarrierDstStages );
500+ VkPipelineStageFlagBits stageBits = kPipelineStageFlagBitMap [readStage];
501+ buffer->updateReadBarrier (readAccessType, stageBits, &mPipelineBarrier );
492502}
493503
494504void CommandBufferHelper::bufferWrite (vk::ResourceUseList *resourceUseList,
495505 VkAccessFlags writeAccessType,
496- VkPipelineStageFlags writeStage,
506+ vk::PipelineStage writeStage,
497507 vk::BufferHelper *buffer)
498508{
499509 buffer->retain (resourceUseList);
500- buffer->updateWriteBarrier (writeAccessType, &mGlobalMemoryBarrierSrcAccess ,
501- &mGlobalMemoryBarrierDstAccess , writeStage,
502- &mGlobalMemoryBarrierSrcStages , &mGlobalMemoryBarrierDstStages );
510+ VkPipelineStageFlagBits stageBits = kPipelineStageFlagBitMap [writeStage];
511+ buffer->updateWriteBarrier (writeAccessType, stageBits, &mPipelineBarrier );
503512}
504513
505514void CommandBufferHelper::imageBarrier (VkPipelineStageFlags srcStageMask,
506515 VkPipelineStageFlags dstStageMask,
507516 const VkImageMemoryBarrier &imageMemoryBarrier)
508517{
509- ASSERT (imageMemoryBarrier.pNext == nullptr );
510- mImageBarrierSrcStageMask |= srcStageMask;
511- mImageBarrierDstStageMask |= dstStageMask;
512- mImageMemoryBarriers .push_back (imageMemoryBarrier);
518+ mPipelineBarrier .mergeImageBarrier (srcStageMask, dstStageMask, imageMemoryBarrier);
513519}
514520
515521void CommandBufferHelper::imageRead (vk::ResourceUseList *resourceUseList,
@@ -535,41 +541,7 @@ void CommandBufferHelper::imageWrite(vk::ResourceUseList *resourceUseList,
535541
536542void CommandBufferHelper::executeBarriers (vk::PrimaryCommandBuffer *primary)
537543{
538- if (mImageMemoryBarriers .empty () && mGlobalMemoryBarrierSrcAccess == 0 )
539- {
540- return ;
541- }
542-
543- VkPipelineStageFlags srcStages = 0 ;
544- VkPipelineStageFlags dstStages = 0 ;
545-
546- VkMemoryBarrier memoryBarrier = {};
547- uint32_t memoryBarrierCount = 0 ;
548-
549- if (mGlobalMemoryBarrierSrcAccess != 0 )
550- {
551- memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
552- memoryBarrier.srcAccessMask = mGlobalMemoryBarrierSrcAccess ;
553- memoryBarrier.dstAccessMask = mGlobalMemoryBarrierDstAccess ;
554-
555- memoryBarrierCount++;
556- srcStages |= mGlobalMemoryBarrierSrcStages ;
557- dstStages |= mGlobalMemoryBarrierDstStages ;
558-
559- mGlobalMemoryBarrierSrcAccess = 0 ;
560- mGlobalMemoryBarrierDstAccess = 0 ;
561- mGlobalMemoryBarrierSrcStages = 0 ;
562- mGlobalMemoryBarrierDstStages = 0 ;
563- }
564-
565- srcStages |= mImageBarrierSrcStageMask ;
566- dstStages |= mImageBarrierDstStageMask ;
567- primary->pipelineBarrier (srcStages, dstStages, 0 , memoryBarrierCount, &memoryBarrier, 0 ,
568- nullptr , static_cast <uint32_t >(mImageMemoryBarriers .size ()),
569- mImageMemoryBarriers .data ());
570- mImageMemoryBarriers .clear ();
571- mImageBarrierSrcStageMask = 0 ;
572- mImageBarrierDstStageMask = 0 ;
544+ mPipelineBarrier .writeCommand (primary);
573545}
574546
575547void CommandBufferHelper::beginRenderPass (const vk::Framebuffer &framebuffer,
@@ -705,11 +677,11 @@ char GetStoreOpShorthand(uint32_t storeOp)
705677void CommandBufferHelper::addCommandDiagnostics (ContextVk *contextVk)
706678{
707679 std::ostringstream out;
708- if ( mGlobalMemoryBarrierSrcAccess != 0 || mGlobalMemoryBarrierDstAccess != 0 )
709- {
710- out << " Memory Barrier Src: 0x " << std::hex << mGlobalMemoryBarrierSrcAccess
711- << " → Dst: 0x " << std::hex << mGlobalMemoryBarrierDstAccess << " \\ l" ;
712- }
680+
681+ out << " Memory Barrier: " ;
682+ mPipelineBarrier . addDiagnosticsString ( out);
683+ out << " \\ l" ;
684+
713685 if (mIsRenderPassCommandBuffer )
714686 {
715687 size_t attachmentCount = mRenderPassDesc .attachmentCount ();
@@ -2029,6 +2001,17 @@ void LineLoopHelper::Draw(uint32_t count, uint32_t baseVertex, CommandBuffer *co
20292001 commandBuffer->drawIndexedBaseVertex (count, baseVertex);
20302002}
20312003
2004+ // PipelineBarrier implementation.
2005+ void PipelineBarrier::addDiagnosticsString (std::ostringstream &out) const
2006+ {
2007+ if (mMemoryBarrierSrcAccess != 0 || mMemoryBarrierDstAccess != 0 )
2008+ {
2009+ out << " {"
2010+ << " Src: 0x" << std::hex << mMemoryBarrierSrcAccess << " -> Dst: 0x" << std::hex
2011+ << mMemoryBarrierDstAccess << " }" ;
2012+ }
2013+ }
2014+
20322015// BufferHelper implementation.
20332016BufferHelper::BufferHelper ()
20342017 : mMemoryPropertyFlags {},
@@ -2289,21 +2272,16 @@ bool BufferHelper::canAccumulateWrite(ContextVk *contextVk, VkAccessFlags writeA
22892272}
22902273
22912274void BufferHelper::updateReadBarrier (VkAccessFlags readAccessType,
2292- VkAccessFlags *barrierSrcOut,
2293- VkAccessFlags *barrierDstOut,
22942275 VkPipelineStageFlags readStage,
2295- VkPipelineStageFlags *barrierSrcStageOut,
2296- VkPipelineStageFlags *barrierDstStageOut)
2276+ PipelineBarrier *barrier)
22972277{
22982278 // If there was a prior write and we are making a read that is either a new access type or from
22992279 // a new stage, we need a barrier
23002280 if (mCurrentWriteAccess != 0 && (((mCurrentReadAccess & readAccessType) != readAccessType) ||
23012281 ((mCurrentReadStages & readStage) != readStage)))
23022282 {
2303- *barrierSrcOut |= mCurrentWriteAccess ;
2304- *barrierDstOut |= readAccessType;
2305- *barrierSrcStageOut |= mCurrentWriteStages ;
2306- *barrierDstStageOut |= readStage;
2283+ barrier->mergeMemoryBarrier (mCurrentWriteStages , readStage, mCurrentWriteAccess ,
2284+ readAccessType);
23072285 }
23082286
23092287 // Accumulate new read usage.
@@ -2312,22 +2290,17 @@ void BufferHelper::updateReadBarrier(VkAccessFlags readAccessType,
23122290}
23132291
23142292void BufferHelper::updateWriteBarrier (VkAccessFlags writeAccessType,
2315- VkAccessFlags *barrierSrcOut,
2316- VkAccessFlags *barrierDstOut,
23172293 VkPipelineStageFlags writeStage,
2318- VkPipelineStageFlags *barrierSrcStageOut,
2319- VkPipelineStageFlags *barrierDstStageOut)
2294+ PipelineBarrier *barrier)
23202295{
23212296 // We don't need to check mCurrentReadStages here since if it is not zero, mCurrentReadAccess
23222297 // must not be zero as well. stage is finer grain than accessType.
23232298 ASSERT ((!mCurrentReadStages && !mCurrentReadAccess ) ||
23242299 (mCurrentReadStages && mCurrentReadAccess ));
23252300 if (mCurrentReadAccess != 0 || mCurrentWriteAccess != 0 )
23262301 {
2327- *barrierSrcOut |= mCurrentWriteAccess ;
2328- *barrierDstOut |= writeAccessType;
2329- *barrierSrcStageOut |= mCurrentWriteStages | mCurrentReadStages ;
2330- *barrierDstStageOut |= writeStage;
2302+ barrier->mergeMemoryBarrier (mCurrentWriteStages | mCurrentReadStages , writeStage,
2303+ mCurrentWriteAccess , writeAccessType);
23312304 }
23322305
23332306 // Reset usages on the new write.
0 commit comments