src/libANGLE/renderer/vulkan/vk_ref_counted_event.cpp


Log

Author Commit Date CI Message
Charlie Lao f5d6112b 2024-06-05T17:20:45 Vulkan: Remove EventStage::BottomOfPipe and AllCommands These two StageFlags never being used in VkCmdSetEvent, and should not be used given that these are very strong synchronization. They are removed in this CL. Bug: b/336844257 Change-Id: I68a47a5459dadf56ad5c269ebb3af55887110cc7 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5601811 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com> Commit-Queue: Charlie Lao <cclao@google.com>
Charlie Lao 295ff607 2024-06-05T14:49:33 Vulkan: Precompute stageMask of kImageMemoryBarrierData Right now every time we need a pipelineStage in kImageMemoryBarrierData, we are doing a bitwise AND with mSupportedVulkanPipelineStageMask. This get called multiple times from barrier call. This CL adds mImageLayoutAndMemoryBarrierDataMap that has already precomputed all stageMask, thus avoid run time bitwise OR. This CL also precomputes the bufferWritePipelineStageMask so that flushImpl can be use it without construct every time. Bug: b/345279810 Change-Id: I878bd31c967cd217477061976f07df13b043fa7f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5601073 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
Charlie Lao 87bbeaee 2024-06-03T15:04:25 Vulkan: Reduce VkEvent counts by using EventStage enums Right now we are using too many VkCmdSetEvents and causes some of the deqp tests timeout on CI bots (because of VVL is very slow along with the number of events being used). RefCountedEvents are per ImageLayout. But some of ImageLayous have the same VkPipelineStageFlags, for example TransferSrc and TransferDst. This CL changes RefCountedEvent to per unique VkPipelineStageFlags instead of per ImageLayout, thus allows TransferSrc and TransferDst to share one VkEvent. To do that, EventStage enum and kEventStageAndPipelineStageFlagsMap table are added to define the predefined VkPielineStageFlags that ANGLE uses. RefCountedEvent now keeps EventStage instead of ImageLayout. To further reduce the CPU overhead, a customized mPipelineStageMaskAndEventMap table is precomputed in renderer with supported vulkan pipeline stages. With this CL, previously timed out tests such as KHR-GLES3.copy_tex_image_conversions.forbidden.renderbuffer_cubemap* now passing. Bug: b/336844257 Change-Id: I021a8f1d6112d5cf96c61652c9af5f679b1172eb Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5597732 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
Charlie Lao 34b832a3 2024-05-24T13:38:58 Vulkan: Add RefCountedEvent recycler Previously the recycler was disabled due to race between resetEvent and setEvent. This CL splits mFreeStack into two list: mEventsToReset and mEventsToReuse. Events are first added to mEventsToReset list. Then at OutsideRenderPassCommandBufferHelper::flushToPrimary time, VkCmdResetEvents are added to reset all events in mEventsToReset list, and that reset operation is tracked by mResettingQueue. When reset command is completed, events moved into mEventsToReuse list. Since access to renderer's RefCountedEventRecycler requires lock, RefCountedEventCollector (a queue of events) is passed between ShareGroupVk and renderer's recycler to minimize the locked access. Bug: b/336844257 Change-Id: Iffac095729a81ba65a43df68cc9255d76e4be7c9 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5576757 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
Charlie Lao e5fe13df 2024-05-20T11:03:49 Vulkan: Destroy VkEvent instead of putting into recycler VVL is complaining about SYNC-vkCmdSetEvent-missingbarrier-reset (See https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8032). I am not sure if the way I did VkCmdResetEvent followed by VkCmdSetEvent is correct either. So destroy VkEvent instead of put it into recycler for now until I sort this out. Bug: b/336844257 Change-Id: I8baf87fa6f6e8c5ed9e2f7e0a29226caa85ebb31 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5549896 Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com>
Charlie Lao 9ed415e5 2024-05-16T14:28:31 Vulkan: Clean up in ImageHelper::updateLayoutAndBarrier There was a duplicated pipelineBarrier wait in ImageHelper::updateLayoutAndBarrier that possibly come from bad code merge. It is removed in this CL. The check of hasEvent and subsequently call addAdditionalStageAccess has moved out of addMemoryEvent and make its own function so that it only affects the specific case where the image is used in different shader stage in the *same* render pass. Bug: b/336844257 Change-Id: I78b0c952be32124cb0fb6a2cf750df41f6c8259d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5544450 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
Charlie Lao b4562086 2024-05-16T12:22:47 Vulkan: Remove std::vector from EventBarrier::mEvents mEvents and mImageMemoryBarriers field of EventBarrier never being more than 1. This CL removes std::vector and just store the handle. Similarly max count for mImageMemoryBarriers is 1, so std::vector also removed. mImageMemoryBarrierCount added (which can be either 0 or 1) to indicate if mImageMemoryBarrier is valid or nullptr should be send to VK driver. Bug: b/336844257 Change-Id: Ib367c649d3a9d790c5e15d4129cde6673bca6cae Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5545883 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
Charlie Lao 7cbac5de 2024-05-16T10:01:41 Vulkan: Switch RefCountedEventCollector to use std::deque Right now it is using std::vector. The vector could potentially grow big. The grow is costly with vector when storage has to resize. This CL switches it to use std::deque. Bug: b/293297177 Bug: b/336844257 Change-Id: Ia407e7d4e1b68bd0cb7cf76ccc5e7523c0e83415 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5545882 Reviewed-by: Roman Lavrov <romanl@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Yuxin Hu <yuxinhu@google.com> Commit-Queue: Charlie Lao <cclao@google.com>
Charlie Lao f82d812d 2024-05-16T15:46:05 Vulkan: Fix EventBarrier bug when asyncSubmission is enabled Since we have moved RefCountedEvent garbage collection into ShareGroupVk, we have changed the reference counting to use non-atomic. There is a bug with async submission code path where the executeSetEvents gets called from submission thread which does not have share group lock. This CL fixes this bug by storing VkEvent in RenderPassCommandBufferHelper so that executeSetEvents uses VkEvent instead of RefCountedEvent when async submission is enabled. This CL also adds assertion that RefCountedEvent::releaseImpl does not get called from async submission thread. Bug: b/336844257 Change-Id: Ifcbd5a09d2bc7636cc15b2c6728dbbca103d4d9c Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5544449 Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com>
Charlie Lao 8884cf06 2024-05-09T11:21:38 Vulkan: Use QueueSerial to track RefCountedEvent garbage RefCountedEvent garbage are only used on one command buffer, so it is a single QueueSerial is enough to track it. Bug: b/336844257 Change-Id: Icafeee722fe19f41dd863a2e6aca6ddd981d28a4 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5529952 Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com> Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Charlie Lao 4629bf6c 2024-05-08T17:43:59 Vulkan: Move RefCountedEvent GC and recycler to ShareGroupVk (3/3) With previous CLs, RefCountedEvents are increment/decrement only within contexts in the same ShareGroup, thus we no longer needs atomic operation. This CL switchs RefCountedEvent to use RefCounted instead of AtomicRefCounted. Bug: b/336844257 Change-Id: Ic5aa9b0f28b8f817f820f595d3de945ce37dbd0e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5527617 Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Charlie Lao <cclao@google.com> Commit-Queue: Charlie Lao <cclao@google.com>
Charlie Lao 0636b509 2024-05-06T12:36:20 Vulkan: Move RefCountedEvent GC and recycler to ShareGroupVk (2/3) One of the problem we had with RefCountedEvents is CPU overhead comes with it, and some part of the CPU overhead is due to atomic reference counting. The RefCountedEvents are only used by ImageHelper and ImageHelpers are per share group, so they are already protected by front end context share lock. The only reason we needs atomic here is due to garbage cleanup, which runs in separate thread and will decrement the refCount. The idea is to move that garbage list from RendererVk to ShareGroupVk so that access of RefCountedEvents are all protected already, thus we can remove the use of atomic. The down side with this approach is that a share group will hold onto its event garbage and not available for other context to reuse. But VkEvents are expected to be very light weighted objects, so that should be acceptable. This is the second CL in the series. In this CL, we added RefCountedEventsGarbageRecycler to the ShareGroupVk which is responsible to garbage collect and recycle RefCountedEvent. Since most of ImageHelper code have only access to Context argument, for convenience we also stored the RefCountedEventsGarbageRecycler pointer in the vk::Context for easy access. vk::Context argument is also passed to RefCounteEvent::init and release function so that it has access to the recycler. The garbage collection happens when RefCountedEvent is needed. The per renderer recycler is still kept to hold the RefCounteEvents that gets released from ShareGroupVk or when it is released without access to context information. Bug: b/336844257 Change-Id: I36fe5d1c8dacdbe35bb2d380f94a32b9b72bbaa5 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5529951 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
Charlie Lao 5332ab8c 2024-05-10T19:48:34 Vulkan: Add RefCountedEventRecycler to vk::Renderer This CL adds event recycler in vk::Renderer to avoid the constant create and destroy of VkEvents. When RefCountedEvent is destroyed previously, it now goes into per renderer recycler. When RefCountedEvent is created previously, it now dips into this recycler and fetch it. Before we issue VkCmdSetEvent, if this event was from recycler, we also issue VkCmdResetEvent before VkCmdSetEvebt. When glFinish/EGLSwapBuffer is called or context gets destroyed, this recycler is purged to keep the free count under limit. Bug: b/336844257 Change-Id: I92ec1b183f708112a96c3d06fcfa265024f5aa04 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5519174 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
Charlie Lao df2e7bd7 2024-05-10T19:48:34 Vulkan: Handle the case that VkEvent failed to create. If VkEvent failed to create, we can still fall back to pipeline barrier. This CL changes RefCountedEvent::init to return boolean. Also when it fail, this CL did an immediate garbage clean up in case it will free up more event from garbage list and then retry again. Bug: b/336844257 Change-Id: I28251849a92d1785701c55eb028a8fed63cfc372 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5532869 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
Charlie Lao 3d04180c 2024-05-02T17:30:02 Vulkan: Add a dedicated garbage list for RefCountedEvents Previously each individual RefCountedEvent is wrapped into a GarbageObject. That is the reason behind RefCountedEvent being a subclass from WrappedObject, since vk::GetGarbage call requires garbage object is a subclass of WrappedObject. This CL adds a new garbage list dedicated for RefCountedEvents, named mRefCountedEventGarbageList. With this new change, we no longer limited by the vk::GetGarbage requirements since it no longer called for RefCountedEvents. RefCountedEventCollector is a vector of RefCountedEvents and every time a RefCountedEvent needs to be released, it adds into the collector. Then the event collector entire thing is treated like a garbage object and gets ResourceUse tracked and added into mRefCountedEventGarbageList. This list gets walked and cleaned when GPU is completed. This CL is also a preparation for later CLs that adds event recycle support. Bug: b/336844257 Change-Id: I4eff69b66922dfe5521b6994f240e967ff3726bd Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5516458 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
Charlie Lao ef8d9f10 2024-05-01T11:52:04 Vulkan: Use DEVICE_ONLY VkEvent when available VK_KHR_synchronization2 adds device only event. Since we are not using host operations on the event, this CL adds VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR bit when create VkEvent for RefCountedEvent. Bug: b/336844257 Change-Id: I0528b7f45b0da162daa228aea2adf5ce06b5fd6b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5503644 Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com>
Charlie Lao d30e4772 2024-02-02T14:13:33 Vulkan: Add VkCmdWaitEvents for image barriers This CL add EventBarrierArray (sister class of PipelineBarrierArray) that accumulates the event barriers instead of pipeline barriers. ImageHelper::barrierImpl and ImageHelper::updateLayoutAndBarrier has been updated to have a code path that inserts waiting event to EventBarrierArray. PipelineBarrier code path is still kept and is also used when event is invalid or under certain situation as a fallback method from waitEvent. After we generate barrier (regardless it is pipelineBarrier or eventBarrier, we always release ImageHelper::mCurrentEvent. When next barrier/layout call is made, if we see mCurrentEvent is invalid, we always fallback to pipelineBarrier. This way it is safe that if somehow we did not (intentionally or accidentally) insert a new event between two barrier calls, we will not end up with second barrier call wait for old event which creates synchronization hazard. With this approach, second barrier will use pipelineBarrier which is still safe. In this CL the useVkEventForImageBarrier feature flag is still disabled, so no events are created and thus pipelineBarrier is still used. Bug: b/336844257 Change-Id: Idaf5a7200b85f901eae5d376543f189d21522022 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5263701 Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Charlie Lao a96e9197 2024-04-25T10:35:02 Vulkan: Add RefCountedEvent class and VkCmdSetEvent call This CL defines RefCountedEvent class that adds reference counting to VkEvent. CommandBufferHelper and ImageHelper each holds one reference count to the event. Every time an event is added to the command buffer, the corresponding RefCountedEvent will be added to the garbage list which tracks the GPU completion using ResourceUse. That event garbage's reference count will not decremented until GPU is finished, thus ensures we never destroy a VkEvent until GPU is completed. For images used by RenderPassCommands, As RenderPassCommandBufferHelper::imageRead and imageWrite get called, an event with that layout gets created and added to the image. That event is saved in RenderPassCommandBufferHelper::mRefCountedEvents and that VkCmdSetEvents calls are issued from RenderPassCommandBufferHelper::flushToPrimary(). For renderPass attachments, the events are created and added to image when attachment image gets finalized. For images used in OutsideRenderPassCommands, The events are inserted as needed as we generates commands that uses image. We do not wait until commands gets flushed to issue VkCmdSetEvent calls. A convenient function trackImageWithEvent() is added to create and setEvent and add event to image all in one call. You can add this call after the image operation whenever we think it benefits, which gives us better control. (Note: Even if forgot to insert the trackImageWithEvent call, it is still okay since every time barrier is inserted, the event gets released. Next time when we inserts barrier again we will fallback to pipelineBarrier since there is no event associated with it. But that is next CL's content). This CL only adds the VkCmdSetEvent call when feature flag is enabled. The feature flag is still disabled and no VkCmdWaitEvent is used in this CL (will be added in later CL). Bug: b/336844257 Change-Id: Iae5c4d2553a80f0f74cd6065d72a9c592c79f075 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5490203 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com>