8093e8511c64cd40cde384291e277faa100624cb
[WebKit-https.git] / LayoutTests / webgpu / whlsl-compute.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <script src="../resources/js-test-pre.js"></script>
5 </head>
6 <body>
7 <script>
8 const shaderSource = `
9 [numthreads(2, 1, 1)]
10 compute void computeShader(device float[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
11     buffer[uint(threadID.x)] = buffer[uint(threadID.x)] * 2.0;
12 }
13 `;
14 let resultsFloat32Array;
15 async function start() {
16     const adapter = await navigator.gpu.requestAdapter();
17     const device = await adapter.requestDevice();
18
19     const shaderModule = device.createShaderModule({code: shaderSource, isWHLSL: true});
20     const computeStage = {module: shaderModule, entryPoint: "computeShader"};
21
22     const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "storage-buffer"}]};
23     const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor);
24     const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]};
25     const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
26
27     const computePipelineDescriptor = {computeStage, layout: pipelineLayout};
28     const computePipeline = device.createComputePipeline(computePipelineDescriptor);
29
30     const size = Float32Array.BYTES_PER_ELEMENT * 8;
31
32     const bufferDescriptor = {size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.TRANSFER_SRC};
33     const buffer = device.createBuffer(bufferDescriptor);
34     const bufferArrayBuffer = await buffer.mapWriteAsync();
35     const bufferFloat32Array = new Float32Array(bufferArrayBuffer);
36     bufferFloat32Array[0] = 1;
37     bufferFloat32Array[1] = 2;
38     bufferFloat32Array[2] = 3;
39     bufferFloat32Array[3] = 4;
40     bufferFloat32Array[4] = 5;
41     bufferFloat32Array[5] = 6;
42     bufferFloat32Array[6] = 7;
43     bufferFloat32Array[7] = 8;
44     buffer.unmap();
45
46     const resultsBufferDescriptor = {size, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.MAP_READ};
47     const resultsBuffer = device.createBuffer(resultsBufferDescriptor);
48
49     const bufferBinding = {buffer: resultsBuffer, size};
50     const bindGroupBinding = {binding: 0, resource: bufferBinding};
51     const bindGroupDescriptor = {layout: bindGroupLayout, bindings: [bindGroupBinding]};
52     const bindGroup = device.createBindGroup(bindGroupDescriptor);
53
54     const commandEncoder = device.createCommandEncoder(); // {}
55     commandEncoder.copyBufferToBuffer(buffer, 0, resultsBuffer, 0, size);
56     const computePassEncoder = commandEncoder.beginComputePass();
57     computePassEncoder.setPipeline(computePipeline);
58     computePassEncoder.setBindGroup(0, bindGroup);
59     computePassEncoder.dispatch(2, 1, 1);
60     computePassEncoder.endPass();
61     const commandBuffer = commandEncoder.finish();
62     device.getQueue().submit([commandBuffer]);
63
64     const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
65     resultsFloat32Array = new Float32Array(resultsArrayBuffer);
66     shouldBe("resultsFloat32Array[0]", "2");
67     shouldBe("resultsFloat32Array[1]", "4");
68     shouldBe("resultsFloat32Array[2]", "6");
69     shouldBe("resultsFloat32Array[3]", "8");
70     shouldBe("resultsFloat32Array[4]", "5");
71     shouldBe("resultsFloat32Array[5]", "6");
72     shouldBe("resultsFloat32Array[6]", "7");
73     shouldBe("resultsFloat32Array[7]", "8");
74     resultsBuffer.unmap();
75 }
76 window.jsTestIsAsync = true;
77 window.addEventListener("load", function() {
78     start().then(function() {
79         finishJSTest();
80     }, function() {
81         finishJSTest();
82     });
83 });
84 </script>
85 <script src="../resources/js-test-post.js"></script>
86 </body>
87 </html>