High watch CVSS 4.7 chrome Uninitialized Memory 🔧 Commit mapped

Overview

High
Severity
4.7
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUninitialized resource in Dawn
DescriptionUninitialized resource in Dawn
ComponentDawn
Sub-componentGL
Bug ClassUninitialized Memory
Action tierwatch — information disclosure — security-relevant, below the RCE-class bar
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Tracker556959073
Fix commit4d90aa23afd4 (dawn) +590/-35
CWECWE-908
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N
CISA KEVNot listed
CreditedGoogle
Reported2026-09-04 (per vendor advisory)
Fix landed2026-09-17 (public git)
Disclosed2026-09-29
Patch gap12 days — fix public in source before the advisory

Background

Dawn `BlitTextureToBuffer`
Dawn’s implementation of WebGPU texture-to-buffer copies, which on some backends emulates the copy with a shader “blit” that loads texels and packs them into the destination buffer.
`glReadPixels` readback path
the OpenGL ES fallback that reads a texture region into a buffer; per the OpenGL ES 3.1 spec, only RGBA32Uint/RGBA32Sint integer formats are guaranteed supported with a matching data layout.
Compute-shader blit (`textureLoadGeneral` / `encodeVectorInU32General`)
WGSL helpers, newly parameterized per texel type (TexelVector4/TexelVector2 aliased to f32/u32/i32), that deterministically load each texel and encode it into dst_buf.
Toggles `UseBlitForUintTextureToBufferCopy` / `UseBlitForSintTextureToBufferCopy`
new toggles, enabled by default on OpenGL ES, that route integer texture formats through the compute blit instead of the readback path.

Root Cause Analysis

On the OpenGL ES backend, texture-to-buffer copies for integer (Uint/Sint) texture formats relied on a glReadPixels-style readback path, but the OpenGL ES 3.1 spec only guarantees that path with a matching data layout for RGBA32Uint/RGBA32Sint; for the other integer formats the readback was not guaranteed to produce correctly-laid-out data, so bytes in the destination buffer could be left with incorrect or uninitialized contents. Because a WebGPU buffer written by a copy is expected to be fully and correctly populated and is subsequently readable by the page, this exposed uninitialized/garbage backing memory to script (an “uninitialized resource”).

The fix adds compute-shader blit code paths for all integer format/dimension combinations (1D/2D/2DArray/3D, plus cube fallback) with format-specific encoders (kEncodeRGBA8UintInU32, kEncodeRGBA8SintInU32, kEncodeRG16UintInU32, kEncodeRG16SintInU32, kEncodeRGB10A2UintInU32, and per-channel 32-bit loads such as kLoadR32Uint/kLoadRGBA32Sint) that deterministically load every texel and pack it into dst_buf. Integer formats are now routed to the compute blit on OpenGL ES except RGBA32Uint/RGBA32Sint (kept on the guaranteed glReadPixels layout) and integer cube textures in compat mode (which fall back to per-face glReadPixels because texture_cube<u32>/texture_cube<i32> lack textureSampleLevel/textureLoad).

Key insight
The single mistake was copying integer textures to buffers on OpenGL ES through a readback path the spec does not guarantee for most integer formats, so the destination buffer could contain wrongly-laid-out or uninitialized bytes; the fix replaces that path with deterministic compute-shader blits that fully write the buffer.

Attack Path

  1. Create an integer-format texture A page creates a WebGPU texture in an affected integer format (e.g. R8Uint, RG16Sint, RGB10A2Uint) on a device using the OpenGL ES backend.
  2. Copy texture to buffer The page issues a copyTextureToBuffer (BlitTextureToBuffer) whose destination buffer is mappable/readable back to script.
  3. Unreliable readback Pre-patch, the copy uses the glReadPixels path that is not guaranteed for that format’s data layout on OpenGL ES, leaving some destination bytes incorrect or uninitialized rather than the intended texel data.
  4. Read uninitialized memory The page maps and reads the destination buffer, observing uninitialized/garbage backing memory (an information disclosure of uninitialized GPU/driver memory contents). Any cross-origin significance of the leaked bytes is (inferred).

