diff --git a/librashader-reflect/src/back/glsl.rs b/librashader-reflect/src/back/glsl.rs index 8f454c6..c73514b 100644 --- a/librashader-reflect/src/back/glsl.rs +++ b/librashader-reflect/src/back/glsl.rs @@ -9,8 +9,6 @@ use crate::reflect::ReflectShader; pub use spirv_cross::glsl::Version as GlslVersion; use crate::reflect::cross::glsl::GlslReflect; -/// The HLSL shader model version to target. -pub use spirv_cross::hlsl::ShaderModel as HlslShaderModel; /// The context for a GLSL compilation via spirv-cross. pub struct CrossGlslContext { diff --git a/librashader-reflect/src/back/hlsl.rs b/librashader-reflect/src/back/hlsl.rs index da5773b..5b6a2d8 100644 --- a/librashader-reflect/src/back/hlsl.rs +++ b/librashader-reflect/src/back/hlsl.rs @@ -5,7 +5,9 @@ use crate::front::SpirvCompilation; use crate::reflect::cross::hlsl::HlslReflect; use crate::reflect::cross::{CompiledProgram, SpirvCross}; use crate::reflect::ReflectShader; -use spirv_cross::hlsl::ShaderModel as HlslShaderModel; + +/// The HLSL shader model version to target. +pub use spirv_cross::hlsl::ShaderModel as HlslShaderModel; /// The context for a HLSL compilation via spirv-cross. pub struct CrossHlslContext { diff --git a/librashader-reflect/src/back/msl.rs b/librashader-reflect/src/back/msl.rs index 8003c55..35c416d 100644 --- a/librashader-reflect/src/back/msl.rs +++ b/librashader-reflect/src/back/msl.rs @@ -7,6 +7,9 @@ use crate::reflect::cross::{CompiledProgram, SpirvCross}; use crate::reflect::naga::{Naga, NagaReflect}; use crate::reflect::ReflectShader; +/// The HLSL shader model version to target. +pub use spirv_cross::msl::Version as MslVersion; + /// Compiler options for MSL #[derive(Debug, Default, Clone)] pub struct MslNagaCompileOptions { diff --git a/librashader-reflect/src/reflect/cross/msl.rs b/librashader-reflect/src/reflect/cross/msl.rs index dd80654..49a3402 100644 --- a/librashader-reflect/src/reflect/cross/msl.rs +++ b/librashader-reflect/src/reflect/cross/msl.rs @@ -1,9 +1,13 @@ +use std::collections::BTreeMap; +use naga::{Module}; use crate::back::msl::CrossMslContext; use crate::back::targets::MSL; use crate::back::{CompileShader, ShaderCompilerOutput}; use crate::error::ShaderCompileError; use crate::reflect::cross::{CompiledAst, CompiledProgram, CrossReflect}; use spirv_cross::msl; +use spirv_cross::msl::{ResourceBinding, ResourceBindingLocation}; +use spirv_cross::spirv::{Ast, Decoration, ExecutionModel}; pub(crate) type MslReflect = CrossReflect; @@ -16,14 +20,65 @@ impl CompileShader for CrossReflect { options: Self::Options, ) -> Result, ShaderCompileError> { let version = options.unwrap_or(msl::Version::V2_0); - let mut options = spirv_cross::msl::CompilerOptions::default(); - options.version = version; + let mut vert_options = spirv_cross::msl::CompilerOptions::default(); + let mut frag_options = spirv_cross::msl::CompilerOptions::default(); - // This is actually all sorts of broken because there's no way to change bindings - // with the current version of spirv_cross. + vert_options.version = version; + frag_options.version = version; - self.vertex.set_compiler_options(&options)?; - self.fragment.set_compiler_options(&options)?; + fn get_binding(ast: &Ast, stage: ExecutionModel, binding_map: &mut BTreeMap) -> Result<(), ShaderCompileError>{ + let resources = ast.get_shader_resources()?; + for resource in &resources.push_constant_buffers { + let location = ResourceBindingLocation { + stage, + desc_set: u32::MAX, // ResourceBindingPushConstantDescriptorSet + binding: 0, + }; + + let overridden = ResourceBinding { + buffer_id: ast.get_decoration(resource.id, Decoration::Binding)?, + texture_id: 0, + sampler_id: 0, + count: 0, + }; + + binding_map.insert(location, overridden); + } + + for resource in resources.uniform_buffers.iter().chain(resources.sampled_images.iter()) { + let binding = ast.get_decoration(resource.id, Decoration::Binding)?; + let location = ResourceBindingLocation { + stage, + desc_set: ast.get_decoration(resource.id, Decoration::DescriptorSet)?, + binding, + }; + + let overridden = ResourceBinding { + buffer_id: binding, + texture_id: binding, + sampler_id: binding, + count: 0, + }; + + binding_map.insert(location, overridden); + } + + Ok(()) + } + get_binding( + &self.vertex, + ExecutionModel::Vertex, + &mut vert_options.resource_binding_overrides + )?; + + get_binding( + &self.fragment, + ExecutionModel::Fragment, + &mut frag_options.resource_binding_overrides + )?; + + self.vertex.set_compiler_options(&vert_options)?; + self.fragment.set_compiler_options(&frag_options)?; Ok(ShaderCompilerOutput { vertex: self.vertex.compile()?, @@ -37,3 +92,68 @@ impl CompileShader for CrossReflect { }) } } + +#[cfg(test)] +mod test { + use crate::back::targets::{MSL, WGSL}; + use crate::back::{CompileShader, FromCompilation}; + use crate::reflect::naga::{Naga, NagaLoweringOptions}; + use crate::reflect::semantics::{Semantic, ShaderSemantics, UniformSemantic, UniqueSemantics}; + use crate::reflect::ReflectShader; + use librashader_preprocess::ShaderSource; + use rustc_hash::FxHashMap; + use bitflags::Flags; + use spirv_cross::msl; + use crate::reflect::cross::SpirvCross; + + #[test] + pub fn test_into() { + // 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 mut uniform_semantics: FxHashMap = 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.fragment); + + // println!("{}", compiled.fragment); + // 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:#?}"); + } +} \ No newline at end of file diff --git a/librashader-reflect/src/reflect/naga/msl.rs b/librashader-reflect/src/reflect/naga/msl.rs index 6b48c0c..8e51604 100644 --- a/librashader-reflect/src/reflect/naga/msl.rs +++ b/librashader-reflect/src/reflect/naga/msl.rs @@ -1,3 +1,4 @@ +use naga::{Module, ResourceBinding}; use crate::back::targets::MSL; use crate::back::{CompileShader, ShaderCompilerOutput}; use crate::error::ShaderCompileError; @@ -11,6 +12,7 @@ impl CompileShader for NagaReflect { self, options: Self::Options, ) -> Result, ShaderCompileError> { + // https://github.com/libretro/RetroArch/blob/434e94c782af2e4d4277a24b7ed8e5fc54870088/gfx/drivers_shader/slang_process.cpp#L524 todo!() } } diff --git a/librashader-runtime-wgpu/src/filter_chain.rs b/librashader-runtime-wgpu/src/filter_chain.rs index 90a2d6a..3537fca 100644 --- a/librashader-runtime-wgpu/src/filter_chain.rs +++ b/librashader-runtime-wgpu/src/filter_chain.rs @@ -20,7 +20,6 @@ use std::sync::Arc; use crate::buffer::WgpuStagedBuffer; use crate::draw_quad::DrawQuad; use librashader_common::{FilterMode, ImageFormat, Size, Viewport, WrapMode}; -use librashader_reflect::back::wgsl::WgslCompileOptions; use librashader_reflect::reflect::naga::{Naga, NagaLoweringOptions}; use librashader_runtime::framebuffer::FramebufferInit; use librashader_runtime::render_target::RenderTarget; diff --git a/librashader/src/lib.rs b/librashader/src/lib.rs index 934a27b..9968981 100644 --- a/librashader/src/lib.rs +++ b/librashader/src/lib.rs @@ -156,18 +156,26 @@ pub mod reflect { #[cfg(feature = "reflect-cross")] #[doc(cfg(feature = "reflect-cross"))] pub mod cross { + pub use librashader_reflect::reflect::cross::SpirvCross; + /// The version of GLSL to target. /// pub use librashader_reflect::back::glsl::GlslVersion; /// The HLSL Shader Model to target. /// - pub use librashader_reflect::back::glsl::HlslShaderModel; + pub use librashader_reflect::back::hlsl::HlslShaderModel; + + /// The MSL version to target. + /// + pub use librashader_reflect::back::msl::MslVersion; pub use librashader_reflect::back::glsl::CrossGlslContext; pub use librashader_reflect::back::hlsl::CrossHlslContext; + pub use librashader_reflect::back::msl::CrossMslContext; + pub use librashader_reflect::reflect::cross::CompiledAst; pub use librashader_reflect::reflect::cross::CompiledProgram; @@ -188,8 +196,9 @@ pub mod reflect { #[cfg(feature = "reflect-naga")] #[doc(cfg(feature = "reflect-naga"))] pub mod naga { + pub use librashader_reflect::reflect::naga::Naga; pub use librashader_reflect::back::wgsl::NagaWgslContext; - pub use librashader_reflect::back::wgsl::WgslCompileOptions; + pub use librashader_reflect::reflect::naga::NagaLoweringOptions; } pub use librashader_reflect::reflect::semantics::BindingMeta;