xref: /aosp_15_r20/external/skia/demos.skia.org/demos/webgpu/index.html (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker<!DOCTYPE html>
2*c8dee2aaSAndroid Build Coastguard Worker<title>Web GPU Demo</title>
3*c8dee2aaSAndroid Build Coastguard Worker<meta charset="utf-8" />
4*c8dee2aaSAndroid Build Coastguard Worker<meta http-equiv="X-UA-Compatible" content="IE=edge">
5*c8dee2aaSAndroid Build Coastguard Worker<meta name="viewport" content="width=device-width, initial-scale=1.0">
6*c8dee2aaSAndroid Build Coastguard Worker<!-- For *.skia.org https://developer.chrome.com/origintrials/#/registration/2983494015644598273
7*c8dee2aaSAndroid Build Coastguard Worker     Expires Nov 19, 2021
8*c8dee2aaSAndroid Build Coastguard Worker     -->
9*c8dee2aaSAndroid Build Coastguard Worker<meta http-equiv="origin-trial" content="AnRs8mYss+Awd1DPUg2VfjXJbw2087/Dysaa3L7JmrbzTkwoEr87cX3y0zUfTGOFSLKJLRqNEmFAwfy+uumVXQsAAABbeyJvcmlnaW4iOiJodHRwczovL3NraWEub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJHUFUiLCJleHBpcnkiOjE2NDMxNTUxOTksImlzU3ViZG9tYWluIjp0cnVlfQ==">
10*c8dee2aaSAndroid Build Coastguard Worker
11*c8dee2aaSAndroid Build Coastguard Worker<!-- For localhost:8123 https://developer.chrome.com/origintrials/#/registration/6568359319031513089
12*c8dee2aaSAndroid Build Coastguard Worker     Expires Nov 19, 2021
13*c8dee2aaSAndroid Build Coastguard Worker     -->
14*c8dee2aaSAndroid Build Coastguard Worker<meta http-equiv="origin-trial" content="ArQyw1ckz8lMOAcs5BbhOVJh2A6KMhYL6w/rTjPNnViqZyfFhlyJ5hnuHARoCkS1ZKiJi+YbsFvPWy23ePkFMQgAAABJeyJvcmlnaW4iOiJodHRwOi8vbG9jYWxob3N0OjgxMjMiLCJmZWF0dXJlIjoiV2ViR1BVIiwiZXhwaXJ5IjoxNjQzMTU1MTk5fQ==">
15*c8dee2aaSAndroid Build Coastguard Worker
16*c8dee2aaSAndroid Build Coastguard Worker<style>
17*c8dee2aaSAndroid Build Coastguard Worker  canvas {
18*c8dee2aaSAndroid Build Coastguard Worker    border: 1px dashed grey;
19*c8dee2aaSAndroid Build Coastguard Worker  }
20*c8dee2aaSAndroid Build Coastguard Worker</style>
21*c8dee2aaSAndroid Build Coastguard Worker
22*c8dee2aaSAndroid Build Coastguard Worker<body>
23*c8dee2aaSAndroid Build Coastguard Worker  <h1>WebGPU Test</h1>
24*c8dee2aaSAndroid Build Coastguard Worker  <pre id="log"></pre>
25*c8dee2aaSAndroid Build Coastguard Worker
26*c8dee2aaSAndroid Build Coastguard Worker  <canvas id=draw width=500 height=500></canvas>
27*c8dee2aaSAndroid Build Coastguard Worker</body>
28*c8dee2aaSAndroid Build Coastguard Worker
29*c8dee2aaSAndroid Build Coastguard Worker<script type="text/javascript" charset="utf-8">
30*c8dee2aaSAndroid Build Coastguard Worker  if ("gpu" in navigator) {
31*c8dee2aaSAndroid Build Coastguard Worker    log("WebGPU detected")
32*c8dee2aaSAndroid Build Coastguard Worker    WebGPUDemo();
33*c8dee2aaSAndroid Build Coastguard Worker  } else {
34*c8dee2aaSAndroid Build Coastguard Worker    log("No WebGPU support.")
35*c8dee2aaSAndroid Build Coastguard Worker  }
36*c8dee2aaSAndroid Build Coastguard Worker
37*c8dee2aaSAndroid Build Coastguard Worker  function log(s) {
38*c8dee2aaSAndroid Build Coastguard Worker    document.getElementById("log").innerText = s;
39*c8dee2aaSAndroid Build Coastguard Worker  }
40*c8dee2aaSAndroid Build Coastguard Worker
41*c8dee2aaSAndroid Build Coastguard Worker  async function WebGPUDemo() {
42*c8dee2aaSAndroid Build Coastguard Worker    // Adapted from https://github.com/austinEng/webgpu-samples/blob/main/src/sample/helloTriangle/main.ts
43*c8dee2aaSAndroid Build Coastguard Worker    const adapter = await navigator.gpu.requestAdapter();
44*c8dee2aaSAndroid Build Coastguard Worker    if (!adapter) {
45*c8dee2aaSAndroid Build Coastguard Worker      log("Could not load an adapter. For Chrome, try running with --enable-features=Vulkan --enable-unsafe-webgpu");
46*c8dee2aaSAndroid Build Coastguard Worker      return;
47*c8dee2aaSAndroid Build Coastguard Worker    }
48*c8dee2aaSAndroid Build Coastguard Worker
49*c8dee2aaSAndroid Build Coastguard Worker    const device = await adapter.requestDevice();
50*c8dee2aaSAndroid Build Coastguard Worker    console.log(adapter, device);
51*c8dee2aaSAndroid Build Coastguard Worker    const canvas = document.getElementById("draw");
52*c8dee2aaSAndroid Build Coastguard Worker    const context = canvas.getContext('webgpu');
53*c8dee2aaSAndroid Build Coastguard Worker    if (!context) {
54*c8dee2aaSAndroid Build Coastguard Worker      log("Could not load webgpu context");
55*c8dee2aaSAndroid Build Coastguard Worker      return;
56*c8dee2aaSAndroid Build Coastguard Worker    }
57*c8dee2aaSAndroid Build Coastguard Worker    console.log(context);
58*c8dee2aaSAndroid Build Coastguard Worker
59*c8dee2aaSAndroid Build Coastguard Worker    const devicePixelRatio = window.devicePixelRatio || 1;
60*c8dee2aaSAndroid Build Coastguard Worker    const presentationSize = [
61*c8dee2aaSAndroid Build Coastguard Worker      canvas.clientWidth * devicePixelRatio,
62*c8dee2aaSAndroid Build Coastguard Worker      canvas.clientHeight * devicePixelRatio,
63*c8dee2aaSAndroid Build Coastguard Worker    ];
64*c8dee2aaSAndroid Build Coastguard Worker    const presentationFormat = context.getPreferredFormat(adapter);
65*c8dee2aaSAndroid Build Coastguard Worker
66*c8dee2aaSAndroid Build Coastguard Worker    context.configure({
67*c8dee2aaSAndroid Build Coastguard Worker      device,
68*c8dee2aaSAndroid Build Coastguard Worker      format: presentationFormat,
69*c8dee2aaSAndroid Build Coastguard Worker      size: presentationSize,
70*c8dee2aaSAndroid Build Coastguard Worker    });
71*c8dee2aaSAndroid Build Coastguard Worker
72*c8dee2aaSAndroid Build Coastguard Worker    const triangleVertWGSL = `[[stage(vertex)]]
73*c8dee2aaSAndroid Build Coastguard Workerfn main([[builtin(vertex_index)]] VertexIndex : u32)
74*c8dee2aaSAndroid Build Coastguard Worker     -> [[builtin(position)]] vec4<f32> {
75*c8dee2aaSAndroid Build Coastguard Worker  var pos = array<vec2<f32>, 3>(
76*c8dee2aaSAndroid Build Coastguard Worker      vec2<f32>(0.0, 0.5),
77*c8dee2aaSAndroid Build Coastguard Worker      vec2<f32>(-0.5, -0.5),
78*c8dee2aaSAndroid Build Coastguard Worker      vec2<f32>(0.5, -0.5));
79*c8dee2aaSAndroid Build Coastguard Worker
80*c8dee2aaSAndroid Build Coastguard Worker  return vec4<f32>(pos[VertexIndex], 0.0, 1.0);
81*c8dee2aaSAndroid Build Coastguard Worker}`;
82*c8dee2aaSAndroid Build Coastguard Worker
83*c8dee2aaSAndroid Build Coastguard Worker    const redFragWGSL = `[[stage(fragment)]]
84*c8dee2aaSAndroid Build Coastguard Workerfn main() -> [[location(0)]] vec4<f32> {
85*c8dee2aaSAndroid Build Coastguard Worker  return vec4<f32>(1.0, 0.0, 0.0, 1.0);
86*c8dee2aaSAndroid Build Coastguard Worker}`;
87*c8dee2aaSAndroid Build Coastguard Worker
88*c8dee2aaSAndroid Build Coastguard Worker    const pipeline = device.createRenderPipeline({
89*c8dee2aaSAndroid Build Coastguard Worker      vertex: {
90*c8dee2aaSAndroid Build Coastguard Worker        module: device.createShaderModule({
91*c8dee2aaSAndroid Build Coastguard Worker          code: triangleVertWGSL,
92*c8dee2aaSAndroid Build Coastguard Worker        }),
93*c8dee2aaSAndroid Build Coastguard Worker        entryPoint: 'main',
94*c8dee2aaSAndroid Build Coastguard Worker      },
95*c8dee2aaSAndroid Build Coastguard Worker      fragment: {
96*c8dee2aaSAndroid Build Coastguard Worker        module: device.createShaderModule({
97*c8dee2aaSAndroid Build Coastguard Worker          code: redFragWGSL,
98*c8dee2aaSAndroid Build Coastguard Worker        }),
99*c8dee2aaSAndroid Build Coastguard Worker        entryPoint: 'main',
100*c8dee2aaSAndroid Build Coastguard Worker        targets: [
101*c8dee2aaSAndroid Build Coastguard Worker          {
102*c8dee2aaSAndroid Build Coastguard Worker            format: presentationFormat,
103*c8dee2aaSAndroid Build Coastguard Worker          },
104*c8dee2aaSAndroid Build Coastguard Worker        ],
105*c8dee2aaSAndroid Build Coastguard Worker      },
106*c8dee2aaSAndroid Build Coastguard Worker      primitive: {
107*c8dee2aaSAndroid Build Coastguard Worker        topology: 'triangle-list',
108*c8dee2aaSAndroid Build Coastguard Worker      },
109*c8dee2aaSAndroid Build Coastguard Worker    });
110*c8dee2aaSAndroid Build Coastguard Worker
111*c8dee2aaSAndroid Build Coastguard Worker    console.log(pipeline);
112*c8dee2aaSAndroid Build Coastguard Worker
113*c8dee2aaSAndroid Build Coastguard Worker    const startTime = Date.now();
114*c8dee2aaSAndroid Build Coastguard Worker    function frame() {
115*c8dee2aaSAndroid Build Coastguard Worker      const now = Date.now();
116*c8dee2aaSAndroid Build Coastguard Worker      const commandEncoder = device.createCommandEncoder();
117*c8dee2aaSAndroid Build Coastguard Worker      const textureView = context.getCurrentTexture().createView();
118*c8dee2aaSAndroid Build Coastguard Worker
119*c8dee2aaSAndroid Build Coastguard Worker      const renderPassDescriptor = {
120*c8dee2aaSAndroid Build Coastguard Worker        colorAttachments: [
121*c8dee2aaSAndroid Build Coastguard Worker          {
122*c8dee2aaSAndroid Build Coastguard Worker            view: textureView,
123*c8dee2aaSAndroid Build Coastguard Worker            loadValue: {
124*c8dee2aaSAndroid Build Coastguard Worker              r: Math.abs(Math.sin((startTime - now) / 500)),
125*c8dee2aaSAndroid Build Coastguard Worker              g: Math.abs(Math.sin((startTime - now) / 600)),
126*c8dee2aaSAndroid Build Coastguard Worker              b: Math.abs(Math.sin((startTime - now) / 700)),
127*c8dee2aaSAndroid Build Coastguard Worker              a: 1.0 },
128*c8dee2aaSAndroid Build Coastguard Worker            storeOp: 'store',
129*c8dee2aaSAndroid Build Coastguard Worker          },
130*c8dee2aaSAndroid Build Coastguard Worker        ],
131*c8dee2aaSAndroid Build Coastguard Worker      };
132*c8dee2aaSAndroid Build Coastguard Worker
133*c8dee2aaSAndroid Build Coastguard Worker      const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
134*c8dee2aaSAndroid Build Coastguard Worker      passEncoder.setPipeline(pipeline);
135*c8dee2aaSAndroid Build Coastguard Worker      passEncoder.draw(3, 1, 0, 0);
136*c8dee2aaSAndroid Build Coastguard Worker      passEncoder.endPass();
137*c8dee2aaSAndroid Build Coastguard Worker
138*c8dee2aaSAndroid Build Coastguard Worker      device.queue.submit([commandEncoder.finish()]);
139*c8dee2aaSAndroid Build Coastguard Worker      requestAnimationFrame(frame);
140*c8dee2aaSAndroid Build Coastguard Worker    }
141*c8dee2aaSAndroid Build Coastguard Worker
142*c8dee2aaSAndroid Build Coastguard Worker    requestAnimationFrame(frame);
143*c8dee2aaSAndroid Build Coastguard Worker  }
144*c8dee2aaSAndroid Build Coastguard Worker</script>