<!DOCTYPE html>
<html>
<head>
<script src="../resources/js-test-pre.js"></script>
</head>
<body>
<script>
const shaderSource = `
bool allEqual(float2x3 mat, float value)
{
    for (uint i = 0; i < 2; i = i + 1) {
        for (uint j = 0; j < 3; j = j + 1) {
            if (mat[i][j] != value)
                return false;
        }
    }
    return true;
}

[numthreads(1, 1, 1)]
compute void computeShader(device float[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
    float2x3 foo;
    if (!allEqual(foo, 0))
        return;

    foo = foo + 1.0;
    if (!allEqual(foo, 1))
        return;

    foo = foo * 8.5;
    if (!allEqual(foo, 8.5))
        return;

    foo = foo - 7.5;
    if (!allEqual(foo, 1))
        return;

    foo = foo + 1.0;
    if (!allEqual(foo, 2))
        return;

    foo = foo + foo;
    if (!allEqual(foo, 4))
        return;

    foo = foo + foo;
    if (!allEqual(foo, 8))
        return;

    float3 fourtyTwo;
    fourtyTwo.x = 42;
    fourtyTwo.y = 42;
    fourtyTwo.z = 42;

    foo[0] = fourtyTwo;
    foo[1] = fourtyTwo;
    if (!allEqual(foo, 42))
        return;

    foo[1337] = fourtyTwo;
    if (!allEqual(foo, 42))
        return;

    foo[1000000] = fourtyTwo;
    if (!allEqual(foo, 42))
        return;

    fourtyTwo[1337] = 50;
    foo[1] = fourtyTwo;
    if (!allEqual(foo, 42))
        return;

    fourtyTwo[1000000] = 50;
    foo[1] = fourtyTwo;
    if (!allEqual(foo, 42))
        return;

    float3 shouldBeZero = foo[100000];
    if (shouldBeZero.x != 0 || shouldBeZero.y != 0 || shouldBeZero.z != 0)
        return;

    if (fourtyTwo[10000000] != 0)
        return;

    buffer[uint(threadID.x)] = buffer[uint(threadID.x)] * 2.0;
}
`;
let resultsFloat32Array;
async function start() {
    const adapter = await navigator.gpu.requestAdapter();
    const device = await adapter.requestDevice();

    const shaderModule = device.createShaderModule({code: shaderSource, isWHLSL: true});
    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 * 8;

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

    const resultsBufferDescriptor = {size, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.TRANSFER_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(4, 1, 1);
    computePassEncoder.endPass();
    const commandBuffer = commandEncoder.finish();
    device.getQueue().submit([commandBuffer]);

    const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
    resultsFloat32Array = new Float32Array(resultsArrayBuffer);
    shouldBe("resultsFloat32Array[0]", "2");
    shouldBe("resultsFloat32Array[1]", "4");
    shouldBe("resultsFloat32Array[2]", "6");
    shouldBe("resultsFloat32Array[3]", "8");
    shouldBe("resultsFloat32Array[4]", "5");
    shouldBe("resultsFloat32Array[5]", "6");
    shouldBe("resultsFloat32Array[6]", "7");
    shouldBe("resultsFloat32Array[7]", "8");
    resultsBuffer.unmap();
}
if (window.testRunner)
    testRunner.waitUntilDone();
window.addEventListener("load", function() {
    start().then(function() {
        if (window.testRunner)
            testRunner.notifyDone();
    }, function() {
        if (window.testRunner)
            testRunner.notifyDone();
    });
});
</script>
<script src="../resources/js-test-post.js"></script>
</body>
</html>
