<!DOCTYPE html>
<meta charset="utf-8">
<title>Blitting Texture To Texture</title>
<meta name="assert" content="Blit operations populate a texture correctly (all mip levels).">
<link rel="match" href="blit-commands-texture-to-texture-expected.html">
<p>Pass if square canvas below shows a green mip chain on a red background.</p>
<canvas width="512" height="512"></canvas>
<body>
<script src="js/webgpu-functions.js"></script>
<script>
if (window.testRunner)
    testRunner.waitUntilDone();

async function loadTextureFromCanvas2d(device, canvas2d) {
    const textureSize = {
        width:  canvas2d.width,
        height: canvas2d.height,
        depth:  2
    };

    // Mipmap count
    let maxResolution = Math.max(canvas2d.width, canvas2d.height);
    let mipLevelCount = Math.ceil(Math.log2(maxResolution));
    if (mipLevelCount < 1) mipLevelCount = 1;

    const textureDescriptor = {
        size: textureSize,
        mipLevelCount: mipLevelCount,
        sampleCount: 1,
        dimension: "2d",
        format: "rgba8unorm",
        usage: GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST | GPUTextureUsage.SAMPLED 
    };

    // Create texture and also add the descriptor
    const texture = device.createTexture(textureDescriptor);
    textureSize.depth = 1;
    texture.descriptor = textureDescriptor;

    // Texture data 
    const context2d = canvas2d.getContext('2d');
    const imageData = context2d.getImageData(0, 0, canvas2d.width, canvas2d.height);

    const textureDataBufferDescriptor = {
        size: imageData.data.length,
        usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.MAP_WRITE
    };
    const textureDataBuffer = device.createBuffer(textureDataBufferDescriptor);

    const textureArrayBuffer = await textureDataBuffer.mapWriteAsync();
    const textureWriteArray = new Uint8Array(textureArrayBuffer);
    textureWriteArray.set(imageData.data);
    textureDataBuffer.unmap();

    const dataCopyView = {
        buffer: textureDataBuffer,
        offset: 0,
        rowPitch: canvas2d.width * 4,
        imageHeight: canvas2d.width * canvas2d.height * 4
    };
    const textureCopyView = {
        texture: texture,
        mipLevel: 0,
        arrayLayer: 0,
        origin: { x: 0, y: 0, z: 0 }
    };

    const blitCommandEncoder = device.createCommandEncoder();
    blitCommandEncoder.copyBufferToTexture(dataCopyView, textureCopyView, textureSize);
    device.getQueue().submit([blitCommandEncoder.finish()]);

    return texture;
}

async function test(device) {
    const canvas2d  = await document.querySelector("canvas");
    const context2d = canvas2d.getContext('2d');

    // textureA (layer 0, mip 0): Green
    context2d.fillStyle = 'rgb(0, 255, 0)';
    context2d.fillRect(0, 0, canvas2d.width, canvas2d.height);
    const textureA = await loadTextureFromCanvas2d(device, canvas2d);

    // textureB (layer 0, mip 0): Red
    context2d.fillStyle = 'rgb(255, 0, 0)';
    context2d.fillRect(0, 0, canvas2d.width, canvas2d.height);
    const textureB = await loadTextureFromCanvas2d(device, canvas2d);

    // Clean canvas to blue
    context2d.fillStyle = 'rgb(0, 0, 255)';
    context2d.fillRect(0, 0, canvas2d.width, canvas2d.height);

    // Test copyTextureToTexture

    let size = Object.assign({}, textureA.descriptor.size);
    let blitCommandEncoder = device.createCommandEncoder();
    for (var i = 1; i < textureA.descriptor.mipLevelCount; ++i) {
        size.width  = Math.max(Math.floor(size.width / 2), 1);
        size.height = Math.max(Math.floor(size.height / 2), 1);

        let srcTextureCopyView = {
            texture: textureA,
            mipLevel: 0,
            arrayLayer: 0,
            origin: { x: 0, y: 0, z: 0 }
        };
        let dstTextureCopyView = {
            texture: textureA,
            mipLevel: i,
            arrayLayer: 1,
            origin: { x: 0, y: 0, z: 0 }
        };
        // Populate textureA (layer 1, mip i)
        blitCommandEncoder.copyTextureToTexture(srcTextureCopyView, dstTextureCopyView, size);

        srcTextureCopyView = {
            texture: textureA,
            mipLevel: i,
            arrayLayer: 1,
            origin: { x: 0, y: 0, z: 0 }
        };
        dstTextureCopyView = {
            texture: textureB,
            mipLevel: 0,
            arrayLayer: 0,
            origin: { x: 0, y: size.height, z: 0 }
        };
        // Populate textureB (layer 0, mip 0) with textureA (layer 1, mip i)
        blitCommandEncoder.copyTextureToTexture(srcTextureCopyView, dstTextureCopyView, size);
    }

    // Render textureB into canvas2d

    const imageDataLengthInBytes = canvas2d.width * canvas2d.height * 4;
    const bufferDescriptor = {
        size: imageDataLengthInBytes,
        usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
    };
    const bufferA = device.createBuffer(bufferDescriptor);

    const bufferCopyView = {
        buffer: bufferA,
        rowPitch: canvas2d.width * 4,
        imageHeight: canvas2d.width * canvas2d.height * 4
    };
    const textureCopyView = {
        texture: textureB
    };
    blitCommandEncoder.copyTextureToBuffer(textureCopyView, bufferCopyView, textureA.descriptor.size);

    device.getQueue().submit([blitCommandEncoder.finish()]);

    const ab = await bufferA.mapReadAsync()
    const array = new Uint8ClampedArray(ab);
    const resultImageData = new ImageData(array, canvas2d.width, canvas2d.height);

    context2d.putImageData(resultImageData, 0, 0);

    bufferA.destroy();
}

getBasicDevice().then(function(device) {
    test(device).then(function() {
        if (window.testRunner)
            testRunner.notifyDone();
    }, function(e) {
        if (window.testRunner)
            testRunner.notifyDone();
    });
}, function() {
    const canvas2d = document.querySelector("canvas");
    drawGreenMipChainOnRedBackgroundInSoftware(canvas2d);
    if (window.testRunner)
        testRunner.notifyDone();
});
</script>
</body>
