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]
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<ShortString, UniformSemantic> = Default::default();

View file

@ -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;
};

View file

@ -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<ShortString, UniformSemantic> = 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::<hlsl::Target>::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<String, CrossHlslContext> =
<CrossReflect<hlsl::Target> as CompileShader<HLSL>>::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<ShortString, UniformSemantic> = 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::<hlsl::Target>::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<String, CrossHlslContext> =
// <CrossReflect<hlsl::Target> as CompileShader<HLSL>>::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());
// }
}

View file

@ -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:#?}");
// }

View file

@ -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<ShortString, UniformSemantic> = 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 = <MSL as FromCompilation<_, Naga>>::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<ShortString, UniformSemantic> = 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 = <MSL as FromCompilation<_, Naga>>::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
// );
// }
}