pub mod cross; #[cfg(all(target_os = "windows", feature = "dxil"))] pub mod dxil; mod msl; mod spirv; pub mod targets; pub mod wgsl; use crate::back::targets::OutputTarget; use crate::error::{ShaderCompileError, ShaderReflectError}; use crate::reflect::semantics::ShaderSemantics; use crate::reflect::{ReflectShader, ShaderReflection}; use std::fmt::Debug; /// The output of the shader compiler. #[derive(Debug)] pub struct ShaderCompilerOutput { /// The output for the vertex shader. pub vertex: T, /// The output for the fragment shader. pub fragment: T, /// Additional context provided by the shader compiler. pub context: Context, } /// A trait for objects that can be compiled into a shader. pub trait CompileShader { /// Options provided to the compiler. type Options; /// Additional context returned by the compiler after compilation. type Context; /// Consume the object and return the compiled output of the shader. fn compile( self, options: Self::Options, ) -> Result, ShaderCompileError>; } /// Marker trait for combinations of targets and compilations that can be reflected and compiled /// successfully. /// /// This trait is automatically implemented for reflected outputs that have [`FromCompilation`](crate::back::FromCompilation) implement /// for a given target that also implement [`CompileShader`](crate::back::CompileShader) for that target. pub trait CompileReflectShader: CompileShader< T, Options = >::Options, Context = >::Context, > + ReflectShader where T: FromCompilation, { } impl CompileReflectShader for O where T: OutputTarget, T: FromCompilation, O: ReflectShader, O: CompileShader< T, Options = >::Options, Context = >::Context, >, { } impl CompileShader for CompilerBackend where T: CompileShader, E: OutputTarget, { type Options = T::Options; type Context = T::Context; fn compile( self, options: Self::Options, ) -> Result, ShaderCompileError> { self.backend.compile(options) } } /// A trait for reflectable compilations that can be transformed /// into an object ready for reflection or compilation. /// /// `T` is the compiled reflectable form of the shader. /// `S` is the semantics under which the shader is reflected. /// /// librashader currently supports two semantics, [`SpirvCross`](crate::reflect::cross::SpirvCross) pub trait FromCompilation { /// The target that the transformed object is expected to compile for. type Target: OutputTarget; /// Options provided to the compiler. type Options; /// Additional context returned by the compiler after compilation. type Context; /// The output type after conversion. type Output: CompileShader + ReflectShader; /// Tries to convert the input object into an object ready for compilation. fn from_compilation(compile: T) -> Result, ShaderReflectError>; } /// A wrapper for a compiler backend. pub struct CompilerBackend { pub(crate) backend: T, } impl ReflectShader for CompilerBackend where T: ReflectShader, { fn reflect( &mut self, pass_number: usize, semantics: &ShaderSemantics, ) -> Result { self.backend.reflect(pass_number, semantics) } } #[cfg(test)] mod test { use crate::front::{Glslang, ShaderInputCompiler, SpirvCompilation}; use librashader_preprocess::ShaderSource; pub fn test() { let result = ShaderSource::load("../test/basic.slang").unwrap(); let _cross = Glslang::compile(&result).unwrap(); } }