summaryrefslogtreecommitdiff
path: root/engine/src/rendering/main_pipeline.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-11-05 12:07:46 +0100
committerHampusM <hampus@hampusmat.com>2026-11-05 12:08:21 +0100
commit48a23ceaf8a85fdd8e82cbb709ef8360d37dadf0 (patch)
tree7a8b13b5fcc0bf349e0353af1fdb8a2884ed8009 /engine/src/rendering/main_pipeline.rs
parente8472cc24f5eafd8a9a08b64c52eb49d01ac4031 (diff)
refactor(engine): make main rendering pipeline create shader programs itself
Diffstat (limited to 'engine/src/rendering/main_pipeline.rs')
-rw-r--r--engine/src/rendering/main_pipeline.rs203
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(