feat(🗿): add createSecondaryDevice() to DawnContext#3768
feat(🗿): add createSecondaryDevice() to DawnContext#3768kbrandwijk wants to merge 3 commits intoShopify:mainfrom
Conversation
Creates an independent Dawn device from the same adapter with its own command queue. Enables concurrent GPU workloads (e.g. ML inference via ONNX Runtime) without mutex contention from ImplicitDeviceSynchronization on the primary rendering device. Includes platform-specific features: - Apple: SharedTextureMemoryIOSurface, DawnMultiPlanarFormats - BufferMapExtendedUsages for staging buffer workflows Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
wcandillon
left a comment
There was a problem hiding this comment.
This is great. Shouldn't the logic of this be in RNDawnUtils and then we can factorize also the duplication with the code in createDawnBackendContext, so we have a generic high level function to request the device?
I noticed that createSecondaryDevice request its own adapter, the idea being that it would be the same adapter anyways? That makes sense to me.
…awnUtils Move shared adapter discovery and device creation logic out of createDawnBackendContext into reusable helpers. createSecondaryDevice now delegates to DawnUtils::requestDevice() instead of duplicating the adapter enumeration, toggles, and device descriptor setup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
kbrandwijk
left a comment
There was a problem hiding this comment.
Refactored — extracted getMatchedAdapter() and requestDevice() into RNDawnUtils.h as shared helpers. Both createDawnBackendContext (primary) and createSecondaryDevice (secondary) now use the same adapter discovery and device creation path.
The difference between the two is just the feature list passed to requestDevice() and the fatalOnDeviceLost flag (primary uses SK_ABORT, secondary logs only).
And yes — each device requests its own adapter, but it resolves to the same GPU. Keeps things simple and avoids coupling the two lifecycles.
Summary
createSecondaryDevice()method toDawnContextthat creates an independent Dawn device from the same GPU adapterImplicitDeviceSynchronization, so it won't contend with the primary rendering device's mutexPlatform features requested on secondary device:
BufferMapExtendedUsages— for staging buffer readback workflowsSharedTextureMemoryIOSurface— zero-copy camera frame importDawnMultiPlanarFormats— multi-planar YUV texture supportUse case
We use this in react-native-webgpu-camera to run ONNX Runtime inference (YOLOv8, depth estimation) on a secondary device while the camera pipeline renders at 120fps on the primary device. Without a secondary device,
ImplicitDeviceSynchronizationserializes all Dawn API calls across threads, causing multi-second freezes during shader compilation.Test plan
createSecondaryDevice()and verify it returns a validwgpu::DeviceSharedTextureMemoryIOSurfaceimport works on secondary device (Apple)