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

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

vertex VertexOut vertex_main(VertexIn vertexIn [[stage_in]], uint iid [[instance_id]])
{
    VertexOut vOut;
    vOut.position = vertexIn.position;

    if (iid == 0) {
        vOut.position.z = 0.5;
        vOut.color = float4(1, 0, 0, 1);
    } else {
        vOut.color = float4(0, 1, 0, 1);
    }

    return vOut;
}

fragment float4 fragment_main(VertexOut v [[stage_in]])
{
    return v.color;
}
`

function createVertexBuffer(device) {
    const vertexArray = new Float32Array([
        // float4 xyzw
        -1, 1, 0, 1,
        -1, -1, 0, 1,
        1, 1, 0, 1,
        1, -1, 0, 1
    ]);
    return createBufferWithData(device, { size: vertexArray.byteLength, usage: GPUBufferUsage.VERTEX }, vertexArray.buffer);
}

function createVertexInputDescriptor() {
    return {
        indexFormat: "uint32",
        vertexBuffers: [{
            stride: 4 * 4,
            attributeSet: [{
                format: "float4",
                shaderLocation: 0
            }]
        }]
    }
}

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 depthStateDescriptor = createBasicDepthStateDescriptor();
    const pipeline = createBasicPipeline(shaderModule, device, null, null, vertexInputDescriptor, depthStateDescriptor);
    const commandEncoder = device.createCommandEncoder();

    const basicAttachment = {
        attachment: swapChain.getCurrentTexture().createDefaultView(),
        loadOp: "clear",
        storeOp: "store",
        clearColor: { r: 1.0, g: 0, b: 0, a: 1.0 }
    };

    const depthAttachment = {
        attachment: createBasicDepthTexture(canvas, device).createDefaultView(),
        depthLoadOp: "clear",
        depthStoreOp: "store",
        clearDepth: 1.0
    };

    const encoder = commandEncoder.beginRenderPass({
        colorAttachments: [basicAttachment],
        depthStencilAttachment: depthAttachment
    });

    encoder.setVertexBuffers(0, [vertexBuffer], [0]);
    encoder.setPipeline(pipeline);
    encoder.draw(4, 2, 0, 0);
    encoder.endPass();

    device.getQueue().submit([commandEncoder.finish()]);
}

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>
