REGRESSION: ( r246394 ) webgpu/whlsl-buffer-fragment.html and webgpu/whlsl-buffer...
[WebKit-https.git] / LayoutTests / webgpu / whlsl-null-dereference.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <script src="js/webgpu-functions.js"></script>
5 <script src="../resources/js-test-pre.js"></script>
6 </head>
7 <body>
8 <script>
9 const shaderSource = `
10 typedef Foo = thread int*;
11 Foo getNullPtr()
12 {
13     return null;
14 }
15
16 struct XYZ {
17     float x;
18     float y;
19     float z;
20 }
21
22 [numthreads(2, 1, 1)]
23 compute void computeShader(device float[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
24     Foo ptr = null;
25     *ptr = 42;
26     *getNullPtr() = 42;
27     if (*ptr == 0) {
28         if (ptr == getNullPtr()) {
29             if (*getNullPtr() == 0) {
30                 thread XYZ* xyzPtr = null;
31                 XYZ xyz;
32                 xyz.x = 1;
33                 xyz.y = 1;
34                 xyz.z = 1;
35                 if (xyz.z == 1.0 && xyz.y == 1.0 && xyz.z == 1.0) {
36                     *xyzPtr = xyz;
37                     xyz = *xyzPtr;
38                     if (xyz.z == 0.0 && xyz.y == 0.0 && xyz.z == 0.0) {
39                         if (&*getNullPtr() == null) {
40                             if (&*(&*getNullPtr()) == null) {
41                                 buffer[uint(threadID.x)] = buffer[uint(threadID.x)] * 2.0;
42                             }
43                         }
44                     }
45                 }
46             }
47         }
48     }
49 }
50 `;
51
52 async function start(device) {
53     const shaderModule = device.createShaderModule({code: shaderSource, isWHLSL: true});
54     const computeStage = {module: shaderModule, entryPoint: "computeShader"};
55
56     const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "storage-buffer"}]};
57     const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor);
58     const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]};
59     const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
60
61     const computePipelineDescriptor = {computeStage, layout: pipelineLayout};
62     const computePipeline = device.createComputePipeline(computePipelineDescriptor);
63
64     const size = Float32Array.BYTES_PER_ELEMENT * 8;
65
66     const bufferDescriptor = {size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.TRANSFER_SRC};
67     const buffer = device.createBuffer(bufferDescriptor);
68     const bufferArrayBuffer = await buffer.mapWriteAsync();
69     const bufferFloat32Array = new Float32Array(bufferArrayBuffer);
70     bufferFloat32Array[0] = 1;
71     bufferFloat32Array[1] = 2;
72     bufferFloat32Array[2] = 3;
73     bufferFloat32Array[3] = 4;
74     bufferFloat32Array[4] = 5;
75     bufferFloat32Array[5] = 6;
76     bufferFloat32Array[6] = 7;
77     bufferFloat32Array[7] = 8;
78     buffer.unmap();
79
80     const resultsBufferDescriptor = {size, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.MAP_READ};
81     const resultsBuffer = device.createBuffer(resultsBufferDescriptor);
82
83     const bufferBinding = {buffer: resultsBuffer, size};
84     const bindGroupBinding = {binding: 0, resource: bufferBinding};
85     const bindGroupDescriptor = {layout: bindGroupLayout, bindings: [bindGroupBinding]};
86     const bindGroup = device.createBindGroup(bindGroupDescriptor);
87
88     const commandEncoder = device.createCommandEncoder(); // {}
89     commandEncoder.copyBufferToBuffer(buffer, 0, resultsBuffer, 0, size);
90     const computePassEncoder = commandEncoder.beginComputePass();
91     computePassEncoder.setPipeline(computePipeline);
92     computePassEncoder.setBindGroup(0, bindGroup);
93     computePassEncoder.dispatch(2, 1, 1);
94     computePassEncoder.endPass();
95     const commandBuffer = commandEncoder.finish();
96     device.getQueue().submit([commandBuffer]);
97
98     const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
99     const resultsFloat32Array = new Float32Array(resultsArrayBuffer);
100     if (resultsFloat32Array[0] == 2
101         && resultsFloat32Array[1] == 4
102         && resultsFloat32Array[2] == 6
103         && resultsFloat32Array[3] == 8
104         && resultsFloat32Array[4] == 5
105         && resultsFloat32Array[5] == 6
106         && resultsFloat32Array[6] == 7
107         && resultsFloat32Array[7] == 8)
108         testPassed("");
109     else
110         testFailed("");
111     resultsBuffer.unmap();
112 }
113 window.jsTestIsAsync = true;
114 getBasicDevice().then(function(device) {
115     start(device).then(function() {
116         finishJSTest();
117     }, function() {
118         testFailed("");
119         finishJSTest();
120     });
121 }, function() {
122     testPassed("");
123     finishJSTest();
124 });
125 </script>
126 <script src="../resources/js-test-post.js"></script>
127 </body>
128 </html>