From 5bee967dcb76c7cc1c7f969118a21c507d127cae Mon Sep 17 00:00:00 2001 From: bogdanov Date: Sat, 1 Feb 2025 01:31:28 +0000 Subject: [PATCH] graphics!: separate texture binding from the `Bindings` struct --- examples/blobs.rs | 3 +- examples/instancing.rs | 3 +- examples/msaa_render_texture.rs | 11 +++---- examples/offscreen.rs | 11 +++---- examples/post_processing.rs | 13 +++++---- examples/quad.rs | 6 ++-- examples/triangle.rs | 3 +- examples/triangle_color4b.rs | 3 +- src/graphics.rs | 25 ++++++---------- src/graphics/gl.rs | 51 ++++++++++++++++----------------- src/graphics/metal.rs | 18 ++++++------ 11 files changed, 70 insertions(+), 77 deletions(-) diff --git a/examples/blobs.rs b/examples/blobs.rs index f29ea4e6..fb8c38ba 100644 --- a/examples/blobs.rs +++ b/examples/blobs.rs @@ -47,8 +47,7 @@ impl Stage { let bindings = Bindings { vertex_buffers: vec![vertex_buffer], - index_buffer: index_buffer, - images: vec![], + index_buffer, }; let shader = ctx diff --git a/examples/instancing.rs b/examples/instancing.rs index 4084aad3..5f4d7a39 100644 --- a/examples/instancing.rs +++ b/examples/instancing.rs @@ -58,8 +58,7 @@ impl Stage { let bindings = Bindings { vertex_buffers: vec![geometry_vertex_buffer, positions_vertex_buffer], - index_buffer: index_buffer, - images: vec![], + index_buffer, }; let shader = ctx diff --git a/examples/msaa_render_texture.rs b/examples/msaa_render_texture.rs index d81ba16a..0053acdd 100644 --- a/examples/msaa_render_texture.rs +++ b/examples/msaa_render_texture.rs @@ -8,6 +8,7 @@ struct Stage { offscreen_pipeline: Pipeline, offscreen_bind: Bindings, offscreen_pass: RenderPass, + color_resolve_img: TextureId, rx: f32, ry: f32, ctx: Box, @@ -104,9 +105,8 @@ impl Stage { ); let offscreen_bind = Bindings { - vertex_buffers: vec![vertex_buffer.clone()], - index_buffer: index_buffer.clone(), - images: vec![], + vertex_buffers: vec![vertex_buffer], + index_buffer, }; let display_bind = { @@ -130,8 +130,7 @@ impl Stage { ); Bindings { vertex_buffers: vec![vertex_buffer], - index_buffer: index_buffer, - images: vec![color_resolve_img], + index_buffer, } }; @@ -195,6 +194,7 @@ impl Stage { offscreen_pipeline, offscreen_bind, offscreen_pass, + color_resolve_img, rx: 0., ry: 0., ctx, @@ -240,6 +240,7 @@ impl EventHandler for Stage { .begin_default_pass(PassAction::clear_color(0.0, 0., 0.45, 1.)); self.ctx.apply_pipeline(&self.display_pipeline); self.ctx.apply_bindings(&self.display_bind); + self.ctx.apply_image(&self.color_resolve_img); self.ctx.apply_uniforms(UniformsSource::table(&vs_params)); self.ctx.draw(0, 6, 1); self.ctx.end_render_pass(); diff --git a/examples/offscreen.rs b/examples/offscreen.rs index f8c32957..d13c4fb7 100644 --- a/examples/offscreen.rs +++ b/examples/offscreen.rs @@ -8,6 +8,7 @@ struct Stage { offscreen_pipeline: Pipeline, offscreen_bind: Bindings, offscreen_pass: RenderPass, + color_img: TextureId, rx: f32, ry: f32, ctx: Box, @@ -89,15 +90,13 @@ impl Stage { ); let offscreen_bind = Bindings { - vertex_buffers: vec![vertex_buffer.clone()], - index_buffer: index_buffer.clone(), - images: vec![], + vertex_buffers: vec![vertex_buffer], + index_buffer, }; let display_bind = Bindings { vertex_buffers: vec![vertex_buffer], - index_buffer: index_buffer, - images: vec![color_img], + index_buffer, }; let source = match ctx.info().backend { @@ -160,6 +159,7 @@ impl Stage { offscreen_pipeline, offscreen_bind, offscreen_pass, + color_img, rx: 0., ry: 0., ctx, @@ -205,6 +205,7 @@ impl EventHandler for Stage { .begin_default_pass(PassAction::clear_color(0.0, 0., 0.45, 1.)); self.ctx.apply_pipeline(&self.display_pipeline); self.ctx.apply_bindings(&self.display_bind); + self.ctx.apply_image(&self.color_img); self.ctx.apply_uniforms(UniformsSource::table(&vs_params)); self.ctx.draw(0, 36, 1); self.ctx.end_render_pass(); diff --git a/examples/post_processing.rs b/examples/post_processing.rs index 3762d229..3788df9d 100644 --- a/examples/post_processing.rs +++ b/examples/post_processing.rs @@ -8,6 +8,7 @@ struct Stage { offscreen_pipeline: Pipeline, offscreen_bind: Bindings, offscreen_pass: RenderPass, + color_img: TextureId, rx: f32, ry: f32, @@ -90,9 +91,8 @@ impl Stage { ); let offscreen_bind = Bindings { - vertex_buffers: vec![vertex_buffer.clone()], - index_buffer: index_buffer.clone(), - images: vec![], + vertex_buffers: vec![vertex_buffer], + index_buffer, }; #[rustfmt::skip] @@ -120,8 +120,7 @@ impl Stage { let post_processing_bind = Bindings { vertex_buffers: vec![vertex_buffer], - index_buffer: index_buffer, - images: vec![color_img], + index_buffer, }; let default_shader = ctx @@ -180,6 +179,7 @@ impl Stage { offscreen_pipeline, offscreen_bind, offscreen_pass, + color_img, rx: 0., ry: 0., ctx, @@ -208,7 +208,7 @@ impl EventHandler for Stage { self.ctx.delete_render_pass(self.offscreen_pass); self.offscreen_pass = offscreen_pass; - self.post_processing_bind.images[0] = color_img; + self.color_img = color_img; } fn draw(&mut self) { @@ -247,6 +247,7 @@ impl EventHandler for Stage { self.ctx.begin_default_pass(PassAction::Nothing); self.ctx.apply_pipeline(&self.post_processing_pipeline); self.ctx.apply_bindings(&self.post_processing_bind); + self.ctx.apply_image(&self.color_img); self.ctx .apply_uniforms(UniformsSource::table(&post_processing_shader::Uniforms { resolution: glam::vec2(w, h), diff --git a/examples/quad.rs b/examples/quad.rs index 821acb11..e8fcaa7b 100644 --- a/examples/quad.rs +++ b/examples/quad.rs @@ -16,6 +16,7 @@ struct Stage { pipeline: Pipeline, bindings: Bindings, + texture: TextureId, } impl Stage { @@ -53,8 +54,7 @@ impl Stage { let bindings = Bindings { vertex_buffers: vec![vertex_buffer], - index_buffer: index_buffer, - images: vec![texture], + index_buffer, }; let shader = ctx @@ -85,6 +85,7 @@ impl Stage { Stage { pipeline, bindings, + texture, ctx, } } @@ -100,6 +101,7 @@ impl EventHandler for Stage { self.ctx.apply_pipeline(&self.pipeline); self.ctx.apply_bindings(&self.bindings); + self.ctx.apply_image(&self.texture); for i in 0..10 { let t = t + i as f64 * 0.3; diff --git a/examples/triangle.rs b/examples/triangle.rs index 383dbf48..b038929b 100644 --- a/examples/triangle.rs +++ b/examples/triangle.rs @@ -37,8 +37,7 @@ impl Stage { let bindings = Bindings { vertex_buffers: vec![vertex_buffer], - index_buffer: index_buffer, - images: vec![], + index_buffer, }; let shader = ctx diff --git a/examples/triangle_color4b.rs b/examples/triangle_color4b.rs index e01a3c36..0589885e 100644 --- a/examples/triangle_color4b.rs +++ b/examples/triangle_color4b.rs @@ -37,8 +37,7 @@ impl Stage { let bindings = Bindings { vertex_buffers: vec![vertex_buffer], - index_buffer: index_buffer, - images: vec![], + index_buffer, }; let shader = ctx diff --git a/src/graphics.rs b/src/graphics.rs index dde3edb6..1fca73f3 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -767,7 +767,7 @@ impl Default for PipelineParams { } } -/// Geometry bindings +/// Geometry buffers bindings #[derive(Clone, Debug)] pub struct Bindings { /// Vertex buffers. Data contained in the buffer must match layout @@ -781,9 +781,6 @@ pub struct Bindings { /// from a vertex buffer, with each subsequent 3 indices forming a /// triangle. pub index_buffer: BufferId, - /// Textures to be used with when drawing the geometry in the fragment - /// shader. - pub images: Vec, } #[derive(Clone, Copy, Debug, PartialEq)] @@ -1322,19 +1319,15 @@ pub trait RenderingBackend { /// Should be applied after begin_pass. fn apply_scissor_rect(&mut self, x: i32, y: i32, w: i32, h: i32); - fn apply_bindings_from_slice( - &mut self, - vertex_buffers: &[BufferId], - index_buffer: BufferId, - textures: &[TextureId], - ); - + fn apply_bindings_from_slice(&mut self, vertex_buffers: &[BufferId], index_buffer: BufferId); fn apply_bindings(&mut self, bindings: &Bindings) { - self.apply_bindings_from_slice( - &bindings.vertex_buffers, - bindings.index_buffer, - &bindings.images, - ); + self.apply_bindings_from_slice(&bindings.vertex_buffers, bindings.index_buffer); + } + + fn apply_images(&mut self, images: &[TextureId]); + /// Same as [RenderingBackend::apply_images], but applies only one image + fn apply_image(&mut self, image: &TextureId) { + self.apply_images(std::slice::from_ref(image)); } fn apply_uniforms(&mut self, uniforms: UniformsSource) { diff --git a/src/graphics/gl.rs b/src/graphics/gl.rs index 74be9fd9..2bef37b4 100644 --- a/src/graphics/gl.rs +++ b/src/graphics/gl.rs @@ -1435,33 +1435,7 @@ impl RenderingBackend for GlContext { } } - fn apply_bindings_from_slice( - &mut self, - vertex_buffers: &[BufferId], - index_buffer: BufferId, - textures: &[TextureId], - ) { - let pip = &self.pipelines[self.cache.cur_pipeline.unwrap().0]; - let shader = &self.shaders[pip.shader.0]; - - for (n, shader_image) in shader.images.iter().enumerate() { - let bindings_image = textures - .get(n) - .unwrap_or_else(|| panic!("Image count in bindings and shader did not match!")); - if let Some(gl_loc) = shader_image.gl_loc { - let texture = self.textures.get(*bindings_image); - let raw = match texture.raw { - TextureOrRenderbuffer::Texture(id) => id, - TextureOrRenderbuffer::Renderbuffer(id) => id, - }; - unsafe { - self.cache - .bind_texture(n, texture.params.kind.into(), raw); - glUniform1i(gl_loc, n as i32); - } - } - } - + fn apply_bindings_from_slice(&mut self, vertex_buffers: &[BufferId], index_buffer: BufferId) { self.cache.bind_buffer( GL_ELEMENT_ARRAY_BUFFER, self.buffers[index_buffer.0].gl_buf, @@ -1535,6 +1509,29 @@ impl RenderingBackend for GlContext { } } + fn apply_images(&mut self, images: &[TextureId]) { + let pip = &self.pipelines[self.cache.cur_pipeline.unwrap().0]; + let shader = &self.shaders[pip.shader.0]; + + for (n, shader_image) in shader.images.iter().enumerate() { + let Some(bindings_image) = images.get(n) else { + panic!("Image count in bindings and shader did not match!"); + }; + + if let Some(gl_loc) = shader_image.gl_loc { + let texture = self.textures.get(*bindings_image); + let raw = match texture.raw { + TextureOrRenderbuffer::Texture(id) => id, + TextureOrRenderbuffer::Renderbuffer(id) => id, + }; + unsafe { + self.cache.bind_texture(n, texture.params.kind.into(), raw); + glUniform1i(gl_loc, n as i32); + } + } + } + } + fn apply_uniforms_from_bytes(&mut self, uniform_ptr: *const u8, size: usize) { let pip = &self.pipelines[self.cache.cur_pipeline.unwrap().0]; let shader = &self.shaders[pip.shader.0]; diff --git a/src/graphics/metal.rs b/src/graphics/metal.rs index 7ac8870f..91d50ffd 100644 --- a/src/graphics/metal.rs +++ b/src/graphics/metal.rs @@ -1057,12 +1057,7 @@ impl RenderingBackend for MetalContext { } } - fn apply_bindings_from_slice( - &mut self, - vertex_buffers: &[BufferId], - index_buffer: BufferId, - textures: &[TextureId], - ) { + fn apply_bindings_from_slice(&mut self, vertex_buffers: &[BufferId], index_buffer: BufferId) { assert!( self.render_encoder.is_some(), "apply_bindings before begin_pass" @@ -1078,13 +1073,20 @@ impl RenderingBackend for MetalContext { atIndex:(index + 1) as u64]; buffer.next_value = buffer.value + 1; } + let index_buffer = &mut self.buffers[index_buffer.0]; self.index_buffer = Some(index_buffer.raw[index_buffer.value]); index_buffer.next_value = index_buffer.value + 1; + } + } + + fn apply_images(&mut self, images: &[TextureId]) { + unsafe { + let render_encoder = self.render_encoder.unwrap(); - let img_count = textures.len(); + let img_count = images.len(); if img_count > 0 { - for (n, img) in textures.iter().enumerate() { + for (n, img) in images.iter().enumerate() { let Texture { sampler, texture, .. } = self.textures.get(*img);