<!DOCTYPE html>
<html>
<head>
<script src="../resources/js-test-pre.js"></script>
<script src="js/webgpu-functions.js"></script>
</head>
<body>
<script>
const shaderSource = `
bool test1() {
    int value = 42;
    thread int[] array = @value;
    if (array.length != 1)
        return false;
    if (array[0] != 42)
        return false;
    if (array[120213] != 0)
        return false;

    array[0] = 1337;
    if (value != 1337)
        return false;

    return true;
}

bool test2() {
    int value = 42;
    thread int* ptr = &value;
    if (*ptr != 42)
        return false;

    thread int[] array = @ptr;
    if (array.length != 1)
        return false;
    if (array[0] != 42)
        return false;
    if (array[12374217] != 0)
        return false;
    
    *ptr = 666;
    if (*ptr != 666)
        return false;
    if (value != 666)
        return false;
    if (array.length != 1)
        return false;
    if (array[0] != 666)
        return false;

    array[0] = 4242;
    if (*ptr != 4242)
        return false;
    if (value != 4242)
        return false;
    if (array[0] != 4242)
        return false;
    if (array.length != 1)
        return false;

    return true;
}

bool test3() {
    int[42] x;
    thread int[42]* arrayPtr = &x;
    if (arrayPtr->length != 42)
        return false;

    x[41] = 666;
    if ((*arrayPtr)[41] != 666)
        return false;
    if ((*arrayPtr)[0] != 0)
        return false;

    thread int[] array = @x;
    if (array.length != 42)
        return false;

    array[0] = 1337;
    if (x[0] != 1337)
        return false;
    if ((*arrayPtr)[0] != 1337)
        return false;

    return true;
}

bool test4() {
    thread int* ptr = null;

    thread int[] array = @ptr;
    if (array.length != 0)
        return false;

    if (array[0] != 0)
        return false;

    if (array[100000] != 0)
        return false;

    return true;
}

[numthreads(1, 1, 1)]
compute void computeShader(device int[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
    if (!test1())
        return;

    if (!test2())
        return;

    if (!test3())
        return;

    if (!test4())
        return;

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

    const bufferDescriptor = {size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.TRANSFER_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.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(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>
