<!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 = `
#include <metal_stdlib>
    
using namespace metal;

struct VertexIn
{
    float4 position [[attribute(0)]];
    float green [[attribute(1)]];
};

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

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

fragment float4 fragment_main(VertexOut v [[stage_in]])
{
    return v.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>
