webgpuOverwriteTexture function

void webgpuOverwriteTexture(
  1. GPUDevice gpu,
  2. TextureHandle target,
  3. ByteData rgba,
  4. ScreenRect rect,
)

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,
    ),
  );
}