[WebGPU] Buffer updates part 1: async mapping functions, unmap, and destroy
[WebKit-https.git] / LayoutTests / webgpu / vertex-buffer-triangle-strip.html
1 <!DOCTYPE html>
2 <meta charset="utf-8">
3 <title>WebGPU Hello Triangles</title>
4 <meta name="assert" content="WebGPU correctly renders a green canvas.">
5 <link rel="match" href="vertex-buffer-triangle-strip-expected.html">
6 <p>Pass if square canvas below is completely green.</p>
7 <canvas width="400" height="400"></canvas>
8 <script src="js/webgpu-functions.js"></script>
9 <script>
10 const shaderCode = `
11 #include <metal_stdlib>
12     
13 using namespace metal;
14
15 struct VertexIn
16 {
17     float4 position [[attribute(0)]];
18     float green [[attribute(1)]];
19 };
20
21 struct VertexOut
22 {
23     float4 position [[position]];
24     float4 color;
25 };
26
27 vertex VertexOut vertex_main(VertexIn vertexIn [[stage_in]])
28 {
29     VertexOut vOut;
30     vOut.position = vertexIn.position;
31     vOut.color = float4(0, vertexIn.green, 0, 1);
32     return vOut;
33 }
34
35 fragment float4 fragment_main(VertexOut v [[stage_in]])
36 {
37     return v.color;
38 }
39 `
40
41 async function createVertexBuffer(device) {
42     const bufferSize = 4 * 5 * 4;
43     const buffer = device.createBuffer({ size: bufferSize, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE });
44     
45     await buffer.mapWriteAsync().then(mapping => {
46         let mappedArray = new Float32Array(mapping);
47         mappedArray.set([
48             // float4 xyzw, float g
49             -1, 1, 0, 1, 1,
50             -1, -1, 0, 1, 1,
51             1, 1, 0, 1, 1,
52             1, -1, 0, 1, 1
53         ]);
54         buffer.unmap();
55     });
56
57     return buffer;
58 }
59
60 function createInputStateDescriptor() {
61     return {
62         indexFormat: WebGPUIndexFormat.UINT32,
63         attributes: [{
64             shaderLocation: 0,
65             inputSlot: 0,
66             offset: 0,
67             format: WebGPUVertexFormat.FLOAT_R32_G32_B32_A32
68         }, {
69             shaderLocation: 1,
70             inputSlot: 0,
71             offset: 4 * 4,
72             format: WebGPUVertexFormat.FLOAT_R32
73         }],
74         inputs: [{
75             inputSlot: 0,
76             stride: 4 * 5,
77             stepMode: WebGPUInputStepMode.VERTEX
78         }]
79     }
80 }
81
82 async function test() {
83     const device = await getBasicDevice();
84     const canvas = document.querySelector("canvas");
85     const context = createBasicContext(canvas, device);
86     // FIXME: Replace with non-MSL shaders.
87     const shaderModule = device.createShaderModule({ code: shaderCode });
88     const vertexBuffer = await createVertexBuffer(device);
89     const inputStateDescriptor = createInputStateDescriptor();
90     const pipeline = createBasicPipeline(shaderModule, device, null, inputStateDescriptor);
91     const commandBuffer = device.createCommandBuffer();
92     const passEncoder = beginBasicRenderPass(context, commandBuffer);
93     const endCommandBuffer = encodeBasicCommands(passEncoder, pipeline, vertexBuffer);
94     const queue = device.getQueue();
95
96     queue.submit([endCommandBuffer]);
97     context.present();
98 }
99
100 test();
101 </script>