Impact Assessment

An attacker-controlled page on an OpenGL ES device could read uninitialized memory back from a texture-to-buffer copy of integer-format textures, an information-disclosure (“uninitialized resource”) condition; the leak occurs within the GPU/renderer copy path and requires the vulnerable backend and an affected integer format. The advisory classifies this as an uninitialized-resource issue in Dawn and does not report exploited-in-the-wild status; the changed non-shader files (Toggles, CommandBufferGL, PhysicalDeviceGL, CommandEncoder, Buffer, Texture) are truncated in the diff and their exact roles are not shown.

Changed Functions

FunctionChangeNotes
switch
src/dawn/native/BlitTextureToBuffer.cpp
modified

Files Changed

  • src/dawn/native/opengl/CommandBufferGL.cpp
  • src/dawn/native/Toggles.h
  • src/dawn/native/opengl/PhysicalDeviceGL.cpp
  • src/dawn/native/BlitTextureToBuffer.cpp
  • src/dawn/native/Toggles.cpp
  • src/dawn/native/CommandEncoder.cpp
  • src/dawn/native/Buffer.cpp
  • src/dawn/tests/end2end/CopyTests.cpp
  • src/dawn/native/Texture.cpp

Audit Directions

  • Backend readback paths not guaranteed by spec
    Audit texture-to-buffer / copy paths that rely on glReadPixels (or analogous driver readbacks) for formats/layouts the backend spec does not guarantee, since they may leave destination buffers partially or wrongly written.
  • Destination buffers not fully written by a copy
    Review copy emulations for format/dimension combinations that fall through to a default or skip, leaving mappable buffer memory uninitialized and readable by script.
  • Integer / less-common format coverage
    Check that Uint/Sint, cube, 1D, and 3D variants are handled in every copy/blit switch, as these are frequent gaps that expose uninitialized resources.
From 4d90aa23afd490070ac38b6244aa875418a201b0 Mon Sep 17 00:00:00 2001
From: Shrek Shao <shrekshao@google.com>
Date: Thu, 17 Sep 2026 14:03:27 -0700
Subject: [PATCH] [gl] Add compute blit for Sint and Uint texture formats

This CL:
- Adds toggles UseBlitForUintTextureToBufferCopy and
  UseBlitForSintTextureToBufferCopy, enabled by default on OpenGLES.
- Implements compute shader blits for integer (Uint and Sint) textures
  in BlitTextureToBuffer.
- Routes integer formats to compute shader blits on OpenGLES except
  RGBA32Uint and RGBA32Sint, which are the only integer formats
  guaranteed by the OpenGL ES 3.1 spec to be supported by glReadPixels
  with matching data layout.
- Bypasses compute shader blit for integer cube textures in compat mode.
  In WGSL, texture_cube<u32> and texture_cube<i32> do not support
  textureSampleLevel or textureLoad, and textureGather only operates on
  mip level 0 for a single component. Therefore, integer cube textures
  fall back to glReadPixels via FramebufferTexture2D for each cube face.
- Expands CopyTests_T2B and CopyTests_T2B_Compat format parameters to
  cover integer formats.

Bug: 556959073, 562077184
Change-Id: Ica78ec08b6702ea386c7d95e36b5f2fd43a1b02b
TAG=agy
CONV=8a0c15f2-fbb5-4cb0-bd81-240982407cd0
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/340755
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Shrek Shao <shrekshao@google.com>
---
diff --git a/src/dawn/native/BlitTextureToBuffer.cpp b/src/dawn/native/BlitTextureToBuffer.cpp
index fcf48af..2f7b30d 100644
--- a/src/dawn/native/BlitTextureToBuffer.cpp
+++ b/src/dawn/native/BlitTextureToBuffer.cpp
@@ -129,7 +129,15 @@
     @group(0) @binding(0) var src_tex : texture_cube<f32>;
 );
 
