<!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="blend-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 positionAttributeNum = 0;

const shaderCode = `
struct VertexOut
{
    float4 position : SV_Position;
    float4 color : attribute(0);
};

vertex VertexOut vertex_main(float4 position : attribute(${positionAttributeNum})) {
    VertexOut vOut;
    vOut.position = position;
    vOut.color = float4(0, 0.5, 0, 0.5);
    return vOut;
}

fragment float4 fragment_main(float4 color : attribute(0)) : SV_Target 0
{
    return color;
}
`;

const canvas = document.querySelector("canvas");

async function start(device) {
    const shaderModule = device.createShaderModule({ code: shaderCode });

    const colorStates = [{
        format: "bgra8unorm",
        alphaBlend: { dstFactor: "one" },
        colorBlend: { dstFactor: "one" }
    }];

    const vertexInputDescriptor = {
        indexFormat: "uint32",
        vertexBuffers: [{
            stride: 4 * 4,
            attributeSet: [{
                format: "float4",
                shaderLocation: positionAttributeNum
            }]
        }]
    };

    const pipeline = createBasicPipeline(shaderModule, device, colorStates, null, vertexInputDescriptor);

    const vertexData = new Float32Array([
        -1, 1, 0, 1,
        -1, -1, 0, 1,
        1, 1, 0, 1,
        1, -1, 0, 1
    ]);
    const vertexBuffer = createBufferWithData(device, { size: vertexData.byteLength, usage: GPUBufferUsage.VERTEX }, vertexData.buffer);

    const context = canvas.getContext("gpu");
    const swapChain = context.configureSwapChain({ device: device, format: "bgra8unorm" });
    const colorAttachment = {
        attachment: swapChain.getCurrentTexture().createDefaultView(),
        loadOp: "clear",
        storeOp: "store",
        clearColor: { r: 0, g: 0, b: 0, a: 0 }
    };

    const commandEncoder = device.createCommandEncoder();
    const passEncoder = commandEncoder.beginRenderPass({ colorAttachments: [colorAttachment] });
    passEncoder.setPipeline(pipeline);
    passEncoder.setVertexBuffers(0, [vertexBuffer], [0]);
    passEncoder.draw(4, 1, 0, 0);
    passEncoder.draw(4, 1, 0, 0);
    passEncoder.endPass();

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

getBasicDevice().then(function(device) {
    start(device).then(function() {
        if (window.testRunner)
            testRunner.notifyDone();
    }, function() {
        if (window.testRunner)
            testRunner.notifyDone();
    });
}, function() {
    drawGreenSquareInSoftware(canvas);
    if (window.testRunner)
        testRunner.notifyDone();
});
</script>
