in src/webgpu/web_platform/reftests/canvas_complex.html.ts [44:145]
function copyBufferToTexture(ctx: GPUCanvasContext) {
const rows = ctx.canvas.height;
const { bytesPerBlock: bytesPerPixel } = getBlockInfoForColorTextureFormat(format);
const bytesPerRow = align(bytesPerPixel * ctx.canvas.width, 256);
const componentsPerPixel = 4;
const buffer = t.device.createBuffer({
mappedAtCreation: true,
size: rows * bytesPerRow,
usage: GPUBufferUsage.COPY_SRC,
});
// These are run only once per test, so there are no wasted reallocations below.
let red: Uint8Array | Uint16Array;
let green: Uint8Array | Uint16Array;
let blue: Uint8Array | Uint16Array;
let yellow: Uint8Array | Uint16Array;
const mapping = buffer.getMappedRange();
let data: Uint8Array | Uint16Array;
switch (format) {
case 'bgra8unorm':
case 'bgra8unorm-srgb':
{
data = new Uint8Array(mapping);
red = new Uint8Array([0x00, 0x00, 0x66, 0xff]);
green = new Uint8Array([0x00, 0x66, 0x00, 0xff]);
blue = new Uint8Array([0x66, 0x00, 0x00, 0xff]);
yellow = new Uint8Array([0x00, 0x66, 0x66, 0xff]);
}
break;
case 'rgba8unorm':
case 'rgba8unorm-srgb':
{
data = new Uint8Array(mapping);
red = new Uint8Array([0x66, 0x00, 0x00, 0xff]);
green = new Uint8Array([0x00, 0x66, 0x00, 0xff]);
blue = new Uint8Array([0x00, 0x00, 0x66, 0xff]);
yellow = new Uint8Array([0x66, 0x66, 0x00, 0xff]);
}
break;
case 'rgba16float':
{
data = new Uint16Array(mapping);
red = new Uint16Array([
float32ToFloat16Bits(0.4),
float32ToFloat16Bits(0.0),
float32ToFloat16Bits(0.0),
float32ToFloat16Bits(1.0),
]);
green = new Uint16Array([
float32ToFloat16Bits(0.0),
float32ToFloat16Bits(0.4),
float32ToFloat16Bits(0.0),
float32ToFloat16Bits(1.0),
]);
blue = new Uint16Array([
float32ToFloat16Bits(0.0),
float32ToFloat16Bits(0.0),
float32ToFloat16Bits(0.4),
float32ToFloat16Bits(1.0),
]);
yellow = new Uint16Array([
float32ToFloat16Bits(0.4),
float32ToFloat16Bits(0.4),
float32ToFloat16Bits(0.0),
float32ToFloat16Bits(1.0),
]);
}
break;
default:
unreachable();
}
for (let i = 0; i < ctx.canvas.width; ++i)
for (let j = 0; j < ctx.canvas.height; ++j) {
let pixel: Uint8Array | Uint16Array;
if (i < ctx.canvas.width / 2) {
if (j < ctx.canvas.height / 2) {
pixel = red;
} else {
pixel = blue;
}
} else {
if (j < ctx.canvas.height / 2) {
pixel = green;
} else {
pixel = yellow;
}
}
data.set(pixel, (i + j * (bytesPerRow / bytesPerPixel)) * componentsPerPixel);
}
buffer.unmap();
const encoder = t.device.createCommandEncoder({
label: 'canvas_complex:copyBufferToTexture',
});
encoder.copyBufferToTexture({ buffer, bytesPerRow }, { texture: ctx.getCurrentTexture() }, [
ctx.canvas.width,
ctx.canvas.height,
1,
]);
t.device.queue.submit([encoder.finish()]);
}