reflect: put vars to end with running link pass to fix naga ordering

This commit is contained in:
chyyran 2024-10-06 15:10:33 -04:00
parent ed8bf637a9
commit 2fe66d958f
5 changed files with 129 additions and 103 deletions

View file

@ -56,9 +56,12 @@ mod test {
#[test] #[test]
pub fn test_into() { 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/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<ShortString, UniformSemantic> = Default::default(); let mut uniform_semantics: FastHashMap<ShortString, UniformSemantic> = Default::default();

View file

@ -98,6 +98,30 @@ impl<'a> LinkInputs<'a> {
pub fn do_pass(&mut self) { pub fn do_pass(&mut self) {
self.trim_inputs(); self.trim_inputs();
self.downgrade_outputs(); 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. /// 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(); let mut pointer_types_to_downgrade = FxHashSet::default();
// Map from Pointer type to pointee // 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 // Map from StorageClass Output to StorageClass Private
let mut downgraded_pointer_types = FxHashMap::default(); let mut downgraded_pointer_types = FxHashMap::default();
@ -152,18 +176,18 @@ impl<'a> LinkInputs<'a> {
continue; 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. // Create pointer types for everything we saw above with Private storage class.
// We don't have to deal with OpTypeForwardPointer, because PhysicalStorageBuffer // We don't have to deal with OpTypeForwardPointer, because PhysicalStorageBuffer
// is not valid in slang shaders, and we're only working with Vulkan inputs. // 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 // Create a new private type
let private_pointer_type = let private_pointer_type =
self.vert_builder self.vert_builder
.type_pointer(None, StorageClass::Private, pointee_type); .type_pointer(None, StorageClass::Private, *pointee_type);
// Add it to the mapping // Add it to the mapping
downgraded_pointer_types.insert(pointer_type, private_pointer_type); downgraded_pointer_types.insert(pointer_type, private_pointer_type);
@ -196,7 +220,7 @@ impl<'a> LinkInputs<'a> {
continue; 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. // We should have created one above.
continue; continue;
}; };

View file

@ -829,54 +829,51 @@ mod test {
use crate::reflect::semantics::{Semantic, ShaderSemantics, UniformSemantic, UniqueSemantics}; use crate::reflect::semantics::{Semantic, ShaderSemantics, UniformSemantic, UniqueSemantics};
use librashader_common::map::{FastHashMap, ShortString}; use librashader_common::map::{FastHashMap, ShortString};
use librashader_preprocess::ShaderSource; use librashader_preprocess::ShaderSource;
use spirv_cross::glsl::{CompilerOptions, Version};
use spirv_cross::hlsl::ShaderModel;
use spirv_cross::{glsl, hlsl};
#[test] // #[test]
pub fn test_into() { // pub fn test_into() {
let result = ShaderSource::load("../test/basic.slang").unwrap(); // let result = ShaderSource::load("../test/basic.slang").unwrap();
let mut uniform_semantics: FastHashMap<ShortString, UniformSemantic> = Default::default(); // let mut uniform_semantics: FastHashMap<ShortString, UniformSemantic> = Default::default();
//
for (_index, param) in result.parameters.iter().enumerate() { // for (_index, param) in result.parameters.iter().enumerate() {
uniform_semantics.insert( // uniform_semantics.insert(
param.1.id.clone(), // param.1.id.clone(),
UniformSemantic::Unique(Semantic { // UniformSemantic::Unique(Semantic {
semantics: UniqueSemantics::FloatParameter, // semantics: UniqueSemantics::FloatParameter,
index: (), // index: (),
}), // }),
); // );
} // }
let spirv = Glslang::compile(&result).unwrap(); // let spirv = Glslang::compile(&result).unwrap();
let mut reflect = CrossReflect::<hlsl::Target>::try_from(&spirv).unwrap(); // let mut reflect = CrossReflect::<hlsl::Target>::try_from(&spirv).unwrap();
let shader_reflection = reflect // let shader_reflection = reflect
.reflect( // .reflect(
0, // 0,
&ShaderSemantics { // &ShaderSemantics {
uniform_semantics, // uniform_semantics,
texture_semantics: Default::default(), // texture_semantics: Default::default(),
}, // },
) // )
.unwrap(); // .unwrap();
let mut opts = hlsl::CompilerOptions::default(); // let mut opts = hlsl::CompilerOptions::default();
opts.shader_model = ShaderModel::V3_0; // opts.shader_model = ShaderModel::V3_0;
//
let compiled: ShaderCompilerOutput<String, CrossHlslContext> = // let compiled: ShaderCompilerOutput<String, CrossHlslContext> =
<CrossReflect<hlsl::Target> as CompileShader<HLSL>>::compile( // <CrossReflect<hlsl::Target> as CompileShader<HLSL>>::compile(
reflect, // reflect,
Some(ShaderModel::V3_0), // Some(ShaderModel::V3_0),
) // )
.unwrap(); // .unwrap();
//
println!("{:?}", shader_reflection.meta); // println!("{:?}", shader_reflection.meta);
println!("{}", compiled.fragment); // println!("{}", compiled.fragment);
println!("{}", compiled.vertex); // println!("{}", compiled.vertex);
//
// // eprintln!("{shader_reflection:#?}"); // // // eprintln!("{shader_reflection:#?}");
// eprintln!("{}", compiled.fragment) // // eprintln!("{}", compiled.fragment)
// let mut loader = rspirv::dr::Loader::new(); // // let mut loader = rspirv::dr::Loader::new();
// rspirv::binary::parse_words(spirv.fragment.as_binary(), &mut loader).unwrap(); // // rspirv::binary::parse_words(spirv.fragment.as_binary(), &mut loader).unwrap();
// let module = loader.module(); // // let module = loader.module();
// println!("{:#}", module.disassemble()); // // println!("{:#}", module.disassemble());
} // }
} }

View file

@ -1046,6 +1046,7 @@ impl ReflectShader for NagaReflect {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::front::ShaderInputCompiler;
use crate::reflect::semantics::{Semantic, TextureSemantics, UniformSemantic}; use crate::reflect::semantics::{Semantic, TextureSemantics, UniformSemantic};
use librashader_common::map::FastHashMap; use librashader_common::map::FastHashMap;
use librashader_preprocess::ShaderSource; use librashader_preprocess::ShaderSource;
@ -1053,18 +1054,19 @@ mod test {
// #[test] // #[test]
// pub fn test_into() { // 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 result = ShaderSource::load("../test/slang-shaders/misc/shaders/simple_color_controls.slang").unwrap();
// let compilation = crate::front::GlslangCompilation::try_from(&result).unwrap(); // let compilation = crate::front::Glslang::compile(&result).unwrap();
// //
// let mut loader = rspirv::dr::Loader::new(); // crate::front::n
// rspirv::binary::parse_words(compilation.vertex.as_binary(), &mut loader).unwrap(); // // let mut loader = rspirv::dr::Loader::new();
// let module = loader.module(); // // rspirv::binary::parse_words(compilation.vertex.as_binary(), &mut loader).unwrap();
// // // let module = loader.module();
// let outputs: Vec<&Instruction> = module // //
// .types_global_values // // let outputs: Vec<&Instruction> = module
// .iter() // // .types_global_values
// .filter(|i| i.class.opcode == Op::Variable) // // .iter()
// .collect(); // // .filter(|i| i.class.opcode == Op::Variable)
// // .collect();
// //
// println!("{outputs:#?}"); // println!("{outputs:#?}");
// } // }

View file

@ -165,42 +165,42 @@ mod test {
use bitflags::Flags; use bitflags::Flags;
use librashader_common::map::{FastHashMap, ShortString}; use librashader_common::map::{FastHashMap, ShortString};
use librashader_preprocess::ShaderSource; use librashader_preprocess::ShaderSource;
use spirv_cross::msl; // use spirv_cross::msl;
#[test] // #[test]
pub fn test_into() { // pub fn test_into() {
let result = ShaderSource::load("../test/basic.slang").unwrap(); // let result = ShaderSource::load("../test/basic.slang").unwrap();
//
let mut uniform_semantics: FastHashMap<ShortString, UniformSemantic> = Default::default(); // let mut uniform_semantics: FastHashMap<ShortString, UniformSemantic> = Default::default();
//
for (_index, param) in result.parameters.iter().enumerate() { // for (_index, param) in result.parameters.iter().enumerate() {
uniform_semantics.insert( // uniform_semantics.insert(
param.1.id.clone(), // param.1.id.clone(),
UniformSemantic::Unique(Semantic { // UniformSemantic::Unique(Semantic {
semantics: UniqueSemantics::FloatParameter, // semantics: UniqueSemantics::FloatParameter,
index: (), // index: (),
}), // }),
); // );
} // }
//
let compilation = crate::front::SpirvCompilation::try_from(&result).unwrap(); // let compilation = crate::front::SpirvCompilation::try_from(&result).unwrap();
//
let mut msl = <MSL as FromCompilation<_, Naga>>::from_compilation(compilation).unwrap(); // let mut msl = <MSL as FromCompilation<_, Naga>>::from_compilation(compilation).unwrap();
//
msl.reflect( // msl.reflect(
0, // 0,
&ShaderSemantics { // &ShaderSemantics {
uniform_semantics, // uniform_semantics,
texture_semantics: Default::default(), // texture_semantics: Default::default(),
}, // },
) // )
.expect(""); // .expect("");
//
let compiled = msl.compile(Some(msl::Version::V2_0)).unwrap(); // let compiled = msl.compile(Some(msl::Version::V2_0)).unwrap();
//
println!( // println!(
"{:?}", // "{:?}",
compiled.context.fragment.translation_info.entry_point_names // compiled.context.fragment.translation_info.entry_point_names
); // );
} // }
} }