262dfbafb4
This uses the Bazel rule wasm_cc_binary, which is defined in @emsdk [1] Note that wasm_cc_binary does not have a linkopts argument defined, so we instead put any emcc options in the cc_binary target. This works around a few bugs in the emsdk Bazel rules: - https://github.com/emscripten-core/emsdk/issues/907 - https://github.com/emscripten-core/emsdk/issues/807 Prior to PS 5, this CL tried a different way to bring in the toolchain, a more manual way outlined in [2]. A similar approach (modifying the .bazelrc and specifying the toolchain directly) might be necessary at some point, but can probably still be done using the @emsdk Bazel rules and --config=wasm. To update the version of emscripten used, we just need to update the parameter in the WORKSPACE call to emsdk_emscripten_deps(). The example/index.html file in this CL does exactly the same as [3], except the WebGPU calls are made from C++ via WASM. I made heavy use of these examples [4], [5] while exploring APIs. What was also useful was looking at the emscripten source headers [6], [7], [8], [9]. I also learned a lot about WebGPU from [10]. [1]3891e7b04b/bazel/emscripten_toolchain/wasm_cc_binary.bzl
[2] https://hackernoon.com/c-to-webassembly-using-bazel-and-emscripten-4him3ymc [3]206c1f3f7e/demos.skia.org/demos/webgpu/index.html
[4] https://github.com/kainino0x/webgpu-cross-platform-demo [5] https://github.com/Twinklebear/wgpu-cpp-starter [6]5e6c74153b/system/include/emscripten/html5_webgpu.h
[7]5e6c74153b/system/include/webgpu/webgpu.h
[8]5e6c74153b/system/include/webgpu/webgpu_cpp.h
[9]5e6c74153b/src/library_html5_webgpu.js (L24)
[10] https://alain.xyz/blog/raw-webgpu Change-Id: Iff33b72e7265200b2caacbc03e5fcc06a650b56b Reviewed-on: https://skia-review.googlesource.com/c/skia/+/457396 Reviewed-by: Leandro Lovisolo <lovisolo@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
70 lines
2.2 KiB
HTML
70 lines
2.2 KiB
HTML
<!DOCTYPE html>
|
|
<title>Testing WebGPU compiled with Bazel</title>
|
|
<meta charset="utf-8" />
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
<script type="text/javascript" src="/build/hello-world.js"></script>
|
|
|
|
<p id="log"></p>
|
|
|
|
<canvas id="webgpu-demo-canvas" width=500 height=500></canvas>
|
|
|
|
<script type="text/javascript" charset="utf-8">
|
|
if ("gpu" in navigator) {
|
|
log("WebGPU detected")
|
|
WebGPUDemo();
|
|
} else {
|
|
log("No WebGPU support.")
|
|
}
|
|
|
|
function log(s) {
|
|
document.getElementById("log").innerText = s;
|
|
}
|
|
|
|
async function WebGPUDemo() {
|
|
const adapter = await navigator.gpu.requestAdapter();
|
|
if (!adapter) {
|
|
log("Could not load an adapter. For Chrome, try running with --enable-features=Vulkan --enable-unsafe-webgpu");
|
|
return;
|
|
}
|
|
const device = await adapter.requestDevice();
|
|
console.log(adapter, device);
|
|
|
|
const wk = await WebGPUKitInit({locateFile: (file) => '/build/'+file});
|
|
// https://github.com/emscripten-core/emscripten/issues/12750#issuecomment-725001907
|
|
wk.preinitializedWebGPUDevice = device;
|
|
|
|
const surface = new wk.WebGPUSurface("#webgpu-demo-canvas", 500, 500);
|
|
|
|
const triangleVertexShader = surface.MakeShader(`[[stage(vertex)]]
|
|
fn main([[builtin(vertex_index)]] VertexIndex : u32)
|
|
-> [[builtin(position)]] vec4<f32> {
|
|
var pos = array<vec2<f32>, 3>(
|
|
vec2<f32>(0.0, 0.5),
|
|
vec2<f32>(-0.5, -0.5),
|
|
vec2<f32>(0.5, -0.5));
|
|
|
|
return vec4<f32>(pos[VertexIndex], 0.0, 1.0);
|
|
}`);
|
|
|
|
const redFragmentShader = surface.MakeShader(`[[stage(fragment)]]
|
|
fn main() -> [[location(0)]] vec4<f32> {
|
|
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
|
}`);
|
|
|
|
const pipeline = surface.MakeRenderPipeline(triangleVertexShader, redFragmentShader);
|
|
|
|
const startTime = Date.now();
|
|
function frame() {
|
|
const now = Date.now();
|
|
surface.drawPipeline(pipeline,
|
|
Math.abs(Math.sin((startTime - now) / 500)), // red
|
|
Math.abs(Math.sin((startTime - now) / 600)), // green
|
|
Math.abs(Math.sin((startTime - now) / 700)), // blue
|
|
1.0);
|
|
requestAnimationFrame(frame);
|
|
}
|
|
requestAnimationFrame(frame);
|
|
}
|
|
</script> |