<!DOCTYPE html>
<html>
<head>
<script src="../js/webgpu-functions.js"></script>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script>
const shaderSource = `
[numthreads(1, 1, 1)]
compute void computeShader(Texture2D<float4> theTexture : register(t0), device uint[] theBuffer : register(u1)) {
    uint width;
    uint height;
    uint numberOfLevels;
    GetDimensions(theTexture, 0, &width, &height, &numberOfLevels);
    theBuffer[0] = width;
    theBuffer[1] = height;
    theBuffer[2] = numberOfLevels;
}
`;

async function start(device) {
    const shaderModule = device.createShaderModule({code: shaderSource});
    const computeStage = {module: shaderModule, entryPoint: "computeShader"};

    const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "sampled-texture"}, {binding: 1, 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 textureDescriptor = {size: {width: 2, height: 2, depth: 1}, format: "rgba8unorm", usage: GPUTextureUsage.SAMPLED};
    const texture = device.createTexture(textureDescriptor);
    const textureView = texture.createDefaultView();

    const resultsBufferDescriptor = {size: Uint32Array.BYTES_PER_ELEMENT * 3, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.MAP_READ};
    const resultsBuffer = device.createBuffer(resultsBufferDescriptor);

    const bufferBinding = {buffer: resultsBuffer, size: Uint32Array.BYTES_PER_ELEMENT * 3};
    const bindGroupBindings = [{binding: 0, resource: textureView}, {binding: 1, resource: bufferBinding}];
    const bindGroupDescriptor = {layout: bindGroupLayout, bindings: bindGroupBindings};
    const bindGroup = device.createBindGroup(bindGroupDescriptor);

    const commandEncoder = device.createCommandEncoder(); // {}
    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();
    const resultsUint32Array = new Uint32Array(resultsArrayBuffer);
    if (resultsUint32Array[0] == 2
        && resultsUint32Array[1] == 2
        && resultsUint32Array[2] == 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>
