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 super::{GraphicsPipelineLoadFn, LoadableGraphicsPipeline};
#[derive(PartialEq, Eq)]
pub enum PipelineState {
NeedBuild,
Loaded,
}
pub type GraphicsPipelineLoadFn =
fn(&Arc<Device>, Format, Format) -> Result<Arc<GraphicsPipeline>, Box<dyn Error>>;
pub struct PipelineLoader {
device: Arc<Device>,
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.
pipelines: Vec<Arc<RwLock<Option<Arc<GraphicsPipeline>>>>>,
pipelines_state: Vec<Arc<RwLock<PipelineState>>>,
pipelines_name: Vec<&'static str>,
}
impl PipelineLoader {
@ -43,20 +43,21 @@ impl PipelineLoader {
depth_image_format,
pipelines: Vec::new(),
pipelines_load_fn: Vec::new(),
pipelines_name: Vec::new(),
pipelines_id: Vec::new(),
pipelines_state: Vec::new(),
pipelines_index: HashMap::new(),
}
}
pub fn register<T: 'static>(
pub fn register<T: LoadableGraphicsPipeline + 'static>(
&mut self,
load_fn: GraphicsPipelineLoadFn,
) -> Result<(), Box<dyn Error>> {
let id = TypeId::of::<T>();
self.pipelines_index.insert(id, self.pipelines.len());
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
.push(Arc::new(RwLock::new(PipelineState::NeedBuild)));
self.pipelines.push(Arc::new(RwLock::new(None)));
@ -65,7 +66,7 @@ impl PipelineLoader {
pub fn load_pipelines(&self) -> Result<(), Box<dyn Error>> {
let iter = self
.pipelines_id
.pipelines_name
.iter()
.zip(self.pipelines.iter())
.zip(self.pipelines_load_fn.iter())
@ -75,7 +76,7 @@ impl PipelineLoader {
*state == PipelineState::NeedBuild
});
for (((id, pipeline), load_fn), state) in iter {
for (((name, pipeline), load_fn), state) in iter {
let new_pipeline = load_fn(
&self.device,
self.swapchain_image_format,
@ -85,7 +86,7 @@ impl PipelineLoader {
*pipeline = Some(new_pipeline);
let mut state = state.write().unwrap();
*state = PipelineState::Loaded;
tracing::trace!("Pipeline {id:?} loaded");
tracing::trace!("Pipeline {name} loaded");
}
Ok(())
}

View file

@ -1,2 +1,18 @@
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,
AsRenderableMeshInstance, mvp::Mvp, transform::TransformRaw, vertex::Vertex3D,
},
resources::texture::Texture,
resources::{pipeline::LoadableGraphicsPipeline, texture::Texture},
};
pub struct SimplePipeline;
impl SimplePipeline {
pub fn new(
impl LoadableGraphicsPipeline for SimplePipeline {
fn load(
device: &Arc<Device>,
swapchain_format: Format,
depth_format: Format,
@ -114,6 +114,10 @@ impl SimplePipeline {
Ok(pipeline)
}
fn pipeline_name() -> &'static str {
"SimplePipeline"
}
}
impl AsRecordable for SimplePipeline {

View file

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