<!DOCTYPE html>
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
<script src="../js/webgpu-functions.js"></script>
</head>
<body>
<script>
const shaderSource = `
void fill(thread float[10][] array, float[10] value) {
    for (uint i = 0; i < array.length; i = i + 1) {
        array[i] = value;
    }
}

void fill(thread float[] array, float value) {
    for (uint i = 0; i < array.length; i = i + 1) {
        array[i] = value;
    }
}

bool contains(thread float[10][] array, float value) {
    for (uint i = 0; i < array.length; i = i + 1) {
        for (uint j = 0; j < array[j].length; j = j + 1) {
            if (array[i][j] != value)
                return false;
        }
    }
    return true;
}

bool contains(thread float[] array, float value) {
    for (uint i = 0; i < array.length; i = i + 1) {
        if (array[i] != value)
            return false;
    }
    return true;
}

[numthreads(1, 1, 1)]
compute void computeShader(device int[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
    float[10][5] array;
    if (array.length != 5)
        return;
    if (!contains(@array, 0))
        return;

    for (uint i = 0; i < array.length; i = i + 1) {
        float[10] value;
        fill(@value, float(i));
        array[i] = value;
    }

    for (uint i = 0; i < array.length; i = i + 1) {
        float[10] value = array[i];
        if (!contains(@value, float(i)))
            return;
    }

    buffer[0] = 1;
}
`;
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 = Int32Array.BYTES_PER_ELEMENT * 1;

    const bufferDescriptor = {size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.COPY_SRC};
    const buffer = device.createBuffer(bufferDescriptor);
    const bufferArrayBuffer = await buffer.mapWriteAsync();
    const bufferFloat32Array = new Int32Array(bufferArrayBuffer);
    bufferFloat32Array[0] = 0;
    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(1, 1, 1);
    computePassEncoder.endPass();
    const commandBuffer = commandEncoder.finish();
    device.getQueue().submit([commandBuffer]);

    const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
    let resultsInt32Array = new Int32Array(resultsArrayBuffer);
    if (resultsInt32Array[0] === 1)
        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>
