<!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="vertex-buffer-triangle-strip-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(float4 position : attribute(0), float green : attribute(1))
{
    VertexOut vOut;
    vOut.position = position;
    vOut.color = float4(0, green, 0, 1);
    return vOut;
}

fragment float4 fragment_main(float4 color : attribute(0)) : SV_Target 0
{
    return color;
}
`

function createVertexBuffer(device) {
    const vertexArray = new Float32Array([
        // float4 xyzw, float g
        -1, 1, 0, 1, 1,
        -1, -1, 0, 1, 1,
        1, 1, 0, 1, 1,
        1, -1, 0, 1, 1
    ]);

    return createBufferWithData(
        device, 
        { 
            size: vertexArray.byteLength, 
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE
        },
        vertexArray.buffer
    );
}

function createVertexInputDescriptor() {
    return {
        vertexBuffers: [{
            stride: 4 * 5,
            attributeSet: [{
                format: "float4",
                shaderLocation: 0
            }, {
                offset: 4 * 4,
                format: "float",
                shaderLocation: 1
            }]
        }]
    }
}

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 vertexBuffer = createVertexBuffer(device);
    const vertexInputDescriptor = createVertexInputDescriptor();
    const pipeline = createBasicPipeline(shaderModule, device, null, null, vertexInputDescriptor);
    const commandEncoder = device.createCommandEncoder();
    const passEncoder = beginBasicRenderPass(swapChain, commandEncoder);
    encodeBasicCommands(passEncoder, pipeline, vertexBuffer);
    const queue = device.getQueue();
    queue.submit([commandEncoder.finish()]);
    vertexBuffer.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>
