<!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="color-write-mask-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 = `
vertex float4 vertex_main(uint vid : SV_VertexID) : SV_Position
{
    float4 v;
    switch (vid) {
    case 0:
        v = float4(-1, 1, 0, 1);
        break;
    case 1:
        v = float4(-1, -1, 0, 1);
        break;
    case 2:
        v = float4(1, 1, 0, 1);
        break;
    default:
        v = float4(1, -1, 0, 1);
        break;
    }
    return v;
}

fragment float4 fragment_main() : SV_Target 0
{
    return float4(1, 1, 1, 1);
}
`

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

async function test(device) {
    const swapChain = createBasicSwapChain(canvas, device);
    const shaderModule = device.createShaderModule({ code: shaderCode });
    const colorStates = [{
        format: "bgra8unorm",
        alphaBlend: {},
        colorBlend: {},
        writeMask: GPUColorWrite.GREEN | GPUColorWrite.ALPHA
    }];
    const pipeline = createBasicPipeline(shaderModule, device, colorStates);
    const commandEncoder = device.createCommandEncoder();
    const colorAttachment = {
        attachment: swapChain.getCurrentTexture().createDefaultView(),
        loadOp: "clear",
        storeOp: "store",
        clearColor: { r: 0, g: 0, b: 0, a: 0 }
    };
    const passEncoder = commandEncoder.beginRenderPass({ colorAttachments: [colorAttachment] });
    encodeBasicCommands(passEncoder, pipeline);
    const queue = device.getQueue();

    queue.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>
