1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 04:40:03 -04:00

Fix wgpu padding (#8448)

The Egui web example was throwing an error in WGPU. In this case, the
error was
```
panicked at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wgpu-30.0.0/src/backend/wgpu_core.rs:1414:26: wgpu error: Validation Error Caused by: In Device::create_render_pipeline, label = ‘egui_pipeline’ In the provided shader, the type given for group 1 binding 2 has a size of 4. Since the device does not support DownlevelFlags::BUFFER_BINDINGS_NOT_16_BYTE_ALIGNED`, the type must have a size that is a multiple of 16 bytes
```

One reference I used was the following Pull Request:
<https://github.com/viridia/quill/pull/14>

The biggest change I made was in `egui-wgpu` to
`r_tex_nearest_filtering`

Shader (`egui.wgsl`)
```wgsl
// Old 
@group(1) @binding(2) var<uniform> r_tex_nearest_filtering: u32;

// New
@group(1) @binding(2) var<uniform> r_tex_nearest_filtering: vec4<u32>;
```

And with the corresponding changes in `renderer.rs`, I ran it locally
and it worked perfectly in Firefox 149 and Chromium 151 (Both fail when
attempting to access https://www.egui.rs/#demo, returning the error
described above)

* Closes <https://github.com/emilk/egui/issues/8446>
* Fixes <https://github.com/emilk/egui/issues/8446>
* [X] I have followed the instructions in the PR template

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Juanperias
2026-08-26 02:09:32 -04:00
committed by GitHub
parent 35b069585d
commit caea233a47
2 changed files with 9 additions and 5 deletions

View File

@@ -98,6 +98,7 @@ fn vs_main(
@group(1) @binding(0) var r_tex_color: texture_2d<f32>;
@group(1) @binding(1) var r_tex_sampler: sampler;
/// Set in bit 0 of `r_tex_flags` if the sampler uses nearest filtering.
///
/// Must match `TEX_FLAG_NEAREST` in `renderer.rs`.
@@ -114,11 +115,11 @@ const WRAP_MODE_MIRRORED_REPEAT: u32 = 2u;
///
/// Bit 0: `TEX_FLAG_NEAREST`.
/// Bits 1+: one of the `WRAP_MODE_*` constants.
@group(1) @binding(2) var<uniform> r_tex_flags: u32;
@group(1) @binding(2) var<uniform> r_tex_flags: vec4<u32>;
/// Map a texel coordinate to a valid texel according to the texture's wrap mode.
fn wrap_texel_coord(coord: vec2<i32>, texture_size: vec2<i32>) -> vec2<i32> {
let wrap_mode = r_tex_flags >> 1u;
let wrap_mode = r_tex_flags[0] >> 1u;
if wrap_mode == WRAP_MODE_REPEAT {
return ((coord % texture_size) + texture_size) % texture_size;
} else if wrap_mode == WRAP_MODE_MIRRORED_REPEAT {
@@ -131,6 +132,7 @@ fn wrap_texel_coord(coord: vec2<i32>, texture_size: vec2<i32>) -> vec2<i32> {
}
}
fn sample_texture(in: VertexOutput) -> vec4<f32> {
if r_locals.predictable_texture_filtering == 0 {
// Hardware filtering: fast, but varies across GPUs and drivers.
@@ -139,7 +141,7 @@ fn sample_texture(in: VertexOutput) -> vec4<f32> {
let texture_size = vec2<i32>(textureDimensions(r_tex_color, 0));
let texture_size_f = vec2<f32>(texture_size);
if (r_tex_flags & TEX_FLAG_NEAREST) != 0u {
if (r_tex_flags[0] & TEX_FLAG_NEAREST) != 0u {
// Nearest filtering: load the texel under the sample position.
let texel = wrap_texel_coord(vec2<i32>(floor(in.tex_coord * texture_size_f)), texture_size);
return textureLoad(r_tex_color, texel, 0);

View File

@@ -357,7 +357,9 @@ impl Renderer {
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Buffer {
has_dynamic_offset: false,
min_binding_size: NonZeroU64::new(core::mem::size_of::<u32>() as _),
min_binding_size: NonZeroU64::new(
(core::mem::size_of::<u32>() * 4) as _,
),
ty: wgpu::BufferBindingType::Uniform,
},
count: None,
@@ -370,7 +372,7 @@ impl Renderer {
let flag = flag as u32;
device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some(&format!("egui_texture_flags_{flag}")),
contents: bytemuck::bytes_of(&flag),
contents: bytemuck::bytes_of(&[flag, 0, 0, 0]),
usage: wgpu::BufferUsages::UNIFORM,
})
});