<!DOCTYPE html>
<meta charset="utf-8">
<title>WebGPU Hello Triangles</title>
<meta name="assert" content="WebGPU correctly renders a green canvas.">
<link rel="match" href="buffer-command-buffer-races-expected.html">
<p>Pass if square canvas below is completely green.</p>
<canvas width="400" height="400"></canvas>
<script src="js/webgpu-functions.js"></script>
<script>
if (window.testRunner)
    testRunner.waitUntilDone();

const shaderCode = `
#include <metal_stdlib>
    
using namespace metal;

struct VertexIn
{
    float2 xy [[attribute(0)]];
    float3 rgb [[attribute(1)]];
};

struct VertexOut
{
    float4 position [[position]];
    float4 color;
};

vertex VertexOut vertex_main(VertexIn vertexIn [[stage_in]])
{
    VertexOut vOut;
    vOut.position = float4(vertexIn.xy, 0, 1);
    vOut.color = float4(vertexIn.rgb, 1);

    return vOut;
}

fragment float4 fragment_main(VertexOut v [[stage_in]])
{
    return v.color;
}
`

function createInputStateDescriptor() {
    return {
        indexFormat: "uint32",
        attributes: [{
            shaderLocation: 0,
            inputSlot: 0,
            format: "float2"
        }, {
            shaderLocation: 1,
            inputSlot: 1,
            format: "float3"
        }],
        inputs: [{
            inputSlot: 0,
            stride: 4 * 2
        }, {
            inputSlot: 1,
            stride: 4 * 3,
            stepMode: "instance"
        }]
    }
}

function createAndSetVertexBuffer(device, vertices) {
    const floatArray = new Float32Array(vertices);
    const buffer = device.createBuffer({ size: floatArray.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.TRANSFER_DST });
    buffer.setSubData(0, floatArray.buffer);
    return buffer;
}

function drawAndSubmitCommands(device, pipeline, attachment, vertexBuffer, colorBuffer) {
    const commandEncoder = device.createCommandEncoder();
    const encoder = commandEncoder.beginRenderPass({ colorAttachments: [attachment] });
    encoder.setVertexBuffers(0, [vertexBuffer, colorBuffer], [0, 0]);
    encoder.setPipeline(pipeline);
    encoder.draw(3, 1, 0, 0);
    encoder.endPass();
    device.getQueue().submit([commandEncoder.finish()]);
}

async function test() {
    const device = await getBasicDevice();
    const canvas = document.querySelector("canvas");
    const swapChain = createBasicSwapChain(canvas, device);
    // FIXME: Replace with non-MSL shaders.
    const shaderModule = device.createShaderModule({ code: shaderCode });
    const inputStateDescriptor = createInputStateDescriptor();
    const pipeline = createBasicPipeline(shaderModule, device, null, null, inputStateDescriptor);

    const upperLeftBuffer = createAndSetVertexBuffer(device, [-1, 1, -1, -1, 0, 1]);
    const middleBuffer = createAndSetVertexBuffer(device, [0, 1, -1, -1, 1, -1]);
    const upperRightBuffer = createAndSetVertexBuffer(device, [0, 1, 1, 1, 1, -1]);

    const green = [0, 1, 0];
    const blue = [0, 0, 1];
    const greenArray = new Float32Array(green);
    const blueArray = new Float32Array(blue);

    const colorBuffer = device.createBuffer({ size: greenArray.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.MAP_WRITE });
    colorBuffer.setSubData(0, greenArray.buffer);

    const attachment = {
        attachment: swapChain.getCurrentTexture().createDefaultView(),
        loadOp: "load",
        storeOp: "store",
        clearColor: { r: 1, g: 0, b: 0, a: 1 }
    };

    /* mapWriteAsync should resolve after GPU commands are complete, so triangle should be green. */
    drawAndSubmitCommands(device, pipeline, attachment, upperLeftBuffer, colorBuffer);
    await colorBuffer.mapWriteAsync().then(ab => {
        let array = new Float32Array(ab);
        array.set(blue);
        colorBuffer.unmap();
    });

    await colorBuffer.mapWriteAsync().then(ab => {
        let array = new Float32Array(ab);
        array.set(green);
    });

    /* colorBuffer that is still mapped should be not submitted to draw a blue triangle. */
    drawAndSubmitCommands(device, pipeline, attachment, upperLeftBuffer, colorBuffer);

    /* colorBuffer does not actually contain "green" again until this call. */
    colorBuffer.unmap();

    /* setSubData immediately after a submit should not affect the preceding draw call. */
    drawAndSubmitCommands(device, pipeline, attachment, middleBuffer, colorBuffer);
    colorBuffer.setSubData(0, blueArray.buffer);

    /* destroy right after a submit should not affect the draw call. */
    colorBuffer.setSubData(0, greenArray.buffer);
    drawAndSubmitCommands(device, pipeline, attachment, upperRightBuffer, colorBuffer);
    upperRightBuffer.destroy();

    /* draw command with a destroyed buffer should fail */
    colorBuffer.destroy();
    drawAndSubmitCommands(device, pipeline, attachment, middleBuffer, colorBuffer);

    upperLeftBuffer.destroy();
    middleBuffer.destroy();
    upperRightBuffer.destroy();

    if (window.testRunner)
        testRunner.notifyDone();
}

test();
</script>