<!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] != 42)
        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] != 42)
        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() {
    int x = 42;
    thread int* ptr = &x;

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

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

    if (array[100000] != 42)
        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});
    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>
