Skip to content

Handle mapAsync rejection when the WebGPU device is lost - #9115

Merged
mvaligursky merged 3 commits into
mainfrom
mv-mapasync-device-lost
Jul 24, 2026
Merged

Handle mapAsync rejection when the WebGPU device is lost#9115
mvaligursky merged 3 commits into
mainfrom
mv-mapasync-device-lost

Conversation

@mvaligursky

Copy link
Copy Markdown
Contributor

Fixes #6677

When the WebGPU device is lost, every in-flight and subsequently issued GPUBuffer.mapAsync() rejects with AbortError: Failed to execute 'mapAsync' on 'GPUBuffer': Device is lost. None of the engine's four mapAsync call sites attached a rejection handler, so this surfaced as an unhandled promise rejection (affecting ~2% of users of the reported game).

Changes:

  • Added an internal WebgpuGraphicsDevice.mapBufferAsync helper that skips the call when the context is already lost and converts the device-lost / buffer-destroyed rejection into a false result instead of an unhandled rejection
  • Dynamic buffers and upload stream: a staging buffer whose mapping fails is no longer recycled (device recovery recreates these anyway)
  • GPU profiler query set: failed mapping returns no results and the profiler skips reporting that frame
  • readBuffer: on failed mapping, the returned promise now rejects with a descriptive error instead of never settling - previously StorageBuffer.read() / texture readback callers would hang forever after device loss

@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown

Build size report

This PR changes the size of the minified bundles.

Bundle Minified Gzip Brotli
playcanvas.min.js 2323.8 KB (+0.4 KB, +0.02%) 598.0 KB (+0.2 KB, +0.03%) 464.9 KB (+0.2 KB, +0.03%)
playcanvas.min.mjs 2321.3 KB (+0.4 KB, +0.02%) 596.8 KB (+0.2 KB, +0.03%) 464.3 KB (−0.0 KB, −0.00%)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the WebGPU backend against GPUBuffer.mapAsync() rejections that occur when the WebGPU device is lost, preventing unhandled promise rejections and ensuring readback promises settle instead of hanging.

Changes:

  • Added WebgpuGraphicsDevice.mapBufferAsync() to centralize mapAsync handling and convert device-lost / buffer-destroyed failures into a false result.
  • Updated WebGPU staging-buffer users (upload stream, dynamic buffers, query set / GPU profiler) to tolerate mapping failure and avoid reporting invalid results.
  • Updated readBuffer-based readback to reject with a descriptive error when mapping fails (instead of never settling).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/platform/graphics/webgpu/webgpu-graphics-device.js Adds mapBufferAsync() and uses it in readback to avoid unhandled rejections / hanging promises on device loss.
src/platform/graphics/webgpu/webgpu-upload-stream.js Switches staging buffer mapping to mapBufferAsync() and destroys buffers that can’t be safely reused.
src/platform/graphics/webgpu/webgpu-dynamic-buffers.js Switches staging buffer mapping to mapBufferAsync() for device-lost safety during buffer recycling.
src/platform/graphics/webgpu/webgpu-query-set.js Switches query staging buffer mapping to mapBufferAsync() and returns null when mapping fails.
src/platform/graphics/webgpu/webgpu-gpu-profiler.js Skips reporting when query results are unavailable due to device loss.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/platform/graphics/webgpu/webgpu-graphics-device.js
Comment thread src/platform/graphics/webgpu/webgpu-dynamic-buffers.js
Comment thread src/platform/graphics/webgpu/webgpu-query-set.js

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment thread src/platform/graphics/webgpu/webgpu-graphics-device.js

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment thread src/platform/graphics/webgpu/webgpu-upload-stream.js
@mvaligursky
mvaligursky merged commit f5e3103 into main Jul 24, 2026
11 checks passed
@mvaligursky
mvaligursky deleted the mv-mapasync-device-lost branch July 24, 2026 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: graphics Graphics related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Failed to execute 'mapAsync' on 'GPUBuffer': Device is lost

2 participants