diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index 362c302036..3919219336 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -148,6 +148,12 @@ impl Default for Options { } } +/// Structure that contains a reflection info +pub struct ReflectionInfo { + pub texture_mapping: FastHashMap, + pub uniforms: FastHashMap, String>, +} + /// Structure that connects a texture to a sampler or not /// /// glsl pre vulkan has no concept of separate textures and samplers instead everything is a @@ -285,6 +291,8 @@ pub struct Writer<'a, W> { /// A map with all the names needed for writing the module /// (generated by a [`Namer`](crate::proc::Namer)) names: FastHashMap, + /// A map with all the names needed for reflections + reflection_names: FastHashMap, String>, /// The selected entry point entry_point: &'a crate::EntryPoint, /// The index of the selected entry point @@ -334,6 +342,7 @@ impl<'a, W: Write> Writer<'a, W> { features: FeaturesManager::new(), names, + reflection_names: FastHashMap::default(), entry_point: &module.entry_points[ep_idx], entry_point_idx: ep_idx as u16, @@ -354,7 +363,7 @@ impl<'a, W: Write> Writer<'a, W> { /// /// # Panics /// Might panic if the module is invalid - pub fn write(&mut self) -> Result, Error> { + pub fn write(&mut self) -> Result { // We use `writeln!(self.out)` throughout the write to add newlines // to make the output more readable @@ -526,8 +535,8 @@ impl<'a, W: Write> Writer<'a, W> { // Add newline at the end of file writeln!(self.out)?; - // Collect all of the texture mappings and return them to the user - self.collect_texture_mapping() + // Collect all relection info and return it to the user + self.collect_reflection_info() } /// Helper method used to write non image/sampler types @@ -962,7 +971,10 @@ impl<'a, W: Write> Writer<'a, W> { // generated number so it's unique and `members` are the same as in a struct if block { // Write the block name, it's just the struct name appended with `_block_ID` - writeln!(self.out, "{}_block_{} {{", name, self.block_id.generate())?; + let block_name = format!("{}_block_{}", name, self.block_id.generate()); + writeln!(self.out, "{} {{", block_name)?; + + self.reflection_names.insert(handle, block_name); } else { writeln!(self.out, "struct {} {{", name)?; } @@ -1873,15 +1885,16 @@ impl<'a, W: Write> Writer<'a, W> { Ok(()) } - /// Helper method used to produce the images mapping that's returned to the user + /// Helper method used to produce the reflection info that's returned to the user /// /// It takes an iterator of [`Function`](crate::Function) references instead of /// [`Handle`](crate::arena::Handle) because [`EntryPoint`](crate::EntryPoint) isn't in any /// [`Arena`](crate::arena::Arena) and we need to traverse it - fn collect_texture_mapping(&self) -> Result, Error> { + fn collect_reflection_info(&self) -> Result { use std::collections::hash_map::Entry; let info = self.analysis.get_entry_point(self.entry_point_idx as usize); let mut mappings = FastHashMap::default(); + let mut uniforms = FastHashMap::default(); for sampling in info.sampling_set.iter() { let tex_name = self.names[&NameKey::GlobalVariable(sampling.image)].clone(); @@ -1907,7 +1920,13 @@ impl<'a, W: Write> Writer<'a, W> { continue; } match self.module.types[var.ty].inner { - crate::TypeInner::Image { .. } => (), + crate::TypeInner::Struct { .. } => match var.class { + StorageClass::Uniform | StorageClass::Storage => { + let name = self.reflection_names[&var.ty].clone(); + uniforms.insert(handle, name); + } + _ => (), + }, _ => continue, } let tex_name = self.names[&NameKey::GlobalVariable(handle)].clone(); @@ -1919,7 +1938,10 @@ impl<'a, W: Write> Writer<'a, W> { } } - Ok(mappings) + Ok(ReflectionInfo { + texture_mapping: mappings, + uniforms, + }) } }