diff options
| author | HampusM <hampus@hampusmat.com> | 2026-11-02 02:07:56 +0100 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-11-02 05:53:56 +0100 |
| commit | 1529915d58524ab4de3eaa0b3441fc09c1dcf4f0 (patch) | |
| tree | dc5b2af146d453e3dfe3be4196c299d5d447699f /engine | |
| parent | b15824514239e37c4c7304d018d9f493e26718ee (diff) | |
Diffstat (limited to 'engine')
| -rw-r--r-- | engine/src/rendering.rs | 12 | ||||
| -rw-r--r-- | engine/src/rendering/backend/opengl.rs | 98 | ||||
| -rw-r--r-- | engine/src/rendering/main_pipeline.rs | 12 | ||||
| -rw-r--r-- | engine/src/rendering/shader.rs | 264 | ||||
| -rw-r--r-- | engine/src/ui/dear_imgui.rs | 10 |
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(), |
