1cb93a386Sopenharmony_ci<!DOCTYPE html>
2cb93a386Sopenharmony_ci<title>Testing WebGPU compiled with Bazel</title>
3cb93a386Sopenharmony_ci<meta charset="utf-8" />
4cb93a386Sopenharmony_ci<meta http-equiv="X-UA-Compatible" content="IE=edge">
5cb93a386Sopenharmony_ci<meta name="viewport" content="width=device-width, initial-scale=1.0">
6cb93a386Sopenharmony_ci
7cb93a386Sopenharmony_ci<script type="text/javascript" src="/build/hello-world.js"></script>
8cb93a386Sopenharmony_ci
9cb93a386Sopenharmony_ci<p id="log"></p>
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ci<canvas id="webgpu-demo-canvas" width=500 height=500></canvas>
12cb93a386Sopenharmony_ci
13cb93a386Sopenharmony_ci<script type="text/javascript" charset="utf-8">
14cb93a386Sopenharmony_ci  if ("gpu" in navigator) {
15cb93a386Sopenharmony_ci    log("WebGPU detected")
16cb93a386Sopenharmony_ci    WebGPUDemo();
17cb93a386Sopenharmony_ci  } else {
18cb93a386Sopenharmony_ci    log("No WebGPU support.")
19cb93a386Sopenharmony_ci  }
20cb93a386Sopenharmony_ci
21cb93a386Sopenharmony_ci  function log(s) {
22cb93a386Sopenharmony_ci    document.getElementById("log").innerText = s;
23cb93a386Sopenharmony_ci  }
24cb93a386Sopenharmony_ci
25cb93a386Sopenharmony_ci  async function WebGPUDemo() {
26cb93a386Sopenharmony_ci    const adapter = await navigator.gpu.requestAdapter();
27cb93a386Sopenharmony_ci    if (!adapter) {
28cb93a386Sopenharmony_ci      log("Could not load an adapter. For Chrome, try running with --enable-features=Vulkan --enable-unsafe-webgpu");
29cb93a386Sopenharmony_ci      return;
30cb93a386Sopenharmony_ci    }
31cb93a386Sopenharmony_ci    const device = await adapter.requestDevice();
32cb93a386Sopenharmony_ci    console.log(adapter, device);
33cb93a386Sopenharmony_ci
34cb93a386Sopenharmony_ci    const wk = await WebGPUKitInit({locateFile: (file) => '/build/'+file});
35cb93a386Sopenharmony_ci    // https://github.com/emscripten-core/emscripten/issues/12750#issuecomment-725001907
36cb93a386Sopenharmony_ci    wk.preinitializedWebGPUDevice = device;
37cb93a386Sopenharmony_ci
38cb93a386Sopenharmony_ci    const surface = new wk.WebGPUSurface("#webgpu-demo-canvas", 500, 500);
39cb93a386Sopenharmony_ci
40cb93a386Sopenharmony_ci    const triangleVertexShader = surface.MakeShader(`[[stage(vertex)]]
41cb93a386Sopenharmony_cifn main([[builtin(vertex_index)]] VertexIndex : u32)
42cb93a386Sopenharmony_ci     -> [[builtin(position)]] vec4<f32> {
43cb93a386Sopenharmony_ci  var pos = array<vec2<f32>, 3>(
44cb93a386Sopenharmony_ci      vec2<f32>(0.0, 0.5),
45cb93a386Sopenharmony_ci      vec2<f32>(-0.5, -0.5),
46cb93a386Sopenharmony_ci      vec2<f32>(0.5, -0.5));
47cb93a386Sopenharmony_ci
48cb93a386Sopenharmony_ci  return vec4<f32>(pos[VertexIndex], 0.0, 1.0);
49cb93a386Sopenharmony_ci}`);
50cb93a386Sopenharmony_ci
51cb93a386Sopenharmony_ci    const redFragmentShader = surface.MakeShader(`[[stage(fragment)]]
52cb93a386Sopenharmony_cifn main() -> [[location(0)]] vec4<f32> {
53cb93a386Sopenharmony_ci  return vec4<f32>(1.0, 0.0, 0.0, 1.0);
54cb93a386Sopenharmony_ci}`);
55cb93a386Sopenharmony_ci
56cb93a386Sopenharmony_ci    const pipeline = surface.MakeRenderPipeline(triangleVertexShader, redFragmentShader);
57cb93a386Sopenharmony_ci
58cb93a386Sopenharmony_ci    const startTime = Date.now();
59cb93a386Sopenharmony_ci    function frame() {
60cb93a386Sopenharmony_ci      const now = Date.now();
61cb93a386Sopenharmony_ci      surface.drawPipeline(pipeline,
62cb93a386Sopenharmony_ci        Math.abs(Math.sin((startTime - now) / 500)), // red
63cb93a386Sopenharmony_ci        Math.abs(Math.sin((startTime - now) / 600)), // green
64cb93a386Sopenharmony_ci        Math.abs(Math.sin((startTime - now) / 700)), // blue
65cb93a386Sopenharmony_ci        1.0);
66cb93a386Sopenharmony_ci      requestAnimationFrame(frame);
67cb93a386Sopenharmony_ci    }
68cb93a386Sopenharmony_ci    requestAnimationFrame(frame);
69cb93a386Sopenharmony_ci  }
70cb93a386Sopenharmony_ci</script>