6 <canvas id="canvas" width="400" height="400"></canvas>
9 vertex float4 vertexShader(float4 position : attribute(0), float i : attribute(1)) : SV_Position {
13 fragment float4 fragmentShader(float4 position : SV_Position) : SV_Target 0 {
17 async function start() {
18 const adapter = await navigator.gpu.requestAdapter();
19 const device = await adapter.requestDevice();
21 const shaderModule = device.createShaderModule({code: shaderSource, isWHLSL: true});
22 const vertexStage = {module: shaderModule, entryPoint: "vertexShader"};
23 const fragmentStage = {module: shaderModule, entryPoint: "fragmentShader"};
24 const primitiveTopology = "triangle-strip";
25 const rasterizationState = {frontFace: "cw", cullMode: "none"};
26 const alphaBlend = {};
27 const colorBlend = {};
28 const colorStates = [{format: "rgba8unorm", alphaBlend, colorBlend, writeMask: 15}]; // GPUColorWriteBits.ALL
29 const depthStencilState = null;
31 const attribute0 = {shaderLocation: 0, inputSlot: 0, format: "float4"};
32 const attribute1 = {shaderLocation: 1, inputSlot: 1, format: "float"};
33 const attributes = [attribute0, attribute1];
34 const input0 = {inputSlot: 0, stride: 16 };
35 const input1 = {inputSlot: 1, stride: 4 };
36 const inputs = [input0, input1];
37 const inputState = {indexFormat: "uint32", attributes, inputs};
39 const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "uniform-buffer"}]};
40 const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor);
41 const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]};
42 const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
44 const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, inputState, sampleCount: 1, layout: pipelineLayout};
45 const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
47 const vertexBuffer0Descriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
48 const vertexBuffer0 = device.createBuffer(vertexBuffer0Descriptor);
49 const vertexBuffer0ArrayBuffer = await vertexBuffer0.mapWriteAsync();
50 const vertexBuffer0Float32Array = new Float32Array(vertexBuffer0ArrayBuffer);
51 vertexBuffer0Float32Array[0] = -0.5;
52 vertexBuffer0Float32Array[1] = -0.5;
53 vertexBuffer0Float32Array[2] = 1.0;
54 vertexBuffer0Float32Array[3] = 1;
55 vertexBuffer0Float32Array[4] = -0.5;
56 vertexBuffer0Float32Array[5] = 0.5;
57 vertexBuffer0Float32Array[6] = 1.0;
58 vertexBuffer0Float32Array[7] = 1;
59 vertexBuffer0Float32Array[8] = 0.5;
60 vertexBuffer0Float32Array[9] = -0.5;
61 vertexBuffer0Float32Array[10] = 1.0;
62 vertexBuffer0Float32Array[11] = 1;
63 vertexBuffer0Float32Array[12] = 0.5;
64 vertexBuffer0Float32Array[13] = 0.5;
65 vertexBuffer0Float32Array[14] = 1.0;
66 vertexBuffer0Float32Array[15] = 1;
67 vertexBuffer0.unmap();
69 const vertexBuffer1Descriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
70 const vertexBuffer1 = device.createBuffer(vertexBuffer1Descriptor);
71 const vertexBuffer1ArrayBuffer = await vertexBuffer1.mapWriteAsync();
72 const vertexBuffer1Float32Array = new Float32Array(vertexBuffer1ArrayBuffer);
73 vertexBuffer1Descriptor[0] = 1;
74 vertexBuffer1Descriptor[1] = 1;
75 vertexBuffer1Descriptor[2] = 1;
76 vertexBuffer1Descriptor[3] = 1;
77 vertexBuffer1.unmap();
79 const resourceBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.MAP_WRITE};
80 const resourceBuffer = device.createBuffer(resourceBufferDescriptor);
81 const resourceBufferArrayBuffer = await resourceBuffer.mapWriteAsync();
82 const resourceBufferFloat32Array = new Float32Array(resourceBufferArrayBuffer);
83 resourceBufferFloat32Array[0] = 1;
84 resourceBuffer.unmap();
86 const bufferBinding = {buffer: resourceBuffer, size: 4};
87 const bindGroupBinding = {binding: 0, resource: bufferBinding};
88 const bindGroupDescriptor = {layout: bindGroupLayout, bindings: [bindGroupBinding]};
89 const bindGroup = device.createBindGroup(bindGroupDescriptor);
91 const canvas = document.getElementById("canvas");
92 const context = canvas.getContext("gpu");
93 const swapChainDescriptor = {device, format: "bgra8unorm"};
94 const swapChain = context.configureSwapChain(swapChainDescriptor);
95 const outputTexture = swapChain.getCurrentTexture();
96 const outputTextureView = outputTexture.createDefaultView();
98 const commandEncoder = device.createCommandEncoder(); // {}
99 const red = {r: 0, g: 0, b: 1, a: 1};
100 const colorAttachments = [{attachment: outputTextureView, resolveTarget: null, loadOp: "clear", storeOp: "store", clearColor: red}];
101 const depthStencilAttachment = null;
102 const renderPassDescriptor = {colorAttachments, depthStencilAttachment};
103 const renderPassEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
104 renderPassEncoder.setPipeline(renderPipeline);
105 renderPassEncoder.setBindGroup(0, bindGroup);
106 renderPassEncoder.setVertexBuffers(0, [vertexBuffer0, vertexBuffer1], [0, 0]);
107 renderPassEncoder.draw(4, 1, 0, 0);
108 renderPassEncoder.endPass();
109 const commandBuffer = commandEncoder.finish();
110 device.getQueue().submit([commandBuffer]);
112 if (window.testRunner)
113 testRunner.notifyDone();
115 if (window.testRunner)
116 testRunner.waitUntilDone();
117 window.addEventListener("load", start);