| <script src="../../resources/js-test-pre.js"></script> | |
| <script> | |
| globalThis.testRunner?.dumpAsText(); | |
| globalThis.testRunner?.waitUntilDone(); | |
| const log = globalThis.$vm?.print ?? console.log; | |
| onload = async () => { | |
| let adapter = await navigator.gpu.requestAdapter({}); | |
| let device = await adapter.requestDevice({}); | |
| device.pushErrorScope('validation'); | |
| let code = ` | |
| struct ad { | |
| c: u32, | |
| af: array<u32>, | |
| } | |
| @group(0) @binding(0) var<storage, read_write> ac: ad; | |
| fn y(t: ptr<storage, array<u32>, read_write>) { | |
| t[0] = 1; | |
| } | |
| fn x(t: ptr<storage, ad, read_write>) { | |
| t.af[2] = 3; | |
| y(&t.af); | |
| } | |
| fn f() | |
| { | |
| ac.c = 13; | |
| x(&ac); | |
| } | |
| var<private> g: u32; | |
| fn z(t: ptr<storage, array<u32>, read_write>) { | |
| g = t[0]; | |
| g = ac.af[1]; | |
| } | |
| fn w(t: ptr<storage, ad, read_write>) { | |
| g = t.af[2]; | |
| g = ac.af[3]; | |
| z(&t.af); | |
| } | |
| fn h() | |
| { | |
| g = ac.c; | |
| w(&ac); | |
| } | |
| @compute @workgroup_size(1) | |
| fn main() | |
| { | |
| f(); | |
| } | |
| `; | |
| let module = device.createShaderModule({code}); | |
| let bindGroupLayout0 = device.createBindGroupLayout({ | |
| entries: [ | |
| {binding: 0, buffer: {type: 'storage'}, visibility: GPUShaderStage.COMPUTE}, | |
| ], | |
| }); | |
| let buffer0 = device.createBuffer({ | |
| size: 32, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC, | |
| }); | |
| await device.queue.onSubmittedWorkDone(); | |
| let bindGroup0 = device.createBindGroup({ | |
| layout: bindGroupLayout0, entries: [ | |
| {binding: 0, resource: {buffer: buffer0}}, | |
| ], | |
| }); | |
| let pipelineLayout = device.createPipelineLayout({bindGroupLayouts: [bindGroupLayout0]}); | |
| let commandEncoder = device.createCommandEncoder(); | |
| let computePassEncoder = commandEncoder.beginComputePass({}); | |
| let computePipeline = device.createComputePipeline({layout: pipelineLayout, compute: {module}}); | |
| computePassEncoder.setPipeline(computePipeline); | |
| computePassEncoder.setBindGroup(0, bindGroup0); | |
| computePassEncoder.dispatchWorkgroups(1); | |
| computePassEncoder.end(); | |
| let outputBuffer0 = device.createBuffer({size: buffer0.size, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ}); | |
| commandEncoder.copyBufferToBuffer(buffer0, 0, outputBuffer0, 0, buffer0.size); | |
| device.queue.submit([commandEncoder.finish()]); | |
| await device.queue.onSubmittedWorkDone(); | |
| await outputBuffer0.mapAsync(GPUMapMode.READ); | |
| output = [...new Uint32Array(outputBuffer0.getMappedRange())] | |
| shouldBe('output[0]', '13'); | |
| shouldBe('output[1]', '1'); | |
| shouldBe('output[2]', '0'); | |
| shouldBe('output[3]', '3'); | |
| shouldBe('output[4]', '0'); | |
| outputBuffer0.unmap(); | |
| let error = await device.popErrorScope(); | |
| if (error) { | |
| log(error.message); | |
| } else { | |
| log('no validation error'); | |
| } | |
| globalThis.testRunner?.notifyDone(); | |
| }; | |
| </script> |