webgpuOverwriteTexture function
Writes rgba into rect of target's base level. See
GraphicsDevice.overwriteTexture — the caller already refused a
compressed format and a non-zero mip level, so this is always a plain
RGBA8 region.
Implementation
void webgpuOverwriteTexture(
GPUDevice gpu,
TextureHandle target,
ByteData rgba,
ScreenRect rect,
) {
final texture = (target.backend as WebGpuTexture).texture;
final bytes = rgba.buffer.asUint8List(rgba.offsetInBytes, rgba.lengthInBytes);
// `writeTexture` stores the bytes as the texture lays them out, and the
// contract hands over RGBA whatever the target is. A `bgra8unorm` target —
// one of the two formats the caller already let through — takes them with
// red and blue exchanged, on a copy, so the caller's buffer is left alone.
final stored = target.format == TextureFormat.b8g8r8a8UNormInt
? _swappedCopy(bytes)
: bytes;
// Not `gpuBlockLayoutOf`: that reads `TextureFormat.blockLayout`, which
// only a compressed format carries — `r8g8b8a8UNormInt` is what this
// function's own doc comment says it always is, four bytes a pixel with
// no block to round up to.
gpu.queue.writeTexture(
GPUTexelCopyTextureInfo(
texture: texture,
mipLevel: 0,
origin: GPUOrigin3DDict(x: rect.x, y: rect.y, z: 0),
aspect: 'all',
),
stored.toJS,
GPUTexelCopyBufferLayout(
offset: 0,
bytesPerRow: rect.width * 4,
rowsPerImage: rect.height,
),
GPUExtent3DDict(
width: rect.width,
height: rect.height,
depthOrArrayLayers: 1,
),
);
}