async function helloTriangle() {
    if (!navigator.gpu || GPUBufferUsage.COPY_SRC === undefined) {
        document.body.className = 'error';
        return;
    }

    const adapter = await navigator.gpu.requestAdapter();
    const device = await adapter.requestDevice();
    
    /*** Shader Setup ***/
    
    /* GPUShaderModule */
    const positionLocation = 0;
    const colorLocation = 1;

    const whlslSource = `
    struct FragmentData {
        float4 position : SV_Position;
        float4 color : attribute(${colorLocation});
    }

    vertex FragmentData vertexMain(float4 position : attribute(${positionLocation}), float4 color : attribute(${colorLocation}))
    {
        FragmentData out;

        out.position = position;
        out.color = color;

        return out;
    }

    fragment float4 fragmentMain(float4 color : attribute(${colorLocation})) : SV_Target 0
    {
        return color;
    }
    `;
    const shaderModule = device.createShaderModule({ code: whlslSource, isWHLSL: true });
    
    /* GPUPipelineStageDescriptors */
    const vertexStageDescriptor = { module: shaderModule, entryPoint: "vertexMain" };
    const fragmentStageDescriptor = { module: shaderModule, entryPoint: "fragmentMain" };
    
    /*** Vertex Buffer Setup ***/
    
    /* Vertex Data */
    const colorOffset = 4 * 4; // 4 floats of 4 bytes each.
    const vertexStride = 8 * 4;
    const vertexDataSize = vertexStride * 3;
    
    /* GPUBufferDescriptor */
    const vertexDataBufferDescriptor = { 
        size: vertexDataSize,
        usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.VERTEX
    };
    /* GPUBuffer */
    const vertexBuffer = device.createBuffer(vertexDataBufferDescriptor);
    
    /*** Write Data To GPU ***/
    
    const vertexArrayBuffer = await vertexBuffer.mapWriteAsync();
    const vertexWriteArray = new Float32Array(vertexArrayBuffer);
    vertexWriteArray.set([
        // x, y, z, w, r, g, b, a
        0, 0.8, 0, 1, 0, 1, 1, 1,
        -0.8, -0.8, 0, 1, 1, 1, 0, 1,
        0.8, -0.8, 0, 1, 1, 0, 1, 1
    ]);
    vertexBuffer.unmap();
    
    /*** Describe Vertex Data For Pipeline ***/
    
    const vertexBufferSlot = 0;
    
    /* GPUVertexAttributeDescriptors */
    const positionAttribute = {
        shaderLocation: positionLocation,
        offset: 0,
        format: "float4"
    };
    const colorAttribute = {
        shaderLocation: colorLocation,
        offset: colorOffset,
        format: "float4"
    };

    /* GPUVertexBufferDescriptor */
    const vertexBufferDescriptor = {
        stride: vertexStride,
        attributeSet: [positionAttribute, colorAttribute]
    };

    /* GPUVertexInputDescriptor */
    const vertexInputDescriptor = {
        vertexBuffers: [vertexBufferDescriptor]
    };
    
    /*** Finish Pipeline State ***/
    
    /* GPUBlendDescriptors */
    const alphaBlendDescriptor = { srcFactor: "one", dstFactor: "zero", operation: "add" };
    const colorBlendDescriptor = { srcFactor: "one", dstFactor: "zero", operation: "add" };
    
    /* GPUColorStateDescriptor */
    const colorStateDescriptor = {
        format: "bgra8unorm",
        alphaBlend: alphaBlendDescriptor,
        colorBlend: colorBlendDescriptor,
        writeMask: GPUColorWrite.ALL
    };
    
    /* GPURenderPipelineDescriptor */
    const renderPipelineDescriptor = {
        vertexStage: vertexStageDescriptor,
        fragmentStage: fragmentStageDescriptor,
        primitiveTopology: "triangle-list",
        colorStates: [colorStateDescriptor],
        vertexInput: vertexInputDescriptor
    };
    /* GPURenderPipeline */
    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
    
    /*** Swap Chain Setup ***/
    
    const canvas = document.querySelector("canvas");
    canvas.width = 600;
    canvas.height = 600;

    const gpuContext = canvas.getContext("gpu");
    
    /* GPUSwapChainDescriptor */
    const swapChainDescriptor = { device: device, format: "bgra8unorm" };
    /* GPUSwapChain */
    const swapChain = gpuContext.configureSwapChain(swapChainDescriptor);
    
    /*** Render Pass Setup ***/
    
    /* Acquire Texture To Render To */
    
    /* GPUTexture */
    const swapChainTexture = swapChain.getCurrentTexture();
    /* GPUTextureView */
    const renderAttachment = swapChainTexture.createDefaultView();
    
    /* GPUColor */
    const darkBlue = { r: 0.15, g: 0.15, b: 0.5, a: 1 };
    
    /* GPURenderPassColorATtachmentDescriptor */
    const colorAttachmentDescriptor = {
        attachment: renderAttachment,
        loadOp: "clear",
        storeOp: "store",
        clearColor: darkBlue
    };
    
    /* GPURenderPassDescriptor */
    const renderPassDescriptor = { colorAttachments: [colorAttachmentDescriptor] };
    
    /*** Rendering ***/
    
    /* GPUCommandEncoder */
    const commandEncoder = device.createCommandEncoder();
    /* GPURenderPassEncoder */
    const renderPassEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
    
    renderPassEncoder.setPipeline(renderPipeline);
    renderPassEncoder.setVertexBuffers(vertexBufferSlot, [vertexBuffer], [0]);
    renderPassEncoder.draw(3, 1, 0, 0); // 3 vertices, 1 instance, 0th vertex, 0th instance.
    renderPassEncoder.endPass();
    
    /* GPUComamndBuffer */
    const commandBuffer = commandEncoder.finish();
    
    /* GPUQueue */
    const queue = device.getQueue();
    queue.submit([commandBuffer]);
}

window.addEventListener("DOMContentLoaded", helloTriangle);
