DynamicUploader: fix pending serial race during WithUploadReservation

This change introduced a potential submit between ticks:
https://dawn-review.googlesource.com/c/dawn/+/226596

Specifically, WithUploadReservation would call
OnStagingMemoryFreePendingOnSubmit, which would call Queue::Submit when
enough memory was freed past some threshold. The problem is that in the
case of WriteTexture, WithUploadReservation gets called reentrantly,
once for the WriteTextureImpl, and once for the ClearTexture when
ensuring the texture is zero-initialized. If ever ClearTexture's
WithUploadReservation ends up submitting (because freed allocs >=
threshold), WriteTexture's copy command would be added to the command
list after the submit, but copying to a ring buffer reservation
associated with a serial for ClearTexture's submit (1) instead of the
one the Copy commands will be in (2).

For example, a possible scenario would be:

WriteTextureImpl
    WithUploadReservation
        Reservation suballoc allocated with PendingSerial 1
        Callback function called
            CopyFromStagingToTexture
                CopyFromStagingToTextureImpl
                    EnsureSubresourceContentInitialized
                        ClearTexture
                            WithUploadReservation
                                Reservation suballoc allocated with PendingSerial 1
                                Callback function called
                                OnStagingMemoryFreePendingOnSubmit
                                    Queue::Submit got serial 1 called because total freed allocs >= threshold
                                    PendingSerial now set to 2
                    RecordBufferTextureCopyWithBufferHandle
                        Copy is scheduled to suballoc with serial 1 _after_ submit for this serial

DeviceBase::Tick
    Queue::UpdateCompletedSerial
        CompletedSerial is set to 1
    DynamicUploader::Deallocate
        Reclaims ring buffer allocs with serial <= 1 (CompletedSerial)

The next WriteTexture allocs the reclaimed buffer alloc from the first
WriteTexture, while the copy command is still in flight on the GPU,
resulting in a GPU copy race to the same buffer.

The fix for this is to remove the submit call from
OnStagingMemoryFreePendingOnSubmit, and instead move it to function
MaybeSubmitPendingCommands which gets called in places where we can
guarantee that no reentrancy can occur; namely, at the end of
QueueBase::APIWriteBuffer, QueueBase::APIWriteTexture, and
BufferBase::APIUnmap.

Bug: 439492882
Change-Id: I84ea1273266c9d6f9d1d3bdb4d9fe5d9bfbc5ff8
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/263636
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
4 files changed
tree: dbafda224ff79cbaf83a949e270d3a6381682da6
  1. .github/
  2. .vscode/
  3. build_overrides/
  4. docs/
  5. generator/
  6. include/
  7. infra/
  8. scripts/
  9. src/
  10. test/
  11. third_party/
  12. tools/
  13. webgpu-cts/
  14. .bazelrc
  15. .clang-format
  16. .clang-format-ignore
  17. .clang-tidy
  18. .git-blame-ignore-revs
  19. .gitattributes
  20. .gitignore
  21. .gitmodules
  22. .gn
  23. .style.yapf
  24. .vpython3
  25. AUTHORS
  26. BUILD.bazel
  27. BUILD.gn
  28. CMakeLists.txt
  29. CMakeSettings.json
  30. CODE_OF_CONDUCT.md
  31. codereview.settings
  32. CONTRIBUTING.md
  33. CPPLINT.cfg
  34. DEPS
  35. DIR_METADATA
  36. go.mod
  37. go.sum
  38. go_presubmit_support.py
  39. LICENSE
  40. OWNERS
  41. PRESUBMIT.py
  42. README.chromium
  43. README.md
  44. unsafe_buffers_paths.txt
  45. WATCHLISTS
  46. WORKSPACE.bazel
README.md

Build Status Matrix Space

Dawn, a WebGPU implementation

Dawn is an open-source and cross-platform implementation of the WebGPU standard. More precisely it implements webgpu.h that is a one-to-one mapping with the WebGPU IDL. Dawn is meant to be integrated as part of a larger system and is the underlying implementation of WebGPU in Chromium.

Dawn provides several WebGPU building blocks:

  • WebGPU C/C++ headers that applications and other building blocks use.
    • The webgpu.h version that Dawn implements.
    • A C++ wrapper for the webgpu.h.
  • A “native” implementation of WebGPU using platforms' GPU APIs: D3D12, Metal, Vulkan and OpenGL. See per API support for more details.
  • A client-server implementation of WebGPU for applications that are in a sandbox without access to native drivers
  • Tint is a compiler for the WebGPU Shader Language (WGSL) that can be used in standalone to convert shaders from and to WGSL.

Helpful links:

Documentation table of content

Developer documentation:

User documentation: (TODO, figure out what overlaps with the webgpu.h docs)

License

BSD 3-Clause License, please see LICENSE.

Disclaimer

This is not an officially supported Google product.