Use trait instead to get load_fn and add name for pipeline

This commit is contained in:
Florian RICHER 2025-06-09 20:53:22 +02:00
parent 6099a3e27f
commit 2300c25603
Signed by: florian.richer
GPG key ID: C73D37CBED7BFC77
4 changed files with 35 additions and 14 deletions

View file

@ -7,15 +7,14 @@ use std::{
use vulkano::{device::Device, format::Format, pipeline::GraphicsPipeline}; use vulkano::{device::Device, format::Format, pipeline::GraphicsPipeline};
use super::{GraphicsPipelineLoadFn, LoadableGraphicsPipeline};
#[derive(PartialEq, Eq)] #[derive(PartialEq, Eq)]
pub enum PipelineState { pub enum PipelineState {
NeedBuild, NeedBuild,
Loaded, Loaded,
} }
pub type GraphicsPipelineLoadFn =
fn(&Arc<Device>, Format, Format) -> Result<Arc<GraphicsPipeline>, Box<dyn Error>>;
pub struct PipelineLoader { pub struct PipelineLoader {
device: Arc<Device>, device: Arc<Device>,
swapchain_image_format: Format, swapchain_image_format: Format,
@ -29,6 +28,7 @@ pub struct PipelineLoader {
// But only the pipeline loader is allowed to load a pipeline when it's needed. // But only the pipeline loader is allowed to load a pipeline when it's needed.
pipelines: Vec<Arc<RwLock<Option<Arc<GraphicsPipeline>>>>>, pipelines: Vec<Arc<RwLock<Option<Arc<GraphicsPipeline>>>>>,
pipelines_state: Vec<Arc<RwLock<PipelineState>>>, pipelines_state: Vec<Arc<RwLock<PipelineState>>>,
pipelines_name: Vec<&'static str>,
} }
impl PipelineLoader { impl PipelineLoader {
@ -43,20 +43,21 @@ impl PipelineLoader {
depth_image_format, depth_image_format,
pipelines: Vec::new(), pipelines: Vec::new(),
pipelines_load_fn: Vec::new(), pipelines_load_fn: Vec::new(),
pipelines_name: Vec::new(),
pipelines_id: Vec::new(), pipelines_id: Vec::new(),
pipelines_state: Vec::new(), pipelines_state: Vec::new(),
pipelines_index: HashMap::new(), pipelines_index: HashMap::new(),
} }
} }
pub fn register<T: 'static>( pub fn register<T: LoadableGraphicsPipeline + 'static>(
&mut self, &mut self,
load_fn: GraphicsPipelineLoadFn,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
let id = TypeId::of::<T>(); let id = TypeId::of::<T>();
self.pipelines_index.insert(id, self.pipelines.len()); self.pipelines_index.insert(id, self.pipelines.len());
self.pipelines_id.push(id); self.pipelines_id.push(id);
self.pipelines_load_fn.push(load_fn); self.pipelines_load_fn.push(T::load);
self.pipelines_name.push(T::pipeline_name());
self.pipelines_state self.pipelines_state
.push(Arc::new(RwLock::new(PipelineState::NeedBuild))); .push(Arc::new(RwLock::new(PipelineState::NeedBuild)));
self.pipelines.push(Arc::new(RwLock::new(None))); self.pipelines.push(Arc::new(RwLock::new(None)));
@ -65,7 +66,7 @@ impl PipelineLoader {
pub fn load_pipelines(&self) -> Result<(), Box<dyn Error>> { pub fn load_pipelines(&self) -> Result<(), Box<dyn Error>> {
let iter = self let iter = self
.pipelines_id .pipelines_name
.iter() .iter()
.zip(self.pipelines.iter()) .zip(self.pipelines.iter())
.zip(self.pipelines_load_fn.iter()) .zip(self.pipelines_load_fn.iter())
@ -75,7 +76,7 @@ impl PipelineLoader {
*state == PipelineState::NeedBuild *state == PipelineState::NeedBuild
}); });
for (((id, pipeline), load_fn), state) in iter { for (((name, pipeline), load_fn), state) in iter {
let new_pipeline = load_fn( let new_pipeline = load_fn(
&self.device, &self.device,
self.swapchain_image_format, self.swapchain_image_format,
@ -85,7 +86,7 @@ impl PipelineLoader {
*pipeline = Some(new_pipeline); *pipeline = Some(new_pipeline);
let mut state = state.write().unwrap(); let mut state = state.write().unwrap();
*state = PipelineState::Loaded; *state = PipelineState::Loaded;
tracing::trace!("Pipeline {id:?} loaded"); tracing::trace!("Pipeline {name} loaded");
} }
Ok(()) Ok(())
} }

View file

@ -1,2 +1,18 @@
mod loader; mod loader;
pub use loader::{GraphicsPipelineLoadFn, PipelineLoader}; use std::{error::Error, sync::Arc};
pub use loader::PipelineLoader;
use vulkano::{device::Device, format::Format, pipeline::GraphicsPipeline};
type GraphicsPipelineLoadFn =
fn(&Arc<Device>, Format, Format) -> Result<Arc<GraphicsPipeline>, Box<dyn Error>>;
pub trait LoadableGraphicsPipeline {
fn load(
device: &Arc<Device>,
swapchain_image_format: Format,
depth_image_format: Format,
) -> Result<Arc<GraphicsPipeline>, Box<dyn Error>>;
fn pipeline_name() -> &'static str;
}

View file

@ -33,13 +33,13 @@ use crate::core::render::{
AsDescriptorSet, AsDescriptorSetLayoutBindings, AsRecordable, AsRenderableMesh, AsDescriptorSet, AsDescriptorSetLayoutBindings, AsRecordable, AsRenderableMesh,
AsRenderableMeshInstance, mvp::Mvp, transform::TransformRaw, vertex::Vertex3D, AsRenderableMeshInstance, mvp::Mvp, transform::TransformRaw, vertex::Vertex3D,
}, },
resources::texture::Texture, resources::{pipeline::LoadableGraphicsPipeline, texture::Texture},
}; };
pub struct SimplePipeline; pub struct SimplePipeline;
impl SimplePipeline { impl LoadableGraphicsPipeline for SimplePipeline {
pub fn new( fn load(
device: &Arc<Device>, device: &Arc<Device>,
swapchain_format: Format, swapchain_format: Format,
depth_format: Format, depth_format: Format,
@ -114,6 +114,10 @@ impl SimplePipeline {
Ok(pipeline) Ok(pipeline)
} }
fn pipeline_name() -> &'static str {
"SimplePipeline"
}
} }
impl AsRecordable for SimplePipeline { impl AsRecordable for SimplePipeline {

View file

@ -61,7 +61,7 @@ impl Scene for MainScene {
swapchain_image_view.format(), swapchain_image_view.format(),
depth_image_view.format(), depth_image_view.format(),
); );
pipeline_loader.register::<SimplePipeline>(SimplePipeline::new)?; pipeline_loader.register::<SimplePipeline>()?;
pipeline_loader.load_pipelines()?; pipeline_loader.load_pipelines()?;
let mut texture_loader = TextureLoader::new(app_context); let mut texture_loader = TextureLoader::new(app_context);