<!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)) : SV_Target 0 {
    return Load(theTexture, int2(0, 0));
}
`;

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

async function start(device) {
    const shaderModule = device.createShaderModule({code: shaderSource});
    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}]; // GPUColorWrite.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"}]};
    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.COPY_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] = 128;
    textureDataBufferUint8Array[5] = 128;
    textureDataBufferUint8Array[6] = 128;
    textureDataBufferUint8Array[7] = 255;
    textureDataBufferUint8Array[8] = 128;
    textureDataBufferUint8Array[9] = 128;
    textureDataBufferUint8Array[10] = 128;
    textureDataBufferUint8Array[11] = 255;
    textureDataBufferUint8Array[12] = 128;
    textureDataBufferUint8Array[13] = 128;
    textureDataBufferUint8Array[14] = 128;
    textureDataBufferUint8Array[15] = 255;
    textureDataBuffer.unmap();

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

    const bindGroupBindings = [{binding: 0, resource: textureView}];
    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>
