summaryrefslogtreecommitdiff
path: root/engine/src
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-11-02 02:07:56 +0100
committerHampusM <hampus@hampusmat.com>2026-11-02 05:53:56 +0100
commit1529915d58524ab4de3eaa0b3441fc09c1dcf4f0 (patch)
treedc5b2af146d453e3dfe3be4196c299d5d447699f /engine/src
parentb15824514239e37c4c7304d018d9f493e26718ee (diff)
refactor(engine): make shader compile targets not hardcodedHEADmaster
Diffstat (limited to 'engine/src')
-rw-r--r--engine/src/rendering.rs12
-rw-r--r--engine/src/rendering/backend/opengl.rs98
-rw-r--r--engine/src/rendering/main_pipeline.rs12
-rw-r--r--engine/src/rendering/shader.rs264
-rw-r--r--engine/src/ui/dear_imgui.rs10
5 files changed, 290 insertions, 106 deletions
diff --git a/engine/src/rendering.rs b/engine/src/rendering.rs
index bbfee72..1f1be64 100644
--- a/engine/src/rendering.rs
+++ b/engine/src/rendering.rs
@@ -24,7 +24,10 @@ use crate::mesh::Mesh;
use crate::rendering::blending::Config as BlendingConfig;
use crate::rendering::object::{Id as ObjectId, Store as ObjectStore};
use crate::rendering::shader::cursor::Binding as ShaderBinding;
-use crate::rendering::shader::Program as ShaderProgram;
+use crate::rendering::shader::{
+ CompileTargetId as ShaderCompileTargetId,
+ Program as ShaderProgram,
+};
use crate::texture::{CubeMapFace, Properties as TextureProperties};
use crate::vector::Vec2;
use crate::windowing::dpi::PhysicalSize;
@@ -199,6 +202,13 @@ impl SurfaceId
}
}
+/// Properties of the current rendering backend.
+#[derive(Debug, Sole)]
+pub struct BackendProperties
+{
+ pub shader_target_id: ShaderCompileTargetId,
+}
+
#[derive(Debug, Default, Sole)]
pub struct RenderPasses
{
diff --git a/engine/src/rendering/backend/opengl.rs b/engine/src/rendering/backend/opengl.rs
index b8ac04b..bdaa555 100644
--- a/engine/src/rendering/backend/opengl.rs
+++ b/engine/src/rendering/backend/opengl.rs
@@ -6,6 +6,7 @@ use std::convert::Infallible;
use std::hint::cold_path;
use std::num::NonZero;
+use ecs::phase::INIT as INIT_PHASE;
use ecs::query::term::With;
use glutin::config::Config as GlutinConfig;
use glutin::display::GetGlDisplay;
@@ -118,12 +119,15 @@ use crate::rendering::shader::cursor::{
};
use crate::rendering::shader::reflection::Stage as ShaderStage;
use crate::rendering::shader::{
+ EntrypointFlags as ShaderEntrypointFlags,
Error as ShaderError,
Program as ShaderProgram,
- ProgramMetadata as ShaderProgramMetadata,
+ VertexDescCreationError as ShaderVertexDescCreationError,
+ VertexDescription as ShaderVertexDescription,
};
use crate::rendering::{
AssetOrValue,
+ BackendProperties,
BufferClearMask,
Command,
CommandQueue,
@@ -436,7 +440,7 @@ enum BackendResource
Shader
{
program: GlShaderProgram,
- program_metadata: ShaderProgramMetadata,
+ info: ShaderInfo,
bindings: IntMap<ShaderBindingIndex, BackendShaderBinding>,
},
Texture
@@ -489,6 +493,14 @@ enum TextureKind
CubeMap,
}
+#[derive(Debug, Clone)]
+struct ShaderInfo
+{
+ /// If the shader program has a entry point in the vertex stage, this field will
+ /// contain a description of the vertex type passed to the entry point.
+ vertex_desc: Option<ShaderVertexDescription>,
+}
+
#[derive(Debug, Default)]
#[non_exhaustive]
pub struct Extension {}
@@ -497,6 +509,8 @@ impl crate::ecs::extension::Extension for Extension
{
fn collect(self, mut collector: crate::ecs::extension::Collector<'_>)
{
+ collector.add_system(*INIT_PHASE, init);
+
collector.add_system(*RENDER_PHASE, handle_commands);
collector.add_system(*POST_RENDER_PHASE, prepare_windows);
@@ -506,6 +520,24 @@ impl crate::ecs::extension::Extension for Extension
}
}
+fn init(
+ mut shader_context: Single<crate::rendering::shader::Context>,
+ mut actions: Actions,
+) -> Result<(), crate::Error>
+{
+ let shader_context = shader_context.get_mut()?;
+
+ let shader_target_ids = shader_context
+ .init_session(&[&crate::rendering::shader::CompileTarget::default()
+ .format(crate::rendering::shader::CompileTargetFormat::Glsl)])?;
+
+ actions.create_sole(BackendProperties {
+ shader_target_id: shader_target_ids[0],
+ });
+
+ Ok(())
+}
+
fn prepare_windows(
window_query: Query<(
Option<&Window>,
@@ -756,6 +788,7 @@ fn handle_commands(
mut object_store: Single<ObjectStore>,
mut command_queue: Single<CommandQueue>,
assets: Single<Assets>,
+ backend_properties: Single<BackendProperties>,
) -> Result<(), crate::Error>
{
let Ok(graphics_ctx) = graphics_ctx.get_mut() else {
@@ -766,6 +799,10 @@ fn handle_commands(
let command_queue = command_queue.get_mut()?;
let assets = assets.get()?;
+ let Ok(backend_properties) = backend_properties.get() else {
+ return Ok(());
+ };
+
let GraphicsContext {
ref gl_context,
ref mut surfaces,
@@ -776,11 +813,8 @@ fn handle_commands(
return Ok(());
};
- let mut activated_gl_shader_program: Option<(
- ObjectId,
- GlShaderProgram,
- ShaderProgramMetadata,
- )> = None;
+ let mut activated_gl_shader_program: Option<(ObjectId, GlShaderProgram, ShaderInfo)> =
+ None;
for command in command_queue.drain() {
let tracing_span = tracing::info_span!(
@@ -895,8 +929,21 @@ fn handle_commands(
program: create_shader_program(
gl_context,
&shader_program,
+ backend_properties,
)?,
- program_metadata: shader_program.metadata().clone(),
+ info: ShaderInfo {
+ vertex_desc: if shader_program
+ .metadata()
+ .link_entrypoints
+ .contains(ShaderEntrypointFlags::VERTEX)
+ {
+ Some(shader_program.create_vertex_desc(
+ backend_properties.shader_target_id,
+ )?)
+ } else {
+ None
+ },
+ },
bindings: IntMap::with_capacity(4),
})
},
@@ -914,7 +961,7 @@ fn handle_commands(
continue;
};
- let BackendResource::Shader { program, program_metadata, bindings } =
+ let BackendResource::Shader { program, info: shader_info, bindings } =
resource
else {
unreachable!();
@@ -927,7 +974,7 @@ fn handle_commands(
}
activated_gl_shader_program =
- Some((shader_object_id, program.clone(), program_metadata.clone()));
+ Some((shader_object_id, program.clone(), shader_info.clone()));
}
Command::SetShaderBinding(
shader_object_id,
@@ -1162,7 +1209,7 @@ fn handle_commands(
unreachable!();
};
- let Some((shader_program_obj_id, _, shader_program_metadata)) =
+ let Some((shader_program_obj_id, _, shader_info)) =
&activated_gl_shader_program
else {
tracing::error!("No shader program is activated");
@@ -1174,8 +1221,7 @@ fn handle_commands(
vertex_attrs_updated_for_shader != *shader_program_obj_id
},
) {
- let Some(shader_program_vertex_desc) =
- &shader_program_metadata.vertex_desc
+ let Some(shader_program_vertex_desc) = &shader_info.vertex_desc
else {
tracing::error!(
"Activated shader program does not have a vertex description"
@@ -1799,9 +1845,12 @@ fn cube_map_texture_face_to_gl(face: CubeMapTextureFace) -> GlCubeMapTextureFace
fn create_shader_program(
current_context: &MaybeCurrentContextWithFns,
shader_program: &ShaderProgram,
+ backend_properties: &BackendProperties,
) -> Result<GlShaderProgram, CreateShaderError>
{
- let shader_program_reflection = shader_program.reflection(0).expect("Not possible");
+ let shader_program_reflection = shader_program
+ .reflection(backend_properties.shader_target_id)
+ .expect("Not possible");
let (vs_entry_point_index, vs_entry_point_reflection) = shader_program_reflection
.entry_points()
@@ -1812,9 +1861,12 @@ fn create_shader_program(
})?;
let vertex_shader_entry_point_code = shader_program
- .get_entry_point_code(vs_entry_point_index.try_into().expect(
- "Vertex shader entry point index does not fit in 32-bit unsigned int",
- ))
+ .get_entry_point_code(
+ vs_entry_point_index.try_into().expect(
+ "Vertex shader entry point index does not fit in 32-bit unsigned int",
+ ),
+ backend_properties.shader_target_id,
+ )
.map_err(|err| CreateShaderError::GetShaderEntryPointCodeFailed {
err,
stage: ShaderStage::Vertex,
@@ -1832,9 +1884,12 @@ fn create_shader_program(
})?;
let fragment_shader_entry_point_code = shader_program
- .get_entry_point_code(fs_entry_point_index.try_into().expect(
- "Fragment shader entry point index does not fit in 32-bit unsigned int",
- ))
+ .get_entry_point_code(
+ fs_entry_point_index.try_into().expect(
+ "Fragment shader entry point index does not fit in 32-bit unsigned int",
+ ),
+ backend_properties.shader_target_id,
+ )
.map_err(|err| CreateShaderError::GetShaderEntryPointCodeFailed {
err,
stage: ShaderStage::Fragment,
@@ -1888,6 +1943,9 @@ enum CreateShaderError
#[error("No entrypoint was found for shader stage {0:?}")]
NoShaderStageEntrypointFound(ShaderStage),
+ #[error("Failed to create shader vertex description")]
+ VertexDescCreationFailed(#[from] ShaderVertexDescCreationError),
+
#[error(transparent)]
ShaderError(#[from] GlShaderError),
}
diff --git a/engine/src/rendering/main_pipeline.rs b/engine/src/rendering/main_pipeline.rs
index 66030ab..754b507 100644
--- a/engine/src/rendering/main_pipeline.rs
+++ b/engine/src/rendering/main_pipeline.rs
@@ -42,6 +42,7 @@ use crate::rendering::shader::{
};
use crate::rendering::{
AssetOrValue,
+ BackendProperties,
BufferClearMask,
Command,
DepthFunction,
@@ -130,6 +131,7 @@ pub fn add_passes(
Traverse<(With<Scene>, With<ActiveScene>), TraverseUp, ChildOf>,
)>,
shader_context: Single<ShaderContext>,
+ backend_properties: Single<BackendProperties>,
mut assets: Single<Assets>,
mut render_passes: Single<RenderPasses>,
mut object_store: Single<ObjectStore>,
@@ -142,6 +144,10 @@ pub fn add_passes(
let render_passes = render_passes.get_mut()?;
let object_store = object_store.get_mut()?;
+ let Ok(backend_properties) = backend_properties.get() else {
+ return Ok(());
+ };
+
let Some((scene_ent_id, (scene_env_lighting, scene_skybox, scene_skybox_state))) =
scene_query.iter_with_euids().next()
else {
@@ -186,7 +192,7 @@ pub fn add_passes(
let main_3d_shader_cursor = ShaderCursor::new(
shaders
.main_3d_shader_program
- .reflection(0)
+ .reflection(backend_properties.shader_target_id)
.context("Unable to get reflection for main 3D shader")?
.global_params_var_layout()
.ok_or_else(|| {
@@ -327,6 +333,7 @@ pub fn add_passes(
&window,
shaders.sky_box_shader_obj_id,
shaders.sky_box_shader_program,
+ &backend_properties,
)?;
}
}
@@ -820,6 +827,7 @@ fn add_sky_box_commands(
window: &Window,
sky_box_shader_obj_id: ObjectId,
sky_box_shader_program: &ShaderProgram,
+ backend_properties: &BackendProperties,
) -> Result<(), crate::Error>
{
render_pass
@@ -828,7 +836,7 @@ fn add_sky_box_commands(
let sky_box_shader_cursor = ShaderCursor::new(
sky_box_shader_program
- .reflection(0)
+ .reflection(backend_properties.shader_target_id)
.unwrap()
.global_params_var_layout()
.unwrap(),
diff --git a/engine/src/rendering/shader.rs b/engine/src/rendering/shader.rs
index b357b2c..926302a 100644
--- a/engine/src/rendering/shader.rs
+++ b/engine/src/rendering/shader.rs
@@ -1,6 +1,5 @@
use std::any::type_name;
use std::borrow::Cow;
-use std::collections::{HashMap, HashSet};
use std::fmt::{Debug, Display, Write};
use std::path::Path;
use std::str::Utf8Error;
@@ -144,20 +143,52 @@ impl Program
&self.metadata
}
- pub fn get_entry_point_code(&self, entry_point_index: u32) -> Result<Blob, Error>
+ pub fn get_entry_point_code(
+ &self,
+ entry_point_index: u32,
+ target_id: CompileTargetId,
+ ) -> Result<Blob, Error>
{
- let blob = self.inner.entry_point_code(entry_point_index.into(), 0)?;
+ let blob = self
+ .inner
+ .entry_point_code(entry_point_index.into(), i64::from(target_id.index))?;
Ok(Blob { inner: blob })
}
- pub fn reflection(&self, target: u32)
- -> Result<self::reflection::Program<'_>, Error>
+ pub fn reflection(
+ &self,
+ target_id: CompileTargetId,
+ ) -> Result<self::reflection::Program<'_>, Error>
{
- let reflection = self.inner.layout(i64::from(target))?;
+ let reflection = self.inner.layout(i64::from(target_id.index))?;
Ok(self::reflection::Program { inner: reflection })
}
+
+ pub fn create_vertex_desc(
+ &self,
+ target_id: CompileTargetId,
+ ) -> Result<VertexDescription, VertexDescCreationError>
+ {
+ if !self
+ .metadata
+ .link_entrypoints
+ .contains(EntrypointFlags::VERTEX)
+ {
+ return Err(VertexDescCreationError::NoVertexStageEntrypointInProgram);
+ }
+
+ let program_reflection = self
+ .reflection(target_id)
+ .map_err(VertexDescCreationError::GetProgramReflectionFailed)?;
+
+ VertexDescription::new(
+ &program_reflection
+ .get_entry_point_by_name("vertex_main")
+ .expect("Not possible"),
+ )
+ }
}
impl Debug for Program
@@ -183,6 +214,7 @@ impl Blob
self.inner.as_slice()
}
+ #[allow(clippy::missing_errors_doc)]
pub fn as_str(&self) -> Result<&str, Utf8Error>
{
self.inner.as_str()
@@ -202,14 +234,63 @@ pub struct Settings
#[derive(Sole)]
pub struct Context
{
- _global_session: SlangGlobalSession,
- session: SlangSession,
- modules: HashMap<AssetId, Module>,
- programs: HashMap<AssetId, Program>,
+ global_session: SlangGlobalSession,
+ session: Option<SlangSession>,
+ modules: hashbrown::HashMap<AssetId, Module>,
+ programs: hashbrown::HashMap<AssetId, Program>,
}
impl Context
{
+ #[allow(clippy::missing_errors_doc)]
+ pub fn init_session(
+ &mut self,
+ compile_targets: &[&CompileTarget],
+ ) -> Result<Vec<CompileTargetId>, ContextSessionInitError>
+ {
+ if self.session.is_some() {
+ return Err(ContextSessionInitError::AlreadyInitialized);
+ }
+
+ if compile_targets.len() > u32::MAX as usize {
+ return Err(ContextSessionInitError::TooManyCompileTargets);
+ }
+
+ let session_options = shader_slang::CompilerOptions::default()
+ .optimization(shader_slang::OptimizationLevel::None)
+ .matrix_layout_row(true)
+ .debug_information(SlangDebugInfoLevel::Maximal)
+ .no_mangle(true);
+
+ let (compile_target_ids, target_descs) = compile_targets
+ .iter()
+ .enumerate()
+ .map(|(index, compile_target)| {
+ // The length of compile_targets is not greater than u32::MAX
+ #[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)]
+ (
+ CompileTargetId { index: index as u32 },
+ shader_slang::TargetDesc::default()
+ .format(compile_target.format.into_slang()),
+ )
+ })
+ .collect::<(Vec<_>, Vec<_>)>();
+
+ let session_desc = shader_slang::SessionDesc::default()
+ .targets(&target_descs)
+ .search_paths([""])
+ .options(&session_options);
+
+ let Some(session) = self.global_session.create_session(&session_desc) else {
+ tracing::error!("Failed to create shader-slang session");
+ return Err(ContextSessionInitError::Internal);
+ };
+
+ self.session = Some(session);
+
+ Ok(compile_target_ids)
+ }
+
#[must_use]
pub fn get_module(&self, asset_id: &AssetId) -> Option<&Module>
{
@@ -229,6 +310,10 @@ impl Context
link_entrypoints: EntrypointFlags,
) -> Result<Program, ComposeProgramError>
{
+ let Some(session) = self.session.as_ref() else {
+ return Err(ComposeProgramError::ContextSessionNotInitialized);
+ };
+
let entry_points = link_entrypoints
.iter()
.filter_map(|entrypoint_flag| {
@@ -254,43 +339,63 @@ impl Context
.chain([SlangComponentType::from(module.inner)])
.collect::<Vec<_>>();
- let program = self
- .session
+ let program = session
.create_composite_component_type(&components)
.map_err(|err| ComposeProgramError::Other(Error(err)))?;
- let vertex_desc = if link_entrypoints.contains(EntrypointFlags::VERTEX) {
- // TODO: Do not have hard coded target here
- let Ok(program_reflection) = program.layout(0) else {
- unreachable!();
- };
-
- let program_reflection =
- self::reflection::Program { inner: program_reflection };
-
- Some(VertexDescription::new(
- &program_reflection
- .get_entry_point_by_name("vertex_main")
- .expect("Not possible"),
- )?)
- } else {
- None
- };
-
Ok(Program {
inner: program,
- metadata: ProgramMetadata { vertex_desc },
+ metadata: ProgramMetadata { link_entrypoints },
})
}
}
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct CompileTargetId
+{
+ index: u32,
+}
+
+#[derive(Debug, Default, Clone, Copy)]
+#[non_exhaustive]
+pub struct CompileTarget
+{
+ pub format: CompileTargetFormat,
+}
+
+impl CompileTarget
+{
+ #[must_use]
+ pub fn format(mut self, format: CompileTargetFormat) -> Self
+ {
+ self.format = format;
+ self
+ }
+}
+
+#[derive(Debug, Default, Clone, Copy)]
+#[non_exhaustive]
+pub enum CompileTargetFormat
+{
+ #[default]
+ Glsl,
+}
+
+impl CompileTargetFormat
+{
+ fn into_slang(self) -> shader_slang::CompileTarget
+ {
+ match self {
+ Self::Glsl => shader_slang::CompileTarget::Glsl,
+ }
+ }
+}
+
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct ProgramMetadata
{
- /// If the program has a entry point in the vertex stage, this field will contain a
- /// description of the vertex type passed to the entry point.
- pub vertex_desc: Option<VertexDescription>,
+ pub link_entrypoints: EntrypointFlags,
}
#[derive(Debug, Clone)]
@@ -303,14 +408,10 @@ pub struct VertexDescription
impl VertexDescription
{
#[tracing::instrument(skip_all, fields(vs_entry_point_name = vs_entrypoint.name()))]
- pub fn new(
+ fn new(
vs_entrypoint: &self::reflection::EntryPointReflection<'_>,
- ) -> Result<Self, VertexDescriptionError>
+ ) -> Result<Self, VertexDescCreationError>
{
- if vs_entrypoint.stage() != self::reflection::Stage::Vertex {
- return Err(VertexDescriptionError::EntrypointNotInVertexStage);
- }
-
let inputs = VarInputDfsIter::new(vs_entrypoint).inspect(|var_input| {
if var_input.type_layout.kind() != self::reflection::TypeKind::Struct {
return;
@@ -327,7 +428,7 @@ impl VertexDescription
);
});
- let mut seen_inputs = HashSet::<VertexInputSemName>::new();
+ let mut seen_inputs = hashbrown::HashSet::<VertexInputSemName>::new();
Ok(Self {
inputs: inputs
@@ -339,7 +440,7 @@ impl VertexDescription
let semantic_name =
var_input.var_layout.semantic_name().ok_or_else(|| {
- VertexDescriptionError::VertexInputMissingSemanticName {
+ VertexDescCreationError::VertexInputMissingSemanticName {
name: name.to_owned(),
}
})?;
@@ -349,7 +450,7 @@ impl VertexDescription
if seen_inputs.contains(&semantic_name) {
return Err(
- VertexDescriptionError::VertexInputHasOccupiedSemanticName {
+ VertexDescCreationError::VertexInputHasOccupiedSemanticName {
name: name.to_owned(),
},
);
@@ -364,9 +465,11 @@ impl VertexDescription
var_input.type_layout.scalar_type(),
)
else {
- return Err(VertexDescriptionError::UnsupportedVertexInputType {
- name: name.to_owned(),
- });
+ return Err(
+ VertexDescCreationError::UnsupportedVertexInputType {
+ name: name.to_owned(),
+ },
+ );
};
seen_inputs.insert(semantic_name.clone());
@@ -457,10 +560,13 @@ impl Display for VertexInputSemName
}
#[derive(Debug, thiserror::Error)]
-pub enum VertexDescriptionError
+pub enum VertexDescCreationError
{
- #[error("Entrypoint is not in vertex stage")]
- EntrypointNotInVertexStage,
+ #[error("Shader program has no entry point in vertex stage")]
+ NoVertexStageEntrypointInProgram,
+
+ #[error("Failed to get shader program reflection")]
+ GetProgramReflectionFailed(#[source] Error),
#[error("Type of vertex input '{name}' is not supported")]
UnsupportedVertexInputType
@@ -486,6 +592,9 @@ pub enum VertexDescriptionError
#[derive(Debug, thiserror::Error)]
pub enum ComposeProgramError
{
+ #[error("A shader context session has not been initialized")]
+ ContextSessionNotInitialized,
+
#[error("Shader module does not have a '{entrypoint_name}' entry point")]
EntrypointNotFoundError
{
@@ -493,13 +602,26 @@ pub enum ComposeProgramError
},
#[error("Failed to create vertex description")]
- VertexDescriptionCreationFailed(#[from] VertexDescriptionError),
+ VertexDescriptionCreationFailed(#[from] VertexDescCreationError),
#[error(transparent)]
Other(Error),
}
#[derive(Debug, thiserror::Error)]
+pub enum ContextSessionInitError
+{
+ #[error("A shader context session has already been initialized")]
+ AlreadyInitialized,
+
+ #[error("Too many compile targets. Count would overflow a u32")]
+ TooManyCompileTargets,
+
+ #[error("An internal error occurred")]
+ Internal,
+}
+
+#[derive(Debug, thiserror::Error)]
#[error(transparent)]
pub struct Error(#[from] shader_slang::Error);
@@ -595,9 +717,7 @@ fn import(
source: std::fs::read_to_string(file_path)
.map_err(ImportError::ReadFileFailed)?
.into(),
- link_entrypoints: settings
- .map(|settings| settings.link_entrypoints)
- .unwrap_or_default(),
+ link_entrypoints: settings.map_or_default(|settings| settings.link_entrypoints),
});
Ok(())
@@ -633,36 +753,12 @@ pub(super) fn prepare(collector: &mut crate::ecs::extension::Collector<'_>)
return;
};
- let session_options = shader_slang::CompilerOptions::default()
- .optimization(shader_slang::OptimizationLevel::None)
- .matrix_layout_row(true)
- .debug_information(SlangDebugInfoLevel::Maximal)
- .no_mangle(true);
-
- let target_desc = shader_slang::TargetDesc::default()
- .format(shader_slang::CompileTarget::Glsl)
- // .format(shader_slang::CompileTarget::Spirv)
- .profile(global_session.find_profile("glsl_330"));
- // .profile(global_session.find_profile("spirv_1_5"));
-
- let targets = [target_desc];
-
- let session_desc = shader_slang::SessionDesc::default()
- .targets(&targets)
- .search_paths([""])
- .options(&session_options);
-
- let Some(session) = global_session.create_session(&session_desc) else {
- tracing::error!("Failed to create shader-slang session");
- return;
- };
-
collector
.add_sole(Context {
- _global_session: global_session,
- session,
- modules: HashMap::new(),
- programs: HashMap::new(),
+ global_session,
+ session: None,
+ modules: hashbrown::HashMap::new(),
+ programs: hashbrown::HashMap::new(),
})
.ok();
@@ -695,6 +791,10 @@ fn load_modules(
let assets = assets.get()?;
let asset_events = asset_events.get()?;
+ let Some(session) = context.session.as_ref() else {
+ return Ok(());
+ };
+
for AssetEvent::Loaded(asset_id, asset_label) in asset_events.iter_last_tick() {
let asset_handle = AssetHandle::<ModuleSource>::from_id(*asset_id);
@@ -708,7 +808,7 @@ fn load_modules(
tracing::debug!(asset_label=?asset_label, "Loading shader module");
- let module = match load_module(&context.session, module_source) {
+ let module = match load_module(session, module_source) {
Ok(module) => module,
Err(err) => {
tracing::error!("Failed to load shader module: {err}");
diff --git a/engine/src/ui/dear_imgui.rs b/engine/src/ui/dear_imgui.rs
index 349cf6c..b3a102b 100644
--- a/engine/src/ui/dear_imgui.rs
+++ b/engine/src/ui/dear_imgui.rs
@@ -55,6 +55,7 @@ use crate::rendering::shader::{
};
use crate::rendering::{
AssetOrValue,
+ BackendProperties as RenderingBackendProperties,
Command as RenderingCommand,
DrawMeshOptions,
DrawProperties,
@@ -243,6 +244,7 @@ fn update(
mut assets: Single<Assets>,
mut render_passes: Single<RenderPasses>,
shader_context: Single<ShaderContext>,
+ rendering_backend_properties: Single<RenderingBackendProperties>,
keyboard: Single<Keyboard>,
mouse: Single<Mouse>,
mouse_buttons: Single<MouseButtons>,
@@ -260,6 +262,10 @@ fn update(
let mouse = mouse.get()?;
let mouse_buttons = mouse_buttons.get()?;
+ let Ok(rendering_backend_properties) = rendering_backend_properties.get() else {
+ return Ok(());
+ };
+
let Some((window, window_surface)) = target_window_query.iter().next() else {
return Ok(());
};
@@ -301,6 +307,7 @@ fn update(
context,
render_passes,
shader_context,
+ rendering_backend_properties,
window_surface.id,
shader_asset.clone(),
mesh_obj_id,
@@ -478,6 +485,7 @@ fn add_drawing_render_pass(
context: &mut Context,
render_passes: &mut RenderPasses,
shader_context: &ShaderContext,
+ rendering_backend_properties: &RenderingBackendProperties,
window_surface_id: SurfaceId,
shader_asset: AssetHandle<ShaderModuleSource>,
mesh_obj_id: RenderingObjectId,
@@ -506,7 +514,7 @@ fn add_drawing_render_pass(
let shader_cursor = ShaderCursor::new(
shader_program
- .reflection(0)
+ .reflection(rendering_backend_properties.shader_target_id)
.unwrap()
.global_params_var_layout()
.unwrap(),