commit 68365c757921344872d01a3f326a27fb9e42d77e Author: Kevin Lubick <kjlu...@google.com> Date: Fri Oct 08 15:39:50 2021
[demos] Add WebGPU demo using origin trial
Before we get too excited, this does not use CanvasKit.
What this does add is an origin-trial token so we can more easily demo our progress on *.skia.org and test locally using localhost:8123 (which is the default if you run make local in //demos.skia.org)
To view this locally, I started chrome (stable 94) with --enable-features=Vulkan --enable-unsafe-webgpu
Further exploration of WebGPU is blocked by paying down some technical debt.
The next goal would be to compile our GMs against WebGPU and be able to test them. We currently can compile our GMs for WebGL, but this is painful to do due to slow compile/link times as a result of the single-threaded nature of compile_gm.sh [1], which is just a result of a bash script not being the right tool to compile something as complex as Skia in an efficient way (it's not GN or Bazel).
Because WebGPU is newer and it will likely take a lot of iteration to get CanvasKit support for it and because I don't want to have to wait 5 minutes to rebuild every time I make a change, we need to address the slow build times first.
The right way to do this is to remove compile.sh and compile_gm.sh and replace them with a proper build system. While this could be done in GN, I would prefer to not have to work hard on GN files/toolchains, just to migrate them to Bazel, as that seems to be the trend of Skia's build system.
I've already done a POC build of a simple WebGPU application using Bazel + Emscripten [2].
Therefore, I am going to hold off on further WebGPU exploration until we can build the GM test suite in WASM using Bazel, so future work is less agonizingly slow.
Update: The Bazel build of the GMs (with the WebGL backend) is much much faster than compile_gm.sh, especially for incremental builds. 10s of minutes down to 10s of seconds.
This will be well worth the detour.
Git Watcher via monorail
unread,
Mar 7, 2022, 9:39:11 AM3/7/22
Reply to author
Sign in to reply to author
Forward
Sign in to forward
Delete
You do not have permission to delete messages in this group
Copy link
Report message
Show original message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
[ganesh][dawn] Support blocking on async WebGPU events in WASM
The `wgpu::Device::Tick()` function is not available when the Dawn backend is compiled using emsdk to target WebAssembly. As an alternative, this CL introduces code that takes advantage of emscripten's Asyncify feature to yield execution to the browser's event loop and allowing it to execute async tasks from blocking Skia code.
* Introduced the GrDawnAsyncWait class which abstracts over Asyncify vs wgpu::Device::Tick depending on the platform and implements common busy-wait boilerplate. * Refactored the fence management in GrDawnGpu to make use of GrDawnAsyncWait. The GPUQueue.onSubmittedWorkDone is now handled by a callback on GrDawnGpu instead of per-fence callbacks since the latter cannot easily prevent a use-after-free if a fence is destroyed before the callback runs.
* Made several changes to the Bazel rules to work around an issue with the Closure compiler and Asyncify and a WASM code-size issue on debug builds.
* The native draw code now invokes Skia using the Dawn backend. The example uses `SkSurface::flushAndSubmit` and Emscripten's Asyncify feature to synchronize animation frames with the underlying WebGPU command queue completion.
* Cosmetic changes to the HTML with CSS and an animation loop that alternates the canvas color between cyan and magenta every second.
Added a radial gradient and a RuntimeEffect to the WebGPU demo. Both of these exercise shader creation and staging buffer allocation.
Also refactored the C++ code to reuse a GrDirectContext which highly improves the per-frame performance when using runtime effects. However this unfortunately triggers skbug.com/13266 so a work-around has been provided in which the context can conditionally get re-created every frame, as before.
GrDawnGpu tries to guarantee the CPU mapping invariants of GrDawnBuffer objects that are managed by a GrStagingBufferManager by issuing and tracking mapAsync requests following command buffer submission. However, this logic suffered from some issues where:
1. The code always assumed mapAsync succeeds. If a mapAsync request failed during shutdown due to a lost GPU connection, the GrDawnGpu destructor would spin forever waiting for pending mapAsync requests to complete. 2. If a client unmapped and then re-mapped a buffer that isn't managed by the async staging buffer logic in GrDawnGpu, the buffer would never get mapped and likely hit an assertion for a non-staging buffer.
These are now fixed:
* GrDawnBuffer now has more explicit error handling to make it more tolerant to mapAsync failures. * GrGpuBuffer now relies on mapAsync completion callbacks instead of spinning on `GrGpuBuffer::isMapped` as a buffer may never get mapped in the case of an error. This also has the benefit of tracking the mapAsync procedure state on a per-request basis intead of relying on state stored in GrDawnBuffer. The existing `fBusyStagingBuffers` has been replaced by a single reference counted `GrDawnAsyncWait` object. * A synchronous/blocking map function has been provided to satisfy the `GrGpuBuffer::onMap` contract. This method is not used in the existing staging buffer use cases in practice but it solves part of problem #2 above. * GrDawnGpu::onReadPixels now uses a GrDawnBuffer's blocking map functionality using the public GrGpuBuffer API. This has the same behavior as the existing blocking map that created and mapped a wgpu::Buffer directly. * The invariants around GrDawnBuffer lifetime and CPU mapping are documented in class level comments.
I have the initial round of API additions up for review here: https://skia-review.googlesource.com/c/skia/+/550327. I'm assigning this bug to myself as I'm currently driving it forward. My plan is to get an initial implementation of my proposed API functions working and available for testing. There will be a long tail of incremental CanvasKit API changes and additions to work better with WebGPU and my plan is to document and inform that future work following this initial milestone.
Git Watcher via monorail
unread,
Jun 16, 2022, 7:15:06 PM6/16/22
Reply to author
Sign in to reply to author
Forward
Sign in to forward
Delete
You do not have permission to delete messages in this group
Copy link
Report message
Show original message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
commit c0271d8db1ef44c881445c5560758b60658e9bbe Author: Arman Uguray <arma...@google.com> Date: Sat Jun 11 07:14:36 2022
[canvaskit] Enable WebGPU in GN build
* Skia GN can now build the Dawn backend without depending on Dawn native, provided that webgpu_cpp.h/webgpu_cpp.cpp is provided by emscripten. * Split gpu.js into webgl.js and webgpu.js. None of the CanvasKit API functions are wired up to WebGPU yet so it will use the CPU renderer. * Added new macros and GN args to distinguish between WebGPU and WebGL builds in CanvasKit, instead of relying on Skia GN args. * Renamed CANVASKIT_NO_ALIAS_FONT macro to CK_NO_ALIAS_FONT to match style.
Dawn headers and symbols for WASM are provided by emscripten and a direct dependency on Dawn native leads to conflicts in those builds. Fixed the ganesh/dawn Bazel rules to only depend on Dawn on non-wasm builds.
[canvaskit] Implement WebGPU API methods for surface creation
* The native backend exposes a variant of _MakeGrContext that creates a GrDirectContext backed by a Dawn wgpu::Device. * The native backend currently exposes a single API function, "_MakeGPUTextureSurface" which returns a SkSurface from Dawn backend render target over a Dawn wgpu::Texture. This function can be used to draw to any WebGPU texture, including offscreen textures or to a canvas swapchain texture. * The MakeGPUDeviceContext, MakeGPUCanvasContext, MakeGPUCanvasSurface functions are implemented purely in JavaScript. * The CanvasKit.webgpu property can be used to detect whether WebGPU support has been compiled in.
Several canvases in the npm_build/example.html demo now use WebGPU if it is supported by the browser and the CanvasKit build in use.
The examples have been refactored to support both WebGPU and non-WebGPU mode of usage. Two examples that currently rely on Surface.drawOnce don't work correctly on WebGPU as the API call may draw to the wrong swapchain texture ("paths" and "pathperson") and will benefit from a `WebGPUCanvasContext.drawOnce` function.