<!DOCTYPE html>
<html>
<head>
<script src="js/webgpu-functions.js"></script>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script>
const shaderSource = `
vertex float4 vertexShader(float4 position : attribute(0)) : SV_Position {
    return position;
}

fragment float4 fragmentShader(Texture2D<float4> theTexture : register(t0), sampler theSampler : register(s1)) : SV_Target 0 {
    return Sample(theTexture, theSampler, float2(0.5, 0.5));
}
`;

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

async function start(device) {
    const shaderModule = device.createShaderModule({code: shaderSource, isWHLSL: true});
    const vertexStage = {module: shaderModule, entryPoint: "vertexShader"};
    const fragmentStage = {module: shaderModule, entryPoint: "fragmentShader"};
    const primitiveTopology = "triangle-strip";
    const rasterizationState = {frontFace: "cw", cullMode: "none"};
    const alphaBlend = {};
    const colorBlend = {};
    const colorStates = [{format: "rgba8unorm", alphaBlend, colorBlend, writeMask: 15}]; // GPUColorWriteBits.ALL
    const depthStencilState = null;
    
    const attribute0 = {shaderLocation: 0, format: "float4"};
    const input0 = {stride: 16, attributeSet: [attribute0]};
    const inputs = [input0];
    const vertexInput = {vertexBuffers: inputs};

    const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "sampled-texture"}, {binding: 1, visibility: 7, type: "sampler"}]};
    const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor);
    const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]};
    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);

    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);

    const vertexBuffer0Descriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
    const vertexBuffer0 = device.createBuffer(vertexBuffer0Descriptor);
    const vertexBuffer0ArrayBuffer = await vertexBuffer0.mapWriteAsync();
    const vertexBuffer0Float32Array = new Float32Array(vertexBuffer0ArrayBuffer);
    vertexBuffer0Float32Array[0] = -0.5;
    vertexBuffer0Float32Array[1] = -0.5;
    vertexBuffer0Float32Array[2] = 1.0;
    vertexBuffer0Float32Array[3] = 1;
    vertexBuffer0Float32Array[4] = -0.5;
    vertexBuffer0Float32Array[5] = 0.5;
    vertexBuffer0Float32Array[6] = 1.0;
    vertexBuffer0Float32Array[7] = 1;
    vertexBuffer0Float32Array[8] = 0.5;
    vertexBuffer0Float32Array[9] = -0.5;
    vertexBuffer0Float32Array[10] = 1.0;
    vertexBuffer0Float32Array[11] = 1;
    vertexBuffer0Float32Array[12] = 0.5;
    vertexBuffer0Float32Array[13] = 0.5;
    vertexBuffer0Float32Array[14] = 1.0;
    vertexBuffer0Float32Array[15] = 1;
    vertexBuffer0.unmap();

    const textureDataBufferDescriptor = {size: Uint8Array.BYTES_PER_ELEMENT * 4 * 2 * 2, usage: GPUBufferUsage.TRANSFER_SRC | GPUBufferUsage.MAP_WRITE};
    const textureDataBuffer = device.createBuffer(textureDataBufferDescriptor);
    const textureDataBufferArrayBuffer = await textureDataBuffer.mapWriteAsync();
    const textureDataBufferUint8Array = new Uint8Array(textureDataBufferArrayBuffer);
    textureDataBufferUint8Array[0] = 255;
    textureDataBufferUint8Array[1] = 255;
    textureDataBufferUint8Array[2] = 255;
    textureDataBufferUint8Array[3] = 255;
    textureDataBufferUint8Array[4] = 255;
    textureDataBufferUint8Array[5] = 255;
    textureDataBufferUint8Array[6] = 255;
    textureDataBufferUint8Array[7] = 255;
    textureDataBufferUint8Array[8] = 255;
    textureDataBufferUint8Array[9] = 255;
    textureDataBufferUint8Array[10] = 255;
    textureDataBufferUint8Array[11] = 255;
    textureDataBufferUint8Array[12] = 255;
    textureDataBufferUint8Array[13] = 255;
    textureDataBufferUint8Array[14] = 255;
    textureDataBufferUint8Array[15] = 255;
    textureDataBuffer.unmap();

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

    const samplerDescriptor = {magFilter: "linear", minFilter: "linear"};
    const sampler = device.createSampler(samplerDescriptor);

    const bindGroupBindings = [{binding: 0, resource: textureView}, {binding: 1, resource: sampler}];
    const bindGroupDescriptor = {layout: bindGroupLayout, bindings: bindGroupBindings};
    const bindGroup = device.createBindGroup(bindGroupDescriptor);

    const context = canvas.getContext("gpu");
    const swapChainDescriptor = {device, format: "bgra8unorm"};
    const swapChain = context.configureSwapChain(swapChainDescriptor);
    const outputTexture = swapChain.getCurrentTexture();
    const outputTextureView = outputTexture.createDefaultView();

    const commandEncoder = device.createCommandEncoder(); // {}

    const bufferCopyView = {buffer: textureDataBuffer, rowPitch: Uint8Array.BYTES_PER_ELEMENT * 4 * 2, imageHeight: Uint8Array.BYTES_PER_ELEMENT * 4 * 2 * 2};
    const textureCopyView = {texture: texture};
    const copySize = {width: 2, height: 2, depth: 1};
    commandEncoder.copyBufferToTexture(bufferCopyView, textureCopyView, copySize);

    const clearColor = {r: 0, g: 0, b: 1, a: 1};
    const colorAttachments = [{attachment: outputTextureView, resolveTarget: null, loadOp: "clear", storeOp: "store", clearColor}];
    const depthStencilAttachment = null;
    const renderPassDescriptor = {colorAttachments, depthStencilAttachment};
    const renderPassEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
    renderPassEncoder.setPipeline(renderPipeline);
    renderPassEncoder.setBindGroup(0, bindGroup);
    renderPassEncoder.setVertexBuffers(0, [vertexBuffer0], [0]);
    renderPassEncoder.draw(4, 1, 0, 0);
    renderPassEncoder.endPass();
    const commandBuffer = commandEncoder.finish();
    device.getQueue().submit([commandBuffer]);

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