<!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 = `
struct VertexOut
{
    float4 position : SV_Position;
    float4 color : attribute(0);
};

vertex VertexOut vertex_main(float2 xy : attribute(0), float3 rgb : attribute(1)) {
    VertexOut vOut;
    vOut.position = float4(xy, 0, 1);
    vOut.color = float4(rgb, 1);
    return vOut;
}

fragment float4 fragment_main(float4 color : attribute(0)) : SV_Target 0
{
    return 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>
