<!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="vertex-buffer-triangle-strip-expected.html">
<p>Pass if square canvas below is a 4 by 4 blue/green checkerboard.</p>
<canvas width="400" height="400"></canvas>
<script src="js/webgpu-functions.js"></script>
<script>
if (window.testRunner)
    testRunner.waitUntilDone();

const positionBufferIndex = 0;
const texCoordsBufferIndex = 1;
const positionAttributeNum = 0;
const texCoordsAttributeNum = 1;
const bindGroupIndex = 0;
const textureBindingNum = 0;
const samplerBindingNum = 1;

const shaderCode = `
#include <metal_stdlib>
    
using namespace metal;

struct VertexIn
{
    float4 position [[attribute(${positionAttributeNum})]];
    float2 texCoords [[attribute(${texCoordsAttributeNum})]];
};

struct VertexOut
{
    float4 position [[position]];
    float2 texCoords;
};

vertex VertexOut vertex_main(VertexIn vertexIn [[stage_in]])
{
    VertexOut vOut;
    vOut.position = vertexIn.position;
    vOut.texCoords = vertexIn.texCoords;
    return vOut;
}

struct TextureSampler
{
    texture2d<float> t [[id(${textureBindingNum})]];
    sampler s [[id(${samplerBindingNum})]];
};

fragment float4 fragment_main(VertexOut v [[stage_in]], const device TextureSampler& args [[buffer(${bindGroupIndex})]])
{
    return args.t.sample(args.s, v.texCoords);
}
`

function createVertexInputDescriptor() {
    var bufferDescriptors = [];
    bufferDescriptors[positionBufferIndex] = {
        stride: 4 * 4,
        attributeSet: [{
            format: "float4",
            shaderLocation: positionAttributeNum
        }]
    };
    bufferDescriptors[texCoordsBufferIndex] = {
        stride: 4 * 2,
        attributeSet: [{
            format: "float2",
            shaderLocation: texCoordsAttributeNum
        }]
    };

    return { vertexBuffers: bufferDescriptors };
}

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 positionArray = new Float32Array([
        // float4 xyzw
        -1, 1, 0, 1,
        -1, -1, 0, 1,
        1, 1, 0, 1, 
        1, -1, 0, 1
    ]);
    const positionBuffer = createBufferWithData(device, { size: positionArray.byteLength, usage: GPUBufferUsage.VERTEX }, positionArray.buffer);

    const texCoordsArray = new Float32Array([
        // float2 texCoords
        0, 0,
        0, 1,
        1, 0,
        1, 1
    ]);
    const textureCoordBuffer = createBufferWithData(device, { size: texCoordsArray.byteLength, usage: GPUBufferUsage.VERTEX }, texCoordsArray.buffer);

    const vertexInputDescriptor = createVertexInputDescriptor();

    // Load texture image
    const image = new Image();
    const imageLoadPromise = new Promise(resolve => { 
        image.onload = () => resolve(); 
        image.src = "resources/blue-checkered.png";
    });
    await Promise.resolve(imageLoadPromise);

    // Convert image to data and fill GPUBuffer
    const canvas2d = document.createElement("canvas");
    canvas2d.width = image.width;
    canvas2d.height = image.height;
    const context2d = canvas2d.getContext("2d");
    context2d.drawImage(image, 0, 0);
    const imageData = context2d.getImageData(0, 0, image.width, image.height);

    const textureBufferDescriptor = {
        size: imageData.data.length,
        usage: GPUBufferUsage.TRANSFER_SRC
    };
    const textureBuffer = createBufferWithData(device, textureBufferDescriptor, imageData.data.buffer);

    // Create GPUTexture
    const textureSize = {
        width: image.width,
        height: image.height,
        depth: 1
    };

    const textureDescriptor = {
        size: { width: image.width, height: image.height, depth: 1 },
        format: "rgba8unorm",
        usage: GPUTextureUsage.TRANSFER_DST | GPUTextureUsage.SAMPLED
    };
    const texture = device.createTexture(textureDescriptor);

    // Bind texture and a sampler to pipeline
    const textureLayoutBinding = { 
        binding: textureBindingNum, 
        visibility: GPUShaderStageBit.FRAGMENT, 
        type: "sampled-texture" 
    };
    const samplerLayoutBinding = {
        binding: samplerBindingNum,
        visibility: GPUShaderStageBit.FRAGMENT,
        type: "sampler"
    };

    const bindGroupLayoutDescriptor = {
        bindings: [textureLayoutBinding, samplerLayoutBinding]
    };
    bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor);
    const pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [bindGroupLayout] });

    const textureBinding = { 
        binding: textureBindingNum, 
        resource: texture.createDefaultView() 
    };
    const samplerBinding = {
        binding: samplerBindingNum,
        resource: device.createSampler({ minFilter: "nearest", magFilter: "nearest" })
    };

    const bindGroupDescriptor = {
        layout: bindGroupLayout,
        bindings: [textureBinding, samplerBinding]
    };
    const bindGroup = device.createBindGroup(bindGroupDescriptor);

    // Pipeline and render
    const pipeline = createBasicPipeline(shaderModule, device, null, pipelineLayout, vertexInputDescriptor);
    const commandEncoder = device.createCommandEncoder();

    const bufferCopyView = {
        buffer: textureBuffer,
        rowPitch: image.width * 4,
        imageHeight: 0
    };
    const textureCopyView = { texture: texture };
    commandEncoder.copyBufferToTexture(bufferCopyView, textureCopyView, textureSize);
    const passEncoder = beginBasicRenderPass(swapChain, commandEncoder);
    passEncoder.setPipeline(pipeline);
    passEncoder.setBindGroup(bindGroupIndex, bindGroup);
    passEncoder.setVertexBuffers(positionBufferIndex, [positionBuffer, textureCoordBuffer], [0, 0]);
    passEncoder.draw(4, 1, 0, 0);
    passEncoder.endPass();

    const queue = device.getQueue();
    queue.submit([commandEncoder.finish()]);
    positionBuffer.destroy();
    textureCoordBuffer.destroy();
    texture.destroy();
}

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