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