<!DOCTYPE html>
<html>
<head>
<script src="js/webgpu-functions.js"></script>
<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 + float2x3(float3(1.0, 1.0, 1.0), float3(1.0, 1.0, 1.0));
    if (!allEqual(foo, 1))
        return;

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

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

    foo = foo + float2x3(float3(1.0, 1.0, 1.0), float3(1.0, 1.0, 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;
}
`;

async function start(device) {
    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();
    const resultsFloat32Array = new Float32Array(resultsArrayBuffer);
    if (resultsFloat32Array[0] == 2
        && resultsFloat32Array[1] == 4
        && resultsFloat32Array[2] == 6
        && resultsFloat32Array[3] == 8
        && resultsFloat32Array[4] == 5
        && resultsFloat32Array[5] == 6
        && resultsFloat32Array[6] == 7
        && resultsFloat32Array[7] == 8)
        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>
