<!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="draw-indexed-triangles-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, 0,
        -1, 1, 0, 1, 1,
        -1, -1, 0, 1, 0,
        -1, -1, 0, 1, 1,
        1, 1, 0, 1, 0,
        1, 1, 0, 1, 1,
        1, -1, 0, 1, 0,
        1, -1, 0, 1, 1
    ]);
    return createBufferWithData(device, { size: vertexArray.byteLength, usage: GPUBufferUsage.VERTEX }, vertexArray.buffer);
}

const indexBufferOffset = 2048; // Test a buffer offset for index array.
const indexOffset = -9001; // Test a base index to add to index array values.

function createIndexBuffer(device) {
    const offsetArray = [1, 3, 5, 3, 5, 7].map(v => { return v - indexOffset; });
    const indexArray = new Uint32Array([1, 3, 5, 3, 5, 7].map(v => { return v - indexOffset; }));
    const buffer = createBufferWithData(
        device, 
        { 
            size: indexArray.byteLength + indexBufferOffset, 
            usage: GPUBufferUsage.INDEX 
        },
        indexArray.buffer,
        indexBufferOffset
    );

    return buffer;
}

function createVertexInputDescriptor() {
    return {
        indexFormat: "uint32",
        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 indexBuffer = createIndexBuffer(device);
    const pipeline = createBasicPipeline(shaderModule, device, null, null, createVertexInputDescriptor(), null, "triangle-list");
    const commandEncoder = device.createCommandEncoder();
    const passEncoder = beginBasicRenderPass(swapChain, commandEncoder);

    passEncoder.setIndexBuffer(indexBuffer, indexBufferOffset);
    passEncoder.setVertexBuffers(0, [vertexBuffer], [0]);
    passEncoder.setPipeline(pipeline);
    passEncoder.drawIndexed(6, 1, 0, indexOffset, 0);
    passEncoder.endPass();

    device.getQueue().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>
