Repository navigation
Conversation
…create a cleared cache directory
… its size is checked
…ff when the JVM can't copy its path
…directory, and let a failed JNI copy throw
…without a directory
… as a session stores
…p and while storing
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Dawn can reuse what it produces while building shaders and pipelines across launches, but only when the embedder gives it storage. That storage is either load/store callbacks on the device descriptor (
DawnCacheDeviceDescriptor), or a caching interface on the platform the instance was created with, which is how Chrome does it. react-native-webgpu provides neither, so every launch builds every pipeline from scratch.On Vulkan (Android) the cached data includes the driver's pipeline data, which is where most of the time goes. On Metal (iOS) it is Dawn's MSL translation; Metal's own system cache keeps the compiled pipelines.
This adds a small file-backed cache (
cpp/rnwgpu/DawnBlobCache) and chains it onto every devicerequestDevice()creates. It uses device callbacks rather than a platform interface because the instance can be React Native Skia's.getCacheDir()/webgpu-dawn.Caches/<bundle id>/webgpu-dawn. The bundle id is included because macOS shares~/Library/Cachesbetween apps.dawnToggles: { enabledToggles: ["disable_blob_cache"] }is Dawn's own toggle. It clears that device's cache callbacks. The install-time housekeeping still runs.Measurements
These were taken with Release builds of the example app from this branch. The later commits change only directory handling. A temporary screen, not part of the PR, requests a device and builds 48 distinct render pipelines, each with a fragment shader using lighting, noise and a short loop. Times run from
requestAdapter()to the last pipeline resolving, so they leave out the housekeeping above. Cold is the first launch after install; warm is a later launch.disable_blob_cacheIn a production app that builds 88 pipelines at startup, the same logic applied as a patch to 0.13.0 took the Seeker from 2.6 s, plus 0.6 s of JS-thread stall creating shader modules, to 0.27 s on warm launches.
Tests
yarn test:cppbuilds 20 host unit tests ofDawnBlobCachewith CMake (3.24 or later) and GoogleTest against Dawn's headers, with no GPU needed. CI runs them in the Android job. They cover:They pass under AddressSanitizer and UndefinedBehaviorSanitizer with
-Werror. Each behavioural fix made during review has a test that fails without it.What the tests don't cover:
GPUAdapter::requestDevice, the JNI and Apple wiring, and the opt-out toggle, which were checked on the devices above;The test setup mirrors #550, which adds the repo's first host C++ tests and fetches GoogleTest the same way. Whichever lands second needs the two
CMakeLists.txtsource lists and the CONTRIBUTING lines combined.Not covered
importDevice(), such as React Native Skia's Graphite device, are created by their own library and don't get the cache. Skia would need the same descriptor on its side.