gpui: Store GPU-facing bools as PaddedBool32 to avoid uninitialized padding (#60482)
`PolychromeSprite` in `crates/gpui/src/scene.rs` is `#[repr(C)]` and had a `grayscale: bool` field followed by 3 compiler-inserted padding bytes that were never written. The wgpu renderer's `instance_bytes` reinterprets `&[PolychromeSprite]` as `&[u8]` via `slice::from_raw_parts` and passes it to `queue.write_buffer`, so those uninitialized padding bytes were exposed behind a shared `&[u8]` on every frame that draws an image or emoji, which is undefined behavior. Rather than widening the field to a raw `u32` (which would suggest values other than 0 and 1 are meaningful), this introduces `PaddedBool32`: a `#[repr(transparent)]` wrapper around `u32` whose only public constructor is `From<bool>`, so the 0-or-1 invariant is enforced by the type while the layout has no padding. `Underline.wavy`, which was already a raw `u32` for the same reason, is converted too. cbindgen emits the wrapper as `typedef uint32_t PaddedBool32;`, so the generated Metal header and shaders are unchanged. The WGSL and HLSL shaders already declared these fields as `u32`/`uint`; their `& 0xFFu` masks, which existed to ignore the garbage padding bytes, are now simplified to plain comparisons. Release Notes: - N/A
This commit is contained in:
1 parent
a103d8322b
commit
711e286c7f
4 files changed
+23
-9
No files matched your search
@@ -1249,7 +1249,7 @@ float4 polychrome_sprite_fragment(PolychromeSpriteFragmentInput input): SV_Targe
|
||||
float distance = quad_sdf(input.position.xy, sprite.bounds, sprite.corner_radii);
|
||||
|
||||
float4 color = sample;
|
||||
if ((sprite.grayscale & 0xFFu) != 0u) {
|
||||
if (sprite.grayscale != 0u) {
|
||||
float3 grayscale = dot(color.rgb, GRAYSCALE_FACTORS);
|
||||
color = float4(grayscale, sample.a);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user