<!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()]);
}

const canvas = document.querySelector("canvas");

async function test(device) {
    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();
}

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