Where should I store things like bind groups and vertex buffers when using wgpu?
Ok so I'm writing a little simulation app using wgpu for GPU stuff. I've been learning wgpu from the Learn Wgpu series. It's been a great resource so far. But now I'm starting to deviate from the tutorial some for the specific app I'm trying to make. I've come to an architectural decision and want to know how you'd do it.
So when you're using wgpu, you have things called Pipelines, Bind Groups, Bind Group Layouts, Buffers, and a few other types that are needed to render a frame. In the tutorial they keep all that stuff around in a giant state struct. I'm trying to be more modular, so I've created a Renderer struct that only has the stuff that is necessary for any rendering. For reference, here is my Renderer:
pub struct Renderer {
pub surface: wgpu::Surface,
pub device: wgpu::Device,
pub queue: wgpu::Queue,
pub config: wgpu::SurfaceConfiguration,
pub size: winit::dpi::PhysicalSize<u32>,
}
Currently, I have a Simulation struct that keeps up with the specific set of pipeline, bind groups,
pub struct Simulation {
pub render_pipeline: wgpu::RenderPipeline,
pub vertex_buffer: wgpu::Buffer,
pub index_buffer: wgpu::Buffer,
pub num_indices: u32,
pub diffuse_texture: texture::Texture,
pub diffuse_bind_group: wgpu::BindGroup,
pub fatcam: FatCamera
}
Excuse the terrible naming of my FatCamera. It just contains camera related logic and its own bindgroup for the camera matrix stuff.
So when I call render() on my Renderer, I have to pass in a reference to the simulation. That all works fine but I'm not sure I really like having all that low level GPU related stuff in my supposedly higher level Simulation. And like with my FatCamera, it keeps up with its own bindgroup. That means that every new type of abstraction I build that interacts with the GPU will also need to keep up with GPU related resources.
Is there a cleaner way to structure all of this? Maybe using a resource registry of some sort? Or am I making too big of a deal of it?