From 0174aeb60e5daba3140871ee4af007f3703e385b Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Mon, 9 Jun 2025 16:12:21 +0200 Subject: [PATCH] Reduce Generics in pipeline rendering --- src/core/render/primitives/command.rs | 6 ++- src/core/render/primitives/descriptor_set.rs | 22 +++++++++ src/core/render/primitives/mod.rs | 23 +-------- src/core/render/primitives/mvp.rs | 12 +++-- src/core/render/resources/texture/loader.rs | 6 +-- src/core/render/resources/texture/texture.rs | 12 +++-- src/game/assets/pipelines/simple.rs | 49 +++++++++----------- src/game/scenes/main_scene.rs | 38 +++++++++------ 8 files changed, 92 insertions(+), 76 deletions(-) create mode 100644 src/core/render/primitives/descriptor_set.rs diff --git a/src/core/render/primitives/command.rs b/src/core/render/primitives/command.rs index a71b9d2..6fdca2c 100644 --- a/src/core/render/primitives/command.rs +++ b/src/core/render/primitives/command.rs @@ -7,7 +7,9 @@ use vulkano::{ pipeline::GraphicsPipeline, }; -pub trait AsRecordable +use super::AsDescriptorSet; + +pub trait AsRecordable where MI: Into + Clone, { @@ -17,7 +19,7 @@ where pipeline: &Arc, mesh: &impl AsRenderableMesh, instances: &impl AsRenderableMeshInstance, - extra_data: &T, + descriptor_sets: Vec>, ) -> Result<(), Box>; fn record_draw_commands( diff --git a/src/core/render/primitives/descriptor_set.rs b/src/core/render/primitives/descriptor_set.rs new file mode 100644 index 0000000..964d5e9 --- /dev/null +++ b/src/core/render/primitives/descriptor_set.rs @@ -0,0 +1,22 @@ +use std::{collections::BTreeMap, sync::Arc}; + +use vulkano::{ + Validated, VulkanError, + descriptor_set::{ + DescriptorSet, + allocator::StandardDescriptorSetAllocator, + layout::{DescriptorSetLayout, DescriptorSetLayoutBinding}, + }, +}; + +pub trait AsDescriptorSetLayoutBindings { + fn as_descriptor_set_layout_bindings() -> BTreeMap; +} + +pub trait AsDescriptorSet { + fn as_descriptor_set( + &self, + descriptor_set_allocator: &Arc, + layout: &Arc, + ) -> Result, Validated>; +} diff --git a/src/core/render/primitives/mod.rs b/src/core/render/primitives/mod.rs index 75743cd..26810d6 100644 --- a/src/core/render/primitives/mod.rs +++ b/src/core/render/primitives/mod.rs @@ -1,16 +1,6 @@ -use std::{collections::BTreeMap, sync::Arc}; - -use vulkano::{ - Validated, VulkanError, - descriptor_set::{ - DescriptorSet, - allocator::StandardDescriptorSetAllocator, - layout::{DescriptorSetLayout, DescriptorSetLayoutBinding}, - }, -}; - mod buffer; mod command; +mod descriptor_set; pub mod camera; pub mod mvp; @@ -19,13 +9,4 @@ pub mod transform; pub mod vertex; pub use buffer::{AsBindableBuffer, AsIndexBuffer, AsUniformBuffer, AsVertexBuffer}; pub use command::{AsRecordable, AsRenderableMesh, AsRenderableMeshInstance}; - -pub trait AsBindableDescriptorSet { - fn as_descriptor_set_layout_bindings() -> BTreeMap; - - fn as_descriptor_set( - descriptor_set_allocator: &Arc, - layout: &Arc, - data: &T, - ) -> Result, Validated>; -} +pub use descriptor_set::{AsDescriptorSet, AsDescriptorSetLayoutBindings}; diff --git a/src/core/render/primitives/mvp.rs b/src/core/render/primitives/mvp.rs index af5db16..09c8673 100644 --- a/src/core/render/primitives/mvp.rs +++ b/src/core/render/primitives/mvp.rs @@ -13,7 +13,9 @@ use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, Standar use vulkano::shader::ShaderStages; use vulkano::{Validated, VulkanError}; -use crate::core::render::primitives::{AsBindableBuffer, AsBindableDescriptorSet, AsUniformBuffer}; +use crate::core::render::primitives::{AsBindableBuffer, AsUniformBuffer}; + +use super::{AsDescriptorSet, AsDescriptorSetLayoutBindings}; #[derive(BufferContents, Clone, Copy)] #[repr(C)] @@ -57,7 +59,7 @@ impl AsBindableBuffer for Mvp { impl AsUniformBuffer for Mvp {} -impl AsBindableDescriptorSet> for Mvp { +impl AsDescriptorSetLayoutBindings for Mvp { fn as_descriptor_set_layout_bindings() -> BTreeMap { BTreeMap::::from_iter([( 0, @@ -67,16 +69,18 @@ impl AsBindableDescriptorSet> for Mvp { }, )]) } +} +impl AsDescriptorSet for Subbuffer<[Mvp]> { fn as_descriptor_set( + &self, descriptor_set_allocator: &Arc, layout: &Arc, - data: &Subbuffer<[Mvp]>, ) -> Result, Validated> { DescriptorSet::new( descriptor_set_allocator.clone(), layout.clone(), - [WriteDescriptorSet::buffer(0, data.clone())], + [WriteDescriptorSet::buffer(0, self.clone())], [], ) } diff --git a/src/core/render/resources/texture/loader.rs b/src/core/render/resources/texture/loader.rs index 8d26862..d440291 100644 --- a/src/core/render/resources/texture/loader.rs +++ b/src/core/render/resources/texture/loader.rs @@ -27,7 +27,7 @@ pub struct TextureLoadInfo { } pub struct TextureLoader { - loaded_textures: HashMap, + loaded_textures: HashMap>, pending_textures: HashMap, device: Arc, command_buffer_allocator: Arc, @@ -102,7 +102,7 @@ impl TextureLoader { )?, }; - loading_textures.insert(name.clone(), texture); + loading_textures.insert(name.clone(), Arc::new(texture)); tracing::trace!("Loaded texture: {}", name); } @@ -113,7 +113,7 @@ impl TextureLoader { Ok(()) } - pub fn get_texture(&self, name: &str) -> Option<&Texture> { + pub fn get_texture(&self, name: &str) -> Option<&Arc> { self.loaded_textures.get(name) } diff --git a/src/core/render/resources/texture/texture.rs b/src/core/render/resources/texture/texture.rs index 3147d26..8eaf140 100644 --- a/src/core/render/resources/texture/texture.rs +++ b/src/core/render/resources/texture/texture.rs @@ -17,7 +17,7 @@ use vulkano::{ shader::ShaderStages, }; -use crate::core::render::primitives::AsBindableDescriptorSet; +use crate::core::render::primitives::{AsDescriptorSet, AsDescriptorSetLayoutBindings}; use super::TextureLoadInfo; @@ -112,7 +112,7 @@ impl Texture { } } -impl AsBindableDescriptorSet for Texture { +impl AsDescriptorSetLayoutBindings for Texture { fn as_descriptor_set_layout_bindings() -> BTreeMap { BTreeMap::::from_iter([ ( @@ -131,18 +131,20 @@ impl AsBindableDescriptorSet for Texture { ), ]) } +} +impl AsDescriptorSet for Texture { fn as_descriptor_set( + &self, descriptor_set_allocator: &Arc, layout: &Arc, - data: &Texture, ) -> Result, Validated> { DescriptorSet::new( descriptor_set_allocator.clone(), layout.clone(), [ - WriteDescriptorSet::sampler(0, data.sampler.clone()), - WriteDescriptorSet::image_view(1, data.texture.clone()), + WriteDescriptorSet::sampler(0, self.sampler.clone()), + WriteDescriptorSet::image_view(1, self.texture.clone()), ], [], ) diff --git a/src/game/assets/pipelines/simple.rs b/src/game/assets/pipelines/simple.rs index 3c87f9a..e003276 100644 --- a/src/game/assets/pipelines/simple.rs +++ b/src/game/assets/pipelines/simple.rs @@ -1,4 +1,4 @@ -use std::{error::Error, sync::Arc}; +use std::{collections::HashMap, error::Error, sync::Arc}; use vulkano::{ buffer::Subbuffer, @@ -28,17 +28,12 @@ use vulkano::{ use crate::core::render::{ primitives::{ - AsBindableDescriptorSet, AsRecordable, AsRenderableMesh, AsRenderableMeshInstance, - mvp::Mvp, transform::TransformRaw, vertex::Vertex3D, + AsDescriptorSet, AsDescriptorSetLayoutBindings, AsRecordable, AsRenderableMesh, + AsRenderableMeshInstance, mvp::Mvp, transform::TransformRaw, vertex::Vertex3D, }, resources::texture::Texture, }; -pub struct SimplePipelineRenderData<'a> { - pub mvp_uniform: &'a Subbuffer<[Mvp]>, - pub texture: &'a Texture, -} - pub struct SimplePipeline { pipeline: Arc, } @@ -125,33 +120,35 @@ impl SimplePipeline { } } -impl<'a> AsRecordable, Vertex3D, Subbuffer<[u32]>, TransformRaw> - for SimplePipeline -{ +impl AsRecordable, TransformRaw> for SimplePipeline { fn record_bind_commands( builder: &mut AutoCommandBufferBuilder, descriptor_set_allocator: &Arc, pipeline: &Arc, mesh: &impl AsRenderableMesh>, instances: &impl AsRenderableMeshInstance, - data: &SimplePipelineRenderData<'a>, + descriptor_sets: Vec>, ) -> Result<(), Box> { - let layouts = pipeline.layout().set_layouts(); - - let uniform_descriptor_set = - Mvp::as_descriptor_set(descriptor_set_allocator, &layouts[0], data.mvp_uniform)?; - - let texture_descriptor_set = - Texture::as_descriptor_set(descriptor_set_allocator, &layouts[1], data.texture)?; - builder.bind_pipeline_graphics(pipeline.clone())?; - builder.bind_descriptor_sets( - PipelineBindPoint::Graphics, - pipeline.layout().clone(), - 0, - vec![uniform_descriptor_set, texture_descriptor_set], - )?; + if !descriptor_sets.is_empty() { + let layouts = pipeline.layout().set_layouts(); + + let descriptor_sets = descriptor_sets + .iter() + .enumerate() + .map(|(layout_index, data)| { + data.as_descriptor_set(descriptor_set_allocator, &layouts[layout_index]) + }) + .collect::, _>>()?; + + builder.bind_descriptor_sets( + PipelineBindPoint::Graphics, + pipeline.layout().clone(), + 0, + descriptor_sets, + )?; + } builder.bind_vertex_buffers( 0, diff --git a/src/game/scenes/main_scene.rs b/src/game/scenes/main_scene.rs index 31126ea..e139e90 100644 --- a/src/game/scenes/main_scene.rs +++ b/src/game/scenes/main_scene.rs @@ -1,19 +1,19 @@ +use std::collections::HashMap; use std::error::Error; +use std::sync::Arc; use super::settings_scene::SettingsScene; use crate::core::app::DEPTH_IMAGE_ID; use crate::core::app::context::WindowContext; use crate::core::app::user_event::UserEvent; -use crate::core::render::primitives::AsRecordable; use crate::core::render::primitives::camera::Camera3D; use crate::core::render::primitives::transform::Transform; +use crate::core::render::primitives::{AsDescriptorSet, AsRecordable}; use crate::core::render::render_pass_manager::{RenderPassConfig, RenderPassManager}; use crate::core::render::resources::meshes::{ObjMesh, SquareMesh}; -use crate::core::render::resources::texture::{ - Texture, TextureLoadInfo, TextureLoader, TextureSourceKind, -}; +use crate::core::render::resources::texture::{TextureLoadInfo, TextureLoader, TextureSourceKind}; use crate::core::scene::Scene; -use crate::game::assets::pipelines::simple::{SimplePipeline, SimplePipelineRenderData}; +use crate::game::assets::pipelines::simple::SimplePipeline; use egui_winit_vulkano::egui; use glam::EulerRot; use glam::Quat; @@ -21,7 +21,7 @@ use glam::Vec3; use vulkano::format::Format; use vulkano::image::sampler::{Filter, SamplerAddressMode, SamplerCreateInfo}; use vulkano::{ - command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, PrimaryCommandBufferAbstract}, + command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage}, sync::GpuFuture, }; use winit::window::CursorGrabMode; @@ -250,7 +250,7 @@ impl Scene for MainScene { } // Create camera uniform using the actual camera - let camera_uniform = state.camera.create_buffer(&app_context.memory_allocator)?; + let camera_uniform = Arc::new(state.camera.create_buffer(&app_context.memory_allocator)?); let square_transform_uniform = Transform::create_buffer(&app_context.memory_allocator, &state.square_instances)?; let obj_transform_uniform = @@ -262,10 +262,14 @@ impl Scene for MainScene { state.simple_pipeline.pipeline(), &state.square, &square_transform_uniform, - &SimplePipelineRenderData { - mvp_uniform: &camera_uniform, - texture: &state.texture_loader.get_texture("wooden-crate").unwrap(), - }, + vec![ + camera_uniform.clone() as Arc, + state + .texture_loader + .get_texture("wooden-crate") + .unwrap() + .clone(), + ], )?; SimplePipeline::record_draw_commands( &mut builder, @@ -279,10 +283,14 @@ impl Scene for MainScene { state.simple_pipeline.pipeline(), &state.obj, &obj_transform_uniform, - &SimplePipelineRenderData { - mvp_uniform: &camera_uniform, - texture: &state.texture_loader.get_texture("cube-diffuse").unwrap(), - }, + vec![ + camera_uniform.clone() as Arc, + state + .texture_loader + .get_texture("cube-diffuse") + .unwrap() + .clone(), + ], )?; SimplePipeline::record_draw_commands(&mut builder, &state.obj, &obj_transform_uniform)?;