<!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 bufferSize = 4 * 5 * 4;
    const buffer = device.createBuffer({ size: bufferSize, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.TRANSFER_DST });
    const vertexArrayBuffer0 = new Float32Array([
        // float4 xyzw, float g
        -1, 1, 0, 1, 1,
        -1, -1, 0, 1, 1
    ]).buffer;
    const vertexArrayBuffer1 = new Float32Array([
        1, 1, 0, 1, 1,
        1, -1, 0, 1, 1
    ]).buffer;

    buffer.setSubData(0, vertexArrayBuffer0);
    buffer.setSubData(4 * 5 * 2, vertexArrayBuffer1);

    return buffer;
}

function createInputStateDescriptor() {
    return {
        indexFormat: "uint32",
        attributes: [{
            shaderLocation: 0,
            inputSlot: 0,
            format: "float4"
        }, {
            shaderLocation: 1,
            inputSlot: 0,
            offset: 4 * 4,
            format: "float"
        }],
        inputs: [{
            inputSlot: 0,
            stride: 4 * 5
        }]
    }
}

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

    if (window.testRunner)
        testRunner.notifyDone();
}

test();
</script>