Search code examples
rustglslwebassemblywebgpuwgpu-rs

Problem with uniform buffer on rust's wgpu only for web target


I made this project as a way to learn rust and graphics programming. The program is based on this great tutorial and currently works as a native desktop application (on Windows atleast).

However, my main goal is to create a web app to showcase my project. I am having great difficulty doing so, as I have encountered an error I have no idea how to fix (GL_INVALID_OPERATION: It is undefined behaviour to use a uniform buffer that is too small. on the browser console). By the looks of it, it may be a bug of the underlying library wgpu, however, since I have no experience with graphics programming I cannot be sure it's not a silly mistake on my part.

The error makes it clear the problem has to do with the uniform buffer. However this buffer has correct padding and looks to be correctly implemented as the program works when not targeting the web (plain cargo build --release).

I opened a similar discussion on the wgpu library GitHub to which I recieved helpful replies but couldn't solve my problem. I found some related question but it wasn't very useful to me.

My uniform buffer in the .wgsl file:

struct Uniform {
   domain: mat2x2<f32>, 
   mouse: vec2<f32>,
   c: vec2<f32>,        
   time: f32,          
   mandelbrot: i32,   
   padding: vec2<f32>,
}
@group(0) @binding(0) 
var<uniform> my_uniform: Uniform;

The uniform buffer on rust:

#[repr(C)]
#[derive(Copy, Clone, Debug, bytemuck::Zeroable, bytemuck::Pod)]
pub struct Uniform {
    pub domain: [[f32; 2]; 2],
    pub mouse: [f32; 2],
    pub c: [f32; 2],
    pub time: f32,
    pub mandelbrot: i32,
    pub _padding: [f32; 2],
}

For more details please check the repository, the link provided is fixed to the current commit where this can be reproduced.

Thanks.


Solution

  • The problem was solved by https://github.com/gfx-rs/wgpu/discussions/3027#discussioncomment-3656241. It seems to be a bug on wgpu.

    Using vec4<f32> instead of mat2x2<f32> fixed the issue. It will probably be corrected in the future, as my implementation should also work.