Skip emitting barriers from MapAsync Emitting a barrier from BufferVk::MapAsyncImpl() should never be necessary due to TransitionMappableBuffersEagerly(). If the buffer hasn't been used on GPU in commands for next submit then a previous eager transition already emitted the required barrier. If the buffer is used on GPU for the next submit then the eager transition will emit the required barrier before vkQueueSubmit() and MapAsync() already waits on completion. Bug: 425472913, 460180744 Change-Id: I584b038101f340ad37a70ee975c8d05f703bcaae Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/270034 Commit-Queue: Kyle Charbonneau <kylechar@google.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/native/vulkan/BufferVk.cpp b/src/dawn/native/vulkan/BufferVk.cpp index d5c15bc..f53175f 100644 --- a/src/dawn/native/vulkan/BufferVk.cpp +++ b/src/dawn/native/vulkan/BufferVk.cpp
@@ -542,12 +542,6 @@ } } - if (isMapUsage) { - // CPU usage, but a pipeline barrier is needed, so mark the buffer as used within the - // pending commands. - MarkUsedInPendingCommands(); - } - return BufferBarrier{.srcAccessMask = srcAccess, .dstAccessMask = VulkanAccessFlags(usage), .srcStages = srcStage, @@ -564,22 +558,21 @@ } MaybeError Buffer::MapAsyncImpl(wgpu::MapMode mode, size_t offset, size_t size) { - CommandRecordingContext* recordingContext = - ToBackend(GetDevice()->GetQueue())->GetPendingRecordingContext(); - - if (mode & wgpu::MapMode::Read) { - TransitionUsageNow(recordingContext, wgpu::BufferUsage::MapRead); - } else { - DAWN_ASSERT(mode & wgpu::MapMode::Write); - TransitionUsageNow(recordingContext, wgpu::BufferUsage::MapWrite); - } - return {}; } MaybeError Buffer::FinalizeMapImpl(BufferState newState) { Device* device = ToBackend(GetDevice()); + // Any required barriers for mapping must have been inserted before map finalizes. This is done + // by eagerly transitioning mappable buffers at the end of GPU submissions that use them. If + // this ASSERT triggers, there is likely a missing call to CheckBufferNeedsEagerTransition() + // after a transition of the buffer for GPU usage. + wgpu::BufferUsage usage = (MapMode() & wgpu::MapMode::Read) ? wgpu::BufferUsage::MapRead + : wgpu::BufferUsage::MapWrite; + BufferBarrier barrier = TrackUsageAndGetResourceBarrier(usage, wgpu::ShaderStage::None); + DAWN_ASSERT(barrier.IsEmpty()); + if (NeedsInitialization() && GetSize() > 0 && newState == BufferState::Mapped) { // Clear full allocated size, including padding bytes, except for zero sized buffers. For // zero sized buffers GetMappedPointerImpl() points to const data which we can't clear.