<!DOCTYPE html>
<html>
<head>
<script src="../js/webgpu-functions.js"></script>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script>
const shaderSource = `
[numthreads(1, 1, 1)]
compute void computeShader(device float4x4[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
    float4x4 result;
    result[0] = float4(1, 2, 3, 4);
    result[1] = float4(5, 6, 7, 8);
    result[2] = float4(9, 10, 11, 12);
    result[3] = float4(13, 14, 15, 16);

    float4x4 mat = buffer[0];

    if (mat[0][0] == 0
        && mat[0][1] == 1
        && mat[0][2] == 2
        && mat[0][3] == 3

        && mat[1][0] == 4
        && mat[1][1] == 5
        && mat[1][2] == 6
        && mat[1][3] == 7

        && mat[2][0] == 8
        && mat[2][1] == 9
        && mat[2][2] == 10
        && mat[2][3] == 11

        && mat[3][0] == 12
        && mat[3][1] == 13
        && mat[3][2] == 14
        && mat[3][3] == 15) {
        buffer[0] = result;
    }
}
`;

async function start(device) {
    const shaderModule = device.createShaderModule({code: shaderSource});
    const computeStage = {module: shaderModule, entryPoint: "computeShader"};

    const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "storage-buffer"}]};
    const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor);
    const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]};
    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);

    const computePipelineDescriptor = {computeStage, layout: pipelineLayout};
    const computePipeline = device.createComputePipeline(computePipelineDescriptor);

    const size = Float32Array.BYTES_PER_ELEMENT * 16;

    const bufferDescriptor = {size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.COPY_SRC};
    const buffer = device.createBuffer(bufferDescriptor);
    const bufferArrayBuffer = await buffer.mapWriteAsync();
    const bufferFloat32Array = new Float32Array(bufferArrayBuffer);
    bufferFloat32Array[0] = 0;
    bufferFloat32Array[1] = 1;
    bufferFloat32Array[2] = 2;
    bufferFloat32Array[3] = 3;
    bufferFloat32Array[4] = 4;
    bufferFloat32Array[5] = 5;
    bufferFloat32Array[6] = 6;
    bufferFloat32Array[7] = 7;
    bufferFloat32Array[8] = 8;
    bufferFloat32Array[9] = 9;
    bufferFloat32Array[10] = 10;
    bufferFloat32Array[11] = 11;
    bufferFloat32Array[12] = 12;
    bufferFloat32Array[13] = 13;
    bufferFloat32Array[14] = 14;
    bufferFloat32Array[15] = 15;
    buffer.unmap();

    const resultsBufferDescriptor = {size, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ};
    const resultsBuffer = device.createBuffer(resultsBufferDescriptor);

    const bufferBinding = {buffer: resultsBuffer, size};
    const bindGroupBinding = {binding: 0, resource: bufferBinding};
    const bindGroupDescriptor = {layout: bindGroupLayout, bindings: [bindGroupBinding]};
    const bindGroup = device.createBindGroup(bindGroupDescriptor);

    const commandEncoder = device.createCommandEncoder(); // {}
    commandEncoder.copyBufferToBuffer(buffer, 0, resultsBuffer, 0, size);
    const computePassEncoder = commandEncoder.beginComputePass();
    computePassEncoder.setPipeline(computePipeline);
    computePassEncoder.setBindGroup(0, bindGroup);
    computePassEncoder.dispatch(2, 1, 1);
    computePassEncoder.endPass();
    const commandBuffer = commandEncoder.finish();
    device.getQueue().submit([commandBuffer]);

    const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
    const resultsFloat32Array = new Float32Array(resultsArrayBuffer);
    if (resultsFloat32Array[0] === 1
        && resultsFloat32Array[1] === 2
        && resultsFloat32Array[2] === 3
        && resultsFloat32Array[3] === 4

        && resultsFloat32Array[4] === 5
        && resultsFloat32Array[5] === 6
        && resultsFloat32Array[6] === 7
        && resultsFloat32Array[7] === 8

        && resultsFloat32Array[8] === 9
        && resultsFloat32Array[9] === 10
        && resultsFloat32Array[10] === 11
        && resultsFloat32Array[11] === 12

        && resultsFloat32Array[12] === 13
        && resultsFloat32Array[13] === 14
        && resultsFloat32Array[14] === 15
        && resultsFloat32Array[15] === 16)
        testPassed("");
    else
        testFailed("");
    resultsBuffer.unmap();
}
window.jsTestIsAsync = true;
getBasicDevice().then(function(device) {
    start(device).then(function() {
        finishJSTest();
    }, function() {
        testFailed("");
        finishJSTest();
    });
}, function() {
    testPassed("");
    finishJSTest();
});
</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
