From 2fe66d958f253f73cf22b15b14f82a8e7bc7a0a0 Mon Sep 17 00:00:00 2001 From: chyyran Date: Sun, 6 Oct 2024 15:10:33 -0400 Subject: [PATCH] reflect: put vars to end with running link pass to fix naga ordering --- librashader-reflect/src/back/wgsl.rs | 5 +- .../front/spirv_passes/link_input_outputs.rs | 34 ++++++- librashader-reflect/src/reflect/cross/mod.rs | 95 +++++++++---------- librashader-reflect/src/reflect/naga/mod.rs | 24 ++--- librashader-reflect/src/reflect/naga/msl.rs | 74 +++++++-------- 5 files changed, 129 insertions(+), 103 deletions(-) diff --git a/librashader-reflect/src/back/wgsl.rs b/librashader-reflect/src/back/wgsl.rs index 92bdda7..1cefb93 100644 --- a/librashader-reflect/src/back/wgsl.rs +++ b/librashader-reflect/src/back/wgsl.rs @@ -56,9 +56,12 @@ mod test { #[test] pub fn test_into() { + let result = + ShaderSource::load("../test/shaders_slang/crt/shaders/slotmask.slang").unwrap(); + // let result = ShaderSource::load("../test/shaders_slang/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang").unwrap(); // let result = ShaderSource::load("../test/shaders_slang/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang").unwrap(); - let result = ShaderSource::load("../test/basic.slang").unwrap(); + // let result = ShaderSource::load("../test/basic.slang").unwrap(); let mut uniform_semantics: FastHashMap = Default::default(); diff --git a/librashader-reflect/src/front/spirv_passes/link_input_outputs.rs b/librashader-reflect/src/front/spirv_passes/link_input_outputs.rs index 5ec6a24..43d84b5 100644 --- a/librashader-reflect/src/front/spirv_passes/link_input_outputs.rs +++ b/librashader-reflect/src/front/spirv_passes/link_input_outputs.rs @@ -98,6 +98,30 @@ impl<'a> LinkInputs<'a> { pub fn do_pass(&mut self) { self.trim_inputs(); self.downgrade_outputs(); + self.put_vertex_variables_to_end(); + } + + fn put_vertex_variables_to_end(&mut self) { + // this is easier than doing proper topo sort. + // we need it so that all type definitions are valid before + // being referred to by a variable. + let mut vars = Vec::new(); + + self.vert_builder + .module_mut() + .types_global_values + .retain(|instr| { + if instr.class.opcode == spirv::Op::Variable { + vars.push(instr.clone()); + return false; + }; + true + }); + + self.vert_builder + .module_mut() + .types_global_values + .append(&mut vars); } /// Downgrade dead inputs corresponding to outputs to global variables, keeping existing mappings. @@ -111,7 +135,7 @@ impl<'a> LinkInputs<'a> { let mut pointer_types_to_downgrade = FxHashSet::default(); // Map from Pointer type to pointee - let mut pointer_type_pointee = Vec::new(); + let mut pointer_type_pointee = FxHashMap::default(); // Map from StorageClass Output to StorageClass Private let mut downgraded_pointer_types = FxHashMap::default(); @@ -152,18 +176,18 @@ impl<'a> LinkInputs<'a> { continue; }; - pointer_type_pointee.push((id, pointee_type)); + pointer_type_pointee.insert(id, pointee_type); } } // Create pointer types for everything we saw above with Private storage class. // We don't have to deal with OpTypeForwardPointer, because PhysicalStorageBuffer // is not valid in slang shaders, and we're only working with Vulkan inputs. - for (pointer_type, pointee_type) in pointer_type_pointee.into_iter() { + for (pointer_type, pointee_type) in pointer_type_pointee.iter() { // Create a new private type let private_pointer_type = self.vert_builder - .type_pointer(None, StorageClass::Private, pointee_type); + .type_pointer(None, StorageClass::Private, *pointee_type); // Add it to the mapping downgraded_pointer_types.insert(pointer_type, private_pointer_type); @@ -196,7 +220,7 @@ impl<'a> LinkInputs<'a> { continue; }; - let Some(new_type) = downgraded_pointer_types.get(&result_type) else { + let Some(new_type) = downgraded_pointer_types.get(&*result_type) else { // We should have created one above. continue; }; diff --git a/librashader-reflect/src/reflect/cross/mod.rs b/librashader-reflect/src/reflect/cross/mod.rs index 6c1e2d8..089e8dc 100644 --- a/librashader-reflect/src/reflect/cross/mod.rs +++ b/librashader-reflect/src/reflect/cross/mod.rs @@ -829,54 +829,51 @@ mod test { use crate::reflect::semantics::{Semantic, ShaderSemantics, UniformSemantic, UniqueSemantics}; use librashader_common::map::{FastHashMap, ShortString}; use librashader_preprocess::ShaderSource; - use spirv_cross::glsl::{CompilerOptions, Version}; - use spirv_cross::hlsl::ShaderModel; - use spirv_cross::{glsl, hlsl}; - #[test] - pub fn test_into() { - let result = ShaderSource::load("../test/basic.slang").unwrap(); - let mut uniform_semantics: FastHashMap = Default::default(); - - for (_index, param) in result.parameters.iter().enumerate() { - uniform_semantics.insert( - param.1.id.clone(), - UniformSemantic::Unique(Semantic { - semantics: UniqueSemantics::FloatParameter, - index: (), - }), - ); - } - let spirv = Glslang::compile(&result).unwrap(); - let mut reflect = CrossReflect::::try_from(&spirv).unwrap(); - let shader_reflection = reflect - .reflect( - 0, - &ShaderSemantics { - uniform_semantics, - texture_semantics: Default::default(), - }, - ) - .unwrap(); - let mut opts = hlsl::CompilerOptions::default(); - opts.shader_model = ShaderModel::V3_0; - - let compiled: ShaderCompilerOutput = - as CompileShader>::compile( - reflect, - Some(ShaderModel::V3_0), - ) - .unwrap(); - - println!("{:?}", shader_reflection.meta); - println!("{}", compiled.fragment); - println!("{}", compiled.vertex); - - // // eprintln!("{shader_reflection:#?}"); - // eprintln!("{}", compiled.fragment) - // let mut loader = rspirv::dr::Loader::new(); - // rspirv::binary::parse_words(spirv.fragment.as_binary(), &mut loader).unwrap(); - // let module = loader.module(); - // println!("{:#}", module.disassemble()); - } + // #[test] + // pub fn test_into() { + // let result = ShaderSource::load("../test/basic.slang").unwrap(); + // let mut uniform_semantics: FastHashMap = Default::default(); + // + // for (_index, param) in result.parameters.iter().enumerate() { + // uniform_semantics.insert( + // param.1.id.clone(), + // UniformSemantic::Unique(Semantic { + // semantics: UniqueSemantics::FloatParameter, + // index: (), + // }), + // ); + // } + // let spirv = Glslang::compile(&result).unwrap(); + // let mut reflect = CrossReflect::::try_from(&spirv).unwrap(); + // let shader_reflection = reflect + // .reflect( + // 0, + // &ShaderSemantics { + // uniform_semantics, + // texture_semantics: Default::default(), + // }, + // ) + // .unwrap(); + // let mut opts = hlsl::CompilerOptions::default(); + // opts.shader_model = ShaderModel::V3_0; + // + // let compiled: ShaderCompilerOutput = + // as CompileShader>::compile( + // reflect, + // Some(ShaderModel::V3_0), + // ) + // .unwrap(); + // + // println!("{:?}", shader_reflection.meta); + // println!("{}", compiled.fragment); + // println!("{}", compiled.vertex); + // + // // // eprintln!("{shader_reflection:#?}"); + // // eprintln!("{}", compiled.fragment) + // // let mut loader = rspirv::dr::Loader::new(); + // // rspirv::binary::parse_words(spirv.fragment.as_binary(), &mut loader).unwrap(); + // // let module = loader.module(); + // // println!("{:#}", module.disassemble()); + // } } diff --git a/librashader-reflect/src/reflect/naga/mod.rs b/librashader-reflect/src/reflect/naga/mod.rs index 6901e78..f806012 100644 --- a/librashader-reflect/src/reflect/naga/mod.rs +++ b/librashader-reflect/src/reflect/naga/mod.rs @@ -1046,6 +1046,7 @@ impl ReflectShader for NagaReflect { #[cfg(test)] mod test { + use crate::front::ShaderInputCompiler; use crate::reflect::semantics::{Semantic, TextureSemantics, UniformSemantic}; use librashader_common::map::FastHashMap; use librashader_preprocess::ShaderSource; @@ -1053,18 +1054,19 @@ mod test { // #[test] // pub fn test_into() { - // let result = ShaderSource::load("../test/slang-shaders/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang").unwrap(); - // let compilation = crate::front::GlslangCompilation::try_from(&result).unwrap(); + // let result = ShaderSource::load("../test/slang-shaders/misc/shaders/simple_color_controls.slang").unwrap(); + // let compilation = crate::front::Glslang::compile(&result).unwrap(); // - // let mut loader = rspirv::dr::Loader::new(); - // rspirv::binary::parse_words(compilation.vertex.as_binary(), &mut loader).unwrap(); - // let module = loader.module(); - // - // let outputs: Vec<&Instruction> = module - // .types_global_values - // .iter() - // .filter(|i| i.class.opcode == Op::Variable) - // .collect(); + // crate::front::n + // // let mut loader = rspirv::dr::Loader::new(); + // // rspirv::binary::parse_words(compilation.vertex.as_binary(), &mut loader).unwrap(); + // // let module = loader.module(); + // // + // // let outputs: Vec<&Instruction> = module + // // .types_global_values + // // .iter() + // // .filter(|i| i.class.opcode == Op::Variable) + // // .collect(); // // println!("{outputs:#?}"); // } diff --git a/librashader-reflect/src/reflect/naga/msl.rs b/librashader-reflect/src/reflect/naga/msl.rs index 381a0ad..ce30376 100644 --- a/librashader-reflect/src/reflect/naga/msl.rs +++ b/librashader-reflect/src/reflect/naga/msl.rs @@ -165,42 +165,42 @@ mod test { use bitflags::Flags; use librashader_common::map::{FastHashMap, ShortString}; use librashader_preprocess::ShaderSource; - use spirv_cross::msl; + // use spirv_cross::msl; - #[test] - pub fn test_into() { - let result = ShaderSource::load("../test/basic.slang").unwrap(); - - let mut uniform_semantics: FastHashMap = Default::default(); - - for (_index, param) in result.parameters.iter().enumerate() { - uniform_semantics.insert( - param.1.id.clone(), - UniformSemantic::Unique(Semantic { - semantics: UniqueSemantics::FloatParameter, - index: (), - }), - ); - } - - let compilation = crate::front::SpirvCompilation::try_from(&result).unwrap(); - - let mut msl = >::from_compilation(compilation).unwrap(); - - msl.reflect( - 0, - &ShaderSemantics { - uniform_semantics, - texture_semantics: Default::default(), - }, - ) - .expect(""); - - let compiled = msl.compile(Some(msl::Version::V2_0)).unwrap(); - - println!( - "{:?}", - compiled.context.fragment.translation_info.entry_point_names - ); - } + // #[test] + // pub fn test_into() { + // let result = ShaderSource::load("../test/basic.slang").unwrap(); + // + // let mut uniform_semantics: FastHashMap = Default::default(); + // + // for (_index, param) in result.parameters.iter().enumerate() { + // uniform_semantics.insert( + // param.1.id.clone(), + // UniformSemantic::Unique(Semantic { + // semantics: UniqueSemantics::FloatParameter, + // index: (), + // }), + // ); + // } + // + // let compilation = crate::front::SpirvCompilation::try_from(&result).unwrap(); + // + // let mut msl = >::from_compilation(compilation).unwrap(); + // + // msl.reflect( + // 0, + // &ShaderSemantics { + // uniform_semantics, + // texture_semantics: Default::default(), + // }, + // ) + // .expect(""); + // + // let compiled = msl.compile(Some(msl::Version::V2_0)).unwrap(); + // + // println!( + // "{:?}", + // compiled.context.fragment.translation_info.entry_point_names + // ); + // } }