<!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 createVertexInputDescriptor() {
    return {
        indexFormat: "uint32",
        vertexBuffers: [{
            stride: 4 * 2,
            attributeSet: [{
                format: "float2",
                shaderLocation: 0
            }]
        }, {
            stride: 4 * 3,
            stepMode: "instance",
            attributeSet: [{
                format: "float3",
                shaderLocation: 1
            }]
        }]
    }
}

function createAndSetVertexBuffer(device, vertices) {
    const vertexArray = new Float32Array(vertices)
    return createBufferWithData(device, { size: vertexArray.byteLength, usage: GPUBufferUsage.VERTEX }, vertexArray.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 vertexInputDescriptor = createVertexInputDescriptor();
    const pipeline = createBasicPipeline(shaderModule, device, null, null, vertexInputDescriptor);

    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 = createBufferWithData(device, { size: greenArray.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE }, 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();

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

    /* destroy right after a submit should not affect the draw call. */
    await mapWriteDataToBuffer(colorBuffer, 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();
}

test().then(function() {
    if (window.testRunner)
        testRunner.notifyDone();
}, function() {
    if (window.testRunner)
        testRunner.notifyDone();
});
</script>
