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

struct VertexInput {
    float4 position [[attribute(0)]];
};

struct Vertex {
    float4 position [[position]];
};

struct VertexArguments {
    device Vertex* v0;
    device Vertex* v1;
    device Vertex* v2;
};

vertex Vertex vertex_main(
    VertexInput input [[stage_in]],
    const device VertexArguments& args0 [[buffer(0)]],
    const device VertexArguments& args1 [[buffer(1)]],
    uint vid [[vertex_id]])
{
    switch (vid)
    {
        case 0:
        case 1:
        case 2: {
            Vertex out;
            out.position = input.position;
            return out;
        }
        case 3: return *args0.v0;
        case 4: return *args0.v1;
        case 5: return *args0.v2;
        case 6: return *args1.v0;
        case 7: return *args1.v1;
        default: return *args1.v2;
    }
}

struct FragmentArguments {
    device float4* color;
};

fragment float4 fragment_main(const device FragmentArguments& args [[buffer(0)]])
{
    return args.color[0];
}
`

const bindingNums = {
    UL: 0,
    UM: 1,
    UR: 2,
    LL: 3,
    LR: 4,
    G: 5
};

function createUniformBufferBindGroupLayout(bindNum, stage = GPUShaderStageBit.VERTEX) {
    return {
        binding: bindNum,
        visibility: stage,
        type: "uniform-buffer"
    };
}

const vertexSize = 4 * 4;
const verticesBufferSize = vertexSize * 3;
function createAndUploadVerticesBuffer(device) {
    const buffer = device.createBuffer({ size:verticesBufferSize, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.TRANSFER_DST });
    const arrayBuffer = new Float32Array([
        0, 1, 0, 1,
        -1, -1, 0, 1,
        1, -1, 0, 1
    ]).buffer;

    buffer.setSubData(0, arrayBuffer);
    return buffer;
}

function createFloat4Buffer(device, a, b, promises) {
    const buffer = device.createBuffer({ size: vertexSize, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.MAP_WRITE });

    const promise = buffer.mapWriteAsync().then(mapping => {
        const mappedArray = new Float32Array(mapping);
        mappedArray.set([a, b, 0, 1]);
        buffer.unmap();
    });

    promises.push(promise);
    return buffer;
}

function createBufferBinding(buffer) {
    return {
        buffer: buffer,
        offset: 0,
        size: vertexSize
    };
}

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

    // Create vertex data WebGPUBuffers.
    const verticesBuffer = createAndUploadVerticesBuffer(device);

    let bufferPromises = [];
    const upperLeft = createFloat4Buffer(device, -1, 1, bufferPromises);
    const upperMiddle = createFloat4Buffer(device, 0, 1, bufferPromises);
    const upperRight = createFloat4Buffer(device, 1, 1, bufferPromises);
    const lowerLeft = createFloat4Buffer(device, -1, -1, bufferPromises);
    const lowerRight = createFloat4Buffer(device, 1, -1, bufferPromises);

    // Color data buffer.
    const green = createFloat4Buffer(device, 0, 1, bufferPromises);

    // Create vertex input state.
    const inputState = {
        indexFormat: "uint32",
        attributes: [{
            shaderLocation: 0,
            inputSlot: 0,
            offset: 0,
            format: "float4"
        }],
        inputs: [{
            inputSlot: 0,
            stride: vertexSize,
            stepMode: "vertex"
        }]
    };

    // Create buffer WebGPUBindGroupLayoutBindings.
    const layoutUL = createUniformBufferBindGroupLayout(bindingNums.UL);
    const layoutUM = createUniformBufferBindGroupLayout(bindingNums.UM);
    const layoutUR = createUniformBufferBindGroupLayout(bindingNums.UR);
    const layoutLL = createUniformBufferBindGroupLayout(bindingNums.LL);
    const layoutLR = createUniformBufferBindGroupLayout(bindingNums.LR);
    const layoutG = createUniformBufferBindGroupLayout(bindingNums.G, GPUShaderStageBit.FRAGMENT);

    // WebGPUBindGroupLayouts
    const leftTriangleBGLayout = device.createBindGroupLayout({ bindings: [layoutUL, layoutUM, layoutLL, layoutG] });
    const rightTriangleBGLayout = device.createBindGroupLayout({ bindings: [layoutUR, layoutUM, layoutLR] });

    // WebGPUPipelineLayout and WebGPURenderPipeline
    const pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [leftTriangleBGLayout, rightTriangleBGLayout] });
    const pipeline = createBasicPipeline(shaderModule, device, pipelineLayout, inputState, null, "triangle-list");

    // WebGPUBufferBindings
    const bindingUL = createBufferBinding(upperLeft);
    const bindingUM = createBufferBinding(upperMiddle);
    const bindingUR = createBufferBinding(upperRight);
    const bindingLL = createBufferBinding(lowerLeft);
    const bindingLR = createBufferBinding(lowerRight);
    const bindingG = createBufferBinding(green);
    
    // WebGPUBindGroupBindings
    const bgBindingUL = { binding: bindingNums.UL, resource: bindingUL };
    const bgBindingUM = { binding: bindingNums.UM, resource: bindingUM };
    const bgBindingUR = { binding: bindingNums.UR, resource: bindingUR };
    const bgBindingLL = { binding: bindingNums.LL, resource: bindingLL };
    const bgBindingLR = { binding: bindingNums.LR, resource: bindingLR };
    const bgBindingG = { binding: bindingNums.G, resource: bindingG };

    // WebGPUBindGroups
    const leftTriangleBG = device.createBindGroup({ 
        layout: leftTriangleBGLayout, 
        bindings: [bgBindingUL, bgBindingUM, bgBindingLL, bgBindingG] 
    });
    const rightTriangleBG = device.createBindGroup({
        layout: rightTriangleBGLayout,
        bindings: [bgBindingUR, bgBindingUM, bgBindingLR]
    });

    Promise.all(bufferPromises).then(() => {
        const commandEncoder = device.createCommandEncoder();
        const passEncoder = beginBasicRenderPass(swapChain, commandEncoder);
        passEncoder.setPipeline(pipeline);

        // Vertex data for upper triangles.
        passEncoder.setBindGroup(0, leftTriangleBG);
        passEncoder.setBindGroup(1, rightTriangleBG);
        // Lower triangle.
        passEncoder.setVertexBuffers(0, [verticesBuffer], [0]);
        passEncoder.draw(9, 1, 0, 0);

        passEncoder.endPass();
        const queue = device.getQueue();
        queue.submit([commandEncoder.finish()]);

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

test();
</script>