diff options
Diffstat (limited to 'engine/src')
| -rw-r--r-- | engine/src/rendering/main_pipeline.rs | 203 |
1 files changed, 87 insertions, 116 deletions
diff --git a/engine/src/rendering/main_pipeline.rs b/engine/src/rendering/main_pipeline.rs index 7caf625..70f0682 100644 --- a/engine/src/rendering/main_pipeline.rs +++ b/engine/src/rendering/main_pipeline.rs @@ -1,5 +1,4 @@ use std::path::Path; -use std::sync::LazyLock; use ecs::actions::Actions; use ecs::component::local::Local; @@ -9,7 +8,7 @@ use ecs::query::term::{Traverse, TraverseUp}; use ecs::uid::Uid; use ecs::Component; -use crate::asset::{Assets, Label as AssetLabel}; +use crate::asset::Assets; use crate::camera::{Active as ActiveCamera, Camera}; use crate::color::Rgba; use crate::data_types::dimens::{Dimens, Dimens3}; @@ -17,7 +16,6 @@ use crate::draw_flags::{DrawFlags, NoDraw, PolygonModeConfig}; use crate::ecs::query::term::{With, Without}; use crate::ecs::sole::Single; use crate::ecs::Query; -use crate::error; use crate::image::Image; use crate::lighting::{ DirectionalLight, @@ -67,6 +65,7 @@ use crate::texture::{ Wrapping as TextureWrapping, }; use crate::transform::Transform; +use crate::util::OptionExt; use crate::vector::Vec3; use crate::windowing::window::Window; @@ -80,18 +79,6 @@ type RenderableEntity<'a> = ( Without<NoDraw>, ); -pub static SKY_BOX_SHADER_ASSET_LABEL: LazyLock<AssetLabel> = - LazyLock::new(|| AssetLabel { - path: Path::new("").into(), - name: Some("sky_box_shader".into()), - }); - -pub static MAIN_3D_SHADER_ASSET_LABEL: LazyLock<AssetLabel> = - LazyLock::new(|| AssetLabel { - path: Path::new("").into(), - name: Some("main_3d_shader".into()), - }); - struct SkyBoxIds { texture_object: ObjectId, @@ -99,9 +86,11 @@ struct SkyBoxIds } #[derive(Debug, Default, Component)] -pub struct MiscObjectIds +pub struct PipelineResources { white_1x1_tex_obj_id: Option<ObjectId>, + main_3d_shader: Option<(ObjectId, ShaderProgram)>, + sky_box_shader: Option<(ObjectId, ShaderProgram)>, } #[tracing::instrument(skip_all)] @@ -136,7 +125,7 @@ pub fn add_passes( mut render_passes: Single<RenderPasses>, mut object_store: Single<ObjectStore>, mut actions: Actions, - mut misc_object_ids: Local<MiscObjectIds>, + mut pipeline_resources: Local<PipelineResources>, ) -> Result<(), crate::Error> { let assets = assets.get_mut()?; @@ -174,24 +163,23 @@ pub fn add_passes( ); } - let shaders = - match get_or_create_shaders(assets, shader_context, object_store, render_pass) { - Ok(ShadersCreationStatus::Ready(ready_shaders)) => ready_shaders, - Ok(ShadersCreationStatus::ProcessingRequired) => return Ok(()), - Err(err) => { - tracing::error!("Failed to create shaders: {err}"); - return Ok(()); - } - }; - - let white_1x1_tex_obj_id = - *misc_object_ids.white_1x1_tex_obj_id.get_or_insert_with(|| { + let white_1x1_tex_obj_id = *pipeline_resources + .white_1x1_tex_obj_id + .get_or_insert_with(|| { create_white_1x1_texture_object(object_store, render_pass) }); + let shaders = get_or_create_shaders( + shader_context, + object_store, + render_pass, + &mut pipeline_resources, + backend_properties, + )?; + let main_3d_shader_cursor = ShaderCursor::new( shaders - .main_3d_shader_program + .main_3d_shader .reflection(backend_properties.shader_target_id) .context("Unable to get reflection for main 3D shader")? .global_params_var_layout() @@ -332,7 +320,7 @@ pub fn add_passes( &camera_transform, &window, shaders.sky_box_shader_obj_id, - shaders.sky_box_shader_program, + shaders.sky_box_shader, &backend_properties, )?; } @@ -370,107 +358,90 @@ fn create_white_1x1_texture_object( } #[derive(Debug)] -enum ShadersCreationStatus<'shader_ctx> -{ - ProcessingRequired, - Ready(ReadyShaders<'shader_ctx>), -} - -#[derive(Debug)] -struct ReadyShaders<'shader_ctx> +struct ReadyShaders<'pipeline_resources> { main_3d_shader_obj_id: ObjectId, - main_3d_shader_program: &'shader_ctx ShaderProgram, + main_3d_shader: &'pipeline_resources ShaderProgram, sky_box_shader_obj_id: ObjectId, - sky_box_shader_program: &'shader_ctx ShaderProgram, + sky_box_shader: &'pipeline_resources ShaderProgram, } -fn get_or_create_shaders<'shader_ctx>( - assets: &mut Assets, - shader_context: &'shader_ctx ShaderContext, +fn get_or_create_shaders<'pipeline_resources>( + shader_context: &ShaderContext, object_store: &mut ObjectStore, render_pass: &mut RenderPass, -) -> Result<ShadersCreationStatus<'shader_ctx>, crate::Error> + pipeline_resources: &'pipeline_resources mut PipelineResources, + backend_properties: &BackendProperties, +) -> Result<ReadyShaders<'pipeline_resources>, crate::Error> { - let main_3d_shader_asset = assets - .get_handle_to_loaded::<ShaderModuleSource>(MAIN_3D_SHADER_ASSET_LABEL.clone()) - .or_else(|| { - assets.store_with_label( - MAIN_3D_SHADER_ASSET_LABEL.clone(), - ShaderModuleSource { - name: "main_3d_shader.slang".into(), - file_path: Path::new("@engine/main_3d_shader").into(), - source: include_str!("../../res/main_3d_shader.slang").into(), - link_entry_points: ShaderEntrypointFlags::VERTEX - | ShaderEntrypointFlags::FRAGMENT, - }, - ); - - None - }); - - let sky_box_shader_asset = assets - .get_handle_to_loaded::<ShaderModuleSource>(SKY_BOX_SHADER_ASSET_LABEL.clone()) - .or_else(|| { - assets.store_with_label( - SKY_BOX_SHADER_ASSET_LABEL.clone(), - ShaderModuleSource { - name: "sky_box_shader.slang".into(), - file_path: Path::new("@engine/sky_box_shader").into(), - source: include_str!("../../res/sky_box_shader.slang").into(), - link_entry_points: ShaderEntrypointFlags::VERTEX - | ShaderEntrypointFlags::FRAGMENT, - }, - ); - None - }); - - let (Some(main_3d_shader_asset), Some(sky_box_shader_asset)) = - (main_3d_shader_asset, sky_box_shader_asset) - else { - return Ok(ShadersCreationStatus::ProcessingRequired); - }; - - let main_3d_shader_program = shader_context.get_program(&main_3d_shader_asset.id()); - - let main_3d_shader_program = main_3d_shader_program.ok_or_else(|| { - error!("Shader context doesn't have a program for main 3D shader") - })?; + let (main_3d_shader_obj_id, main_3d_shader) = pipeline_resources + .main_3d_shader + .get_or_try_insert_with_fn(|| { + let module_source = ShaderModuleSource { + name: "main_3d_shader.slang".into(), + file_path: Path::new("@engine/main_3d_shader").into(), + source: include_str!("../../res/main_3d_shader.slang").into(), + link_entry_points: ShaderEntrypointFlags::VERTEX + | ShaderEntrypointFlags::FRAGMENT, + }; - let main_3d_shader_obj_id = ObjectId::Asset(main_3d_shader_asset.id()); + let obj_id = ObjectId::new_sequential(); - if !object_store.contains_maybe_pending_with_id(&main_3d_shader_obj_id) { - object_store.insert_pending(main_3d_shader_obj_id); + let shader = shader_context + .compose_program( + &[shader_context.load_module(&module_source)?], + module_source.link_entry_points, + backend_properties.shader_target_id, + )? + .into_linked()?; - render_pass.commands.push(Command::CreateShaderProgram( - main_3d_shader_obj_id, - main_3d_shader_program.clone(), - )); - } + object_store.insert_pending(obj_id); - let sky_box_shader_program = shader_context.get_program(&sky_box_shader_asset.id()); - - let sky_box_shader_program = sky_box_shader_program.ok_or_else(|| { - error!("Shader context doesn't have a program for sky box shader") - })?; + render_pass + .commands + .push(Command::CreateShaderProgram(obj_id, shader.clone())); + + Ok::<_, crate::Error>((obj_id, shader)) + }) + .context("Creation of main 3D shader failed")?; + + let (sky_box_shader_obj_id, sky_box_shader) = pipeline_resources + .sky_box_shader + .get_or_try_insert_with_fn(|| { + let module_source = ShaderModuleSource { + name: "sky_box_shader.slang".into(), + file_path: Path::new("@engine/sky_box_shader").into(), + source: include_str!("../../res/sky_box_shader.slang").into(), + link_entry_points: ShaderEntrypointFlags::VERTEX + | ShaderEntrypointFlags::FRAGMENT, + }; - let sky_box_shader_obj_id = ObjectId::Asset(sky_box_shader_asset.id()); + let obj_id = ObjectId::new_sequential(); - if !object_store.contains_maybe_pending_with_id(&sky_box_shader_obj_id) { - object_store.insert_pending(sky_box_shader_obj_id); + let shader = shader_context + .compose_program( + &[shader_context.load_module(&module_source)?], + module_source.link_entry_points, + backend_properties.shader_target_id, + )? + .into_linked()?; - render_pass.commands.push(Command::CreateShaderProgram( - sky_box_shader_obj_id, - sky_box_shader_program.clone(), - )); - } + object_store.insert_pending(obj_id); - Ok(ShadersCreationStatus::Ready(ReadyShaders { - main_3d_shader_obj_id, - main_3d_shader_program, - sky_box_shader_obj_id, - sky_box_shader_program, - })) + render_pass + .commands + .push(Command::CreateShaderProgram(obj_id, shader.clone())); + + Ok::<_, crate::Error>((obj_id, shader)) + }) + .context("Creation of sky box shader failed")?; + + Ok(ReadyShaders { + main_3d_shader_obj_id: *main_3d_shader_obj_id, + main_3d_shader: main_3d_shader, + sky_box_shader_obj_id: *sky_box_shader_obj_id, + sky_box_shader: sky_box_shader, + }) } fn add_renderable_creation_commands( |