-constexpr std::string_view kUintTexture = DAWN_MULTILINE(
+constexpr std::string_view kUintTexture1D = DAWN_MULTILINE(
+    fn textureLoadGeneral(tex: texture_1d<u32>, coords: vec3u, level: u32) -> vec4<u32> {
+        //
+        return textureLoad(tex, coords.x, level);
+    }
+    @group(0) @binding(0) var src_tex : texture_1d<u32>;
+);
+
+constexpr std::string_view kUintTexture2D = DAWN_MULTILINE(
     fn textureLoadGeneral(tex: texture_2d<u32>, coords: vec3u, level: u32) -> vec4<u32> {
         //
         return textureLoad(tex, coords.xy, level);
@@ -137,7 +145,7 @@
     @group(0) @binding(0) var src_tex : texture_2d<u32>;
 );
 
-constexpr std::string_view kUintTextureArray = DAWN_MULTILINE(
+constexpr std::string_view kUintTexture2DArray = DAWN_MULTILINE(
     fn textureLoadGeneral(tex: texture_2d_array<u32>, coords: vec3u, level: u32) -> vec4<u32> {
         //
         return textureLoad(tex, coords.xy, coords.z, level);
@@ -145,6 +153,14 @@
     @group(0) @binding(0) var src_tex : texture_2d_array<u32>;
 );
 
+constexpr std::string_view kUintTexture3D = DAWN_MULTILINE(
+    fn textureLoadGeneral(tex: texture_3d<u32>, coords: vec3u, level: u32) -> vec4<u32> {
+        //
+        return textureLoad(tex, coords, level);
+    }
+    @group(0) @binding(0) var src_tex : texture_3d<u32>;
+);
+
 // textureSampleLevel doesn't support texture_cube<u32>
 // Use textureGather as a workaround.
 // Always choose the texel with the smallest coord (stored in w component).
@@ -158,6 +174,58 @@
     @group(0) @binding(0) var src_tex : texture_cube<u32>;
 );
 
+constexpr std::string_view kSintTexture1D = DAWN_MULTILINE(
+    fn textureLoadGeneral(tex: texture_1d<i32>, coords: vec3u, level: u32) -> vec4<i32> {
+        //
+        return textureLoad(tex, coords.x, level);
+    }
+    @group(0) @binding(0) var src_tex : texture_1d<i32>;
+);
+
+constexpr std::string_view kSintTexture2D = DAWN_MULTILINE(
+    fn textureLoadGeneral(tex: texture_2d<i32>, coords: vec3u, level: u32) -> vec4<i32> {
+        //
+        return textureLoad(tex, coords.xy, level);
+    }
+    @group(0) @binding(0) var src_tex : texture_2d<i32>;
+);
+
+constexpr std::string_view kSintTexture2DArray = DAWN_MULTILINE(
+    fn textureLoadGeneral(tex: texture_2d_array<i32>, coords: vec3u, level: u32) -> vec4<i32> {
+        //
+        return textureLoad(tex, coords.xy, coords.z, level);
+    }
+    @group(0) @binding(0) var src_tex : texture_2d_array<i32>;
+);
+
+constexpr std::string_view kSintTexture3D = DAWN_MULTILINE(
+    fn textureLoadGeneral(tex: texture_3d<i32>, coords: vec3u, level: u32) -> vec4<i32> {
+        //
+        return textureLoad(tex, coords, level);
+    }
+    @group(0) @binding(0) var src_tex : texture_3d<i32>;
+);
+
+constexpr std::string_view kTexelVector4F32 = DAWN_MULTILINE(
+    alias TexelVector4 = vec4f;
+);
+constexpr std::string_view kTexelVector4U32 = DAWN_MULTILINE(
+    alias TexelVector4 = vec4<u32>;
+);
+constexpr std::string_view kTexelVector4I32 = DAWN_MULTILINE(
+    alias TexelVector4 = vec4<i32>;
+);
+
+constexpr std::string_view kTexelVector2F32 = DAWN_MULTILINE(
+    alias TexelVector2 = vec2f;
+);
+constexpr std::string_view kTexelVector2U32 = DAWN_MULTILINE(
+    alias TexelVector2 = vec2<u32>;
+);
+constexpr std::string_view kTexelVector2I32 = DAWN_MULTILINE(
+    alias TexelVector2 = vec2<i32>;
+);
+
 constexpr std::string_view kEncodeRGBA8UnormInU32 = DAWN_MULTILINE(
     fn encodeVectorInU32General(v: vec4f) -> u32 {
         //
@@ -172,6 +240,20 @@
     }
 );
 
+constexpr std::string_view kEncodeRGBA8UintInU32 = DAWN_MULTILINE(
+    fn encodeVectorInU32General(v: vec4<u32>) -> u32 {
+        //
+        return pack4xU8(v);
+    }
+);
+
+constexpr std::string_view kEncodeRGBA8SintInU32 = DAWN_MULTILINE(
+    fn encodeVectorInU32General(v: vec4<i32>) -> u32 {
+        //
+        return pack4xI8(v);
+    }
+);
+
 // Storing and swizzling bgra8unorm texel values and convert to u32.
 constexpr std::string_view kEncodeBGRA8UnormInU32 = DAWN_MULTILINE(
     fn encodeVectorInU32General(v: vec4f) -> u32 {
@@ -187,6 +269,27 @@
     }
 );
 
+constexpr std::string_view kEncodeRG16UintInU32 = DAWN_MULTILINE(
+    fn encodeVectorInU32General(v: vec2<u32>) -> u32 {
+        //
+        return (v.x & 0xffffu) | ((v.y & 0xffffu) << 16u);
+    }
+);
+
+constexpr std::string_view kEncodeRG16SintInU32 = DAWN_MULTILINE(
+    fn encodeVectorInU32General(v: vec2<i32>) -> u32 {
+        //
+        return (bitcast<u32>(v.x) & 0xffffu) | ((bitcast<u32>(v.y) & 0xffffu) << 16u);
+    }
+);
+
+constexpr std::string_view kEncodeRGB10A2UintInU32 = DAWN_MULTILINE(
+    fn encodeVectorInU32General(v: vec4<u32>) -> u32 {
+        //
+        return (v.r & 0x3ffu) | ((v.g & 0x3ffu) << 10u) | ((v.b & 0x3ffu) << 20u) | ((v.a & 0x3u) << 30u);
+    }
+);
+
 // Keep in sync with the WGSL struct below.
 struct Params {
     // copyExtent
@@ -396,9 +499,9 @@
 constexpr std::string_view kPackR8ToU32 = DAWN_MULTILINE(
         // Result bits to store into dst_buf
         var result: u32 = 0u;
-        // Storing xnorm8 texel values
-        // later called by pack4x8xnorm to convert to u32.
-        var v: vec4<f32>;
+        // Storing texel values
+        // later called by encodeVectorInU32General to convert to u32.
+        var v: TexelVector4;
 
         // dstBuf value is used for starting part.
         var mask: u32 = 0xffffffffu;
@@ -534,9 +637,9 @@
 constexpr std::string_view kPackRG8ToU32 = DAWN_MULTILINE(
         // Result bits to store into dst_buf
         var result: u32 = 0u;
-        // Storing snorm8 texel values
-        // later called by pack4x8xnorm to convert to u32.
-        var v: vec4<f32>;
+        // Storing texel values
+        // later called by encodeVectorInU32General to convert to u32.
+        var v: TexelVector4;
 
         // dstBuf value is used for starting part.
         var mask: u32 = 0xffffffffu;
@@ -569,9 +672,9 @@
 constexpr std::string_view kPackR16ToU32 = DAWN_MULTILINE(
         // Result bits to store into dst_buf
         var result: u32 = 0u;
-        // Storing half texel values
-        // later called by pack2x16unorm to convert to u32.
-        var v: vec2f;
+        // Storing half/integer texel values
+        // later called by encodeVectorInU32General to convert to u32.
+        var v: TexelVector2;
 
         // dstBuf value is used for starting part.
         var mask: u32 = 0xffffffffu;
@@ -598,13 +701,13 @@
 );
 
 constexpr std::string_view kPackRG16ToU32 = DAWN_MULTILINE(  //
-        let v: vec2f = textureLoadGeneral(src_tex, coord0, params.mipLevel).rg;
+        let v = textureLoadGeneral(src_tex, coord0, params.mipLevel).rg;
         let result = encodeVectorInU32General(v);
 );
 
 // Load RGBA16 and pack to 2 uint4_t
 constexpr std::string_view kLoadRGBA16ToU32 = DAWN_MULTILINE(
-        let v: vec4f = textureLoadGeneral(src_tex, coord0, params.mipLevel);
+        let v = textureLoadGeneral(src_tex, coord0, params.mipLevel);
         // dstOffset is based on 8 bytes so we need to multiply by 2 to get uint32 offset.
         let uintOffset = dstOffset << 1;
         dst_buf[uintOffset] = encodeVectorInU32General(v.rg);
@@ -747,6 +850,47 @@
         dst_buf[uintOffset + 3u] = v.a;
 );
 
+constexpr std::string_view kLoadR32Uint = DAWN_MULTILINE(  //
+        dst_buf[dstOffset] = textureLoadGeneral(src_tex, coord0, params.mipLevel).r;
+);
+constexpr std::string_view kLoadR32Sint = DAWN_MULTILINE(  //
+        dst_buf[dstOffset] = bitcast<u32>(textureLoadGeneral(src_tex, coord0, params.mipLevel).r);
+);
+constexpr std::string_view kLoadRG32Uint =
+    DAWN_MULTILINE(
+        let v = textureLoadGeneral(src_tex, coord0, params.mipLevel);
+        // dstOffset is based on 8 bytes so we need to multiply by 2.
+        let uintOffset = dstOffset << 1;
+        dst_buf[uintOffset] = v.r;
+        dst_buf[uintOffset + 1u] = v.g;
+);
+constexpr std::string_view kLoadRG32Sint =
+    DAWN_MULTILINE(
+        let v = textureLoadGeneral(src_tex, coord0, params.mipLevel);
+        // dstOffset is based on 8 bytes so we need to multiply by 2.
+        let uintOffset = dstOffset << 1;
+        dst_buf[uintOffset] = bitcast<u32>(v.r);
+        dst_buf[uintOffset + 1u] = bitcast<u32>(v.g);
+);
+constexpr std::string_view kLoadRGBA32Uint = DAWN_MULTILINE(  //
+        let v = textureLoadGeneral(src_tex, coord0, params.mipLevel);
+        // dstOffset is based on 16 bytes so we need to multiply by 4.
+        let uintOffset = dstOffset << 2;
+        dst_buf[uintOffset] = v.r;
+        dst_buf[uintOffset + 1u] = v.g;
+        dst_buf[uintOffset + 2u] = v.b;
+        dst_buf[uintOffset + 3u] = v.a;
+);
+constexpr std::string_view kLoadRGBA32Sint = DAWN_MULTILINE(  //
+        let v = textureLoadGeneral(src_tex, coord0, params.mipLevel);
+        // dstOffset is based on 16 bytes so we need to multiply by 4.
+        let uintOffset = dstOffset << 2;
+        dst_buf[uintOffset] = bitcast<u32>(v.r);
+        dst_buf[uintOffset + 1u] = bitcast<u32>(v.g);
+        dst_buf[uintOffset + 2u] = bitcast<u32>(v.b);
+        dst_buf[uintOffset + 3u] = bitcast<u32>(v.a);
+);
+
 ResultOrError<Ref<ComputePipelineBase>> GetOrCreateTextureToBufferPipeline(
     DeviceBase* device,
     const TextureCopy& src,
@@ -793,10 +937,10 @@
         switch (viewDimension) {
             // Stencil cannot have e1D texture.
             case wgpu::TextureViewDimension::e2D:
-                shader += kUintTexture;
+                shader += kUintTexture2D;
                 break;
             case wgpu::TextureViewDimension::e2DArray:
-                shader += kUintTextureArray;
+                shader += kUintTexture2DArray;
                 break;
             case wgpu::TextureViewDimension::Cube:
                 shader += kCubeCoordCommon;
@@ -806,6 +950,42 @@
                 DAWN_UNREACHABLE();
         }
     };
+    auto AppendUintTextureHead = [&]() {
+        switch (viewDimension) {
+            case wgpu::TextureViewDimension::e1D:
+                shader += kUintTexture1D;
+                break;
+            case wgpu::TextureViewDimension::e2D:
+                shader += kUintTexture2D;
+                break;
+            case wgpu::TextureViewDimension::e2DArray:
+                shader += kUintTexture2DArray;
+                break;
+            case wgpu::TextureViewDimension::e3D:
+                shader += kUintTexture3D;
+                break;
+            default:
+                DAWN_UNREACHABLE();
+        }
+    };
+    auto AppendSintTextureHead = [&]() {
+        switch (viewDimension) {
+            case wgpu::TextureViewDimension::e1D:
+                shader += kSintTexture1D;
+                break;
+            case wgpu::TextureViewDimension::e2D:
+                shader += kSintTexture2D;
+                break;
+            case wgpu::TextureViewDimension::e2DArray:
+                shader += kSintTexture2DArray;
+                break;
+            case wgpu::TextureViewDimension::e3D:
+                shader += kSintTexture3D;
+                break;
+            default:
+                DAWN_UNREACHABLE();
+        }
+    };
 
     switch (format.format) {
         case wgpu::TextureFormat::R8Snorm:
@@ -813,6 +993,7 @@
             AppendFloatTextureHead();
             shader += kDstBufferU32;
             shader += format.IsSnorm() ? kEncodeRGBA8SnormInU32 : kEncodeRGBA8UnormInU32;
+            shader += kTexelVector4F32;
             shader += kCommonHead;
             shader += kNonMultipleOf4OffsetStart;
             shader += kPackR8ToU32;
@@ -824,6 +1005,7 @@
             AppendFloatTextureHead();
             shader += kDstBufferU32;
             shader += format.IsSnorm() ? kEncodeRGBA8SnormInU32 : kEncodeRGBA8UnormInU32;
+            shader += kTexelVector4F32;
             shader += kCommonHead;
             shader += kNonMultipleOf4OffsetStart;
             shader += kPackRG8ToU32;
@@ -841,6 +1023,70 @@
             shader += kCommonEnd;
             textureSampleType = wgpu::TextureSampleType::Float;
             break;
+        case wgpu::TextureFormat::R8Uint:
+            AppendUintTextureHead();
+            shader += kDstBufferU32;
+            shader += kEncodeRGBA8UintInU32;
+            shader += kTexelVector4U32;
+            shader += kCommonHead;
+            shader += kNonMultipleOf4OffsetStart;
+            shader += kPackR8ToU32;
+            shader += kCommonEnd;
+            textureSampleType = wgpu::TextureSampleType::Uint;
+            break;
+        case wgpu::TextureFormat::R8Sint:
+            AppendSintTextureHead();
+            shader += kDstBufferU32;
+            shader += kEncodeRGBA8SintInU32;
+            shader += kTexelVector4I32;
+            shader += kCommonHead;
+            shader += kNonMultipleOf4OffsetStart;
+            shader += kPackR8ToU32;
+            shader += kCommonEnd;
+            textureSampleType = wgpu::TextureSampleType::Sint;
+            break;
+        case wgpu::TextureFormat::RG8Uint:
+            AppendUintTextureHead();
+            shader += kDstBufferU32;
+            shader += kEncodeRGBA8UintInU32;
+            shader += kTexelVector4U32;
+            shader += kCommonHead;
+            shader += kNonMultipleOf4OffsetStart;
+            shader += kPackRG8ToU32;
+            shader += kCommonEnd;
+            textureSampleType = wgpu::TextureSampleType::Uint;
+            break;
+        case wgpu::TextureFormat::RG8Sint:
+            AppendSintTextureHead();
+            shader += kDstBufferU32;
+            shader += kEncodeRGBA8SintInU32;
+            shader += kTexelVector4I32;
... (file diff truncated)
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/src/dawn/tests/end2end/CopyTests.cpp b/src/dawn/tests/end2end/CopyTests.cpp
index 7dfc35e..5daed79 100644
--- a/src/dawn/tests/end2end/CopyTests.cpp
+++ b/src/dawn/tests/end2end/CopyTests.cpp
@@ -2238,31 +2238,36 @@
 
         wgpu::TextureFormat::RGBA8Unorm,
 
+        // Also covers OpenGL compat Toggle::UseBlitForUintTextureToBufferCopy and
+        // Toggle::UseBlitForSintTextureToBufferCopy
         wgpu::TextureFormat::R8Uint,
         wgpu::TextureFormat::R8Sint,
-
+        wgpu::TextureFormat::RG8Uint,
+        wgpu::TextureFormat::RG8Sint,
+        wgpu::TextureFormat::RGBA8Uint,
+        wgpu::TextureFormat::RGBA8Sint,
         wgpu::TextureFormat::R16Uint,
         wgpu::TextureFormat::R16Sint,
-        wgpu::TextureFormat::R16Float,
-
         wgpu::TextureFormat::RG16Uint,
         wgpu::TextureFormat::RG16Sint,
-        wgpu::TextureFormat::RG16Float,
-
+        wgpu::TextureFormat::RGBA16Uint,
+        wgpu::TextureFormat::RGBA16Sint,
         wgpu::TextureFormat::R32Uint,
         wgpu::TextureFormat::R32Sint,
+        wgpu::TextureFormat::RG32Uint,
+        wgpu::TextureFormat::RG32Sint,
+        wgpu::TextureFormat::RGB10A2Uint,
+
+        wgpu::TextureFormat::RGBA32Uint,
+        wgpu::TextureFormat::RGBA32Sint,
 
         // Also covers OpenGL compat Toggle::UseBlitForNonRGBAFloatTextureToBufferCopy
+        wgpu::TextureFormat::R16Float,
+        wgpu::TextureFormat::RG16Float,
         wgpu::TextureFormat::R32Float,
         wgpu::TextureFormat::RG32Float,
 
-        wgpu::TextureFormat::RG32Uint,
-        wgpu::TextureFormat::RG32Sint,
-
-        wgpu::TextureFormat::RGBA16Uint,
-        wgpu::TextureFormat::RGBA16Sint,
         wgpu::TextureFormat::RGBA16Float,
-
         wgpu::TextureFormat::RGBA32Float,
 
         wgpu::TextureFormat::RGB10A2Unorm,
@@ -2456,6 +2461,28 @@
 
                             // Testing OpenGL compat Toggle::UseBlitForRGB9E5UfloatTextureCopy
                             wgpu::TextureFormat::RGB9E5Ufloat,
+
+                            // Testing OpenGL compat Toggle::UseBlitForUintTextureToBufferCopy and
+                            // Toggle::UseBlitForSintTextureToBufferCopy
+                            wgpu::TextureFormat::R8Uint,
+                            wgpu::TextureFormat::R8Sint,
+                            wgpu::TextureFormat::RG8Uint,
+                            wgpu::TextureFormat::RG8Sint,
+                            wgpu::TextureFormat::RGBA8Uint,
+                            wgpu::TextureFormat::RGBA8Sint,
+
+                            wgpu::TextureFormat::R16Sint,
+                            wgpu::TextureFormat::RG16Sint,
+                            wgpu::TextureFormat::RGBA16Sint,
+
+                            wgpu::TextureFormat::R32Uint,
+                            wgpu::TextureFormat::R32Sint,
+                            wgpu::TextureFormat::RG32Uint,
+                            wgpu::TextureFormat::RG32Sint,
+                            wgpu::TextureFormat::RGBA32Uint,
+                            wgpu::TextureFormat::RGBA32Sint,
+
+                            wgpu::TextureFormat::RGB10A2Uint,
                         });
 
 // Test that copying an entire texture with 256-byte aligned dimensions works
Loading diff…