| <!DOCTYPE html><!-- webkit-test-runner [ experimental:WebGPUEnabled=true ] --> |
| <meta charset="utf-8"> |
| <title>Basic Blitting</title> |
| <meta name="assert" content="Blit operations copy a green canvas."> |
| <link rel="match" href="blit-commands-expected.html"> |
| <p>Pass if square canvas below is completely green.</p> |
| <canvas width="400" height="400"></canvas> |
| <body> |
| <script src="js/webgpu-functions.js"></script> |
| <script> |
| if (window.testRunner) |
| testRunner.waitUntilDone(); |
| |
| async function loadImage() { |
| const image = new Image(); |
| image.src = "resources/green-400.png"; |
| image.onload = function() { |
| test(image).then(function() { |
| if (window.testRunner) |
| testRunner.notifyDone(); |
| }, function() { |
| if (window.testRunner) |
| testRunner.notifyDone(); |
| }); |
| } |
| } |
| |
| async function test(image) { |
| const device = await getBasicDevice(); |
| |
| 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 bufferDescriptor = { |
| size: imageData.data.byteLength, |
| usage: GPUBufferUsage.TRANSFER_SRC |
| }; |
| bufferA = createBufferWithData(device, bufferDescriptor, imageData.data.buffer); |
| |
| bufferDescriptor.usage |= GPUBufferUsage.TRANSFER_DST; |
| const bufferB = device.createBuffer(bufferDescriptor); |
| const bufferViewB = { |
| buffer: bufferB, |
| rowPitch: image.width * 4, |
| imageHeight: 0 |
| }; |
| |
| const textureSize = { |
| width: image.width, |
| height: image.height, |
| depth: 1 |
| }; |
| const textureDescriptor = { |
| size: textureSize, |
| format: "rgba8unorm", |
| usage: GPUTextureUsage.TRANSFER_SRC | GPUTextureUsage.TRANSFER_DST |
| }; |
| const textureA = device.createTexture(textureDescriptor); |
| const textureViewA = { texture: textureA }; |
| |
| const textureB = device.createTexture(textureDescriptor); |
| const textureViewB = { texture: textureB }; |
| |
| const readBufferDescriptor = { |
| size: imageData.data.byteLength, |
| usage: GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.MAP_READ |
| }; |
| const readBuffer = device.createBuffer(readBufferDescriptor); |
| const readBufferView = { |
| buffer: readBuffer, |
| rowPitch: image.width * 4, |
| imageHeight: 0 |
| }; |
| |
| const commandEncoder = device.createCommandEncoder(); |
| commandEncoder.copyBufferToBuffer(bufferA, 0, bufferB, 0, imageData.data.byteLength); |
| commandEncoder.copyBufferToTexture(bufferViewB, textureViewA, textureSize); |
| commandEncoder.copyBufferToTexture(bufferViewB, textureViewA, textureSize); |
| commandEncoder.copyTextureToTexture(textureViewA, textureViewB, textureSize); |
| commandEncoder.copyTextureToBuffer(textureViewB, readBufferView, textureSize); |
| device.getQueue().submit([commandEncoder.finish()]); |
| bufferA.destroy(); |
| bufferB.destroy(); |
| textureA.destroy(); |
| textureB.destroy(); |
| |
| const resultContext = document.querySelector('canvas').getContext('2d'); |
| |
| await readBuffer.mapReadAsync().then(ab => { |
| const array = new Uint8ClampedArray(ab); |
| const resultImageData = new ImageData(array, image.width, image.height); |
| |
| resultContext.putImageData(resultImageData, 0, 0); |
| |
| readBuffer.destroy(); |
| }); |
| } |
| |
| loadImage(); |
| </script> |
| </body> |