librashader_reflect/back/
mod.rs1#[cfg(all(target_os = "windows", feature = "dxil"))]
2pub mod dxil;
3pub mod glsl;
4pub mod hlsl;
5pub mod msl;
6pub mod spirv;
7pub mod targets;
8pub mod wgsl;
9
10use crate::back::targets::OutputTarget;
11use crate::error::{ShaderCompileError, ShaderReflectError};
12use crate::reflect::semantics::ShaderSemantics;
13use crate::reflect::{ReflectShader, ShaderReflection};
14use std::fmt::Debug;
15
16#[derive(Debug)]
18pub struct ShaderCompilerOutput<T, Context = ()> {
19 pub vertex: T,
21 pub fragment: T,
23 pub context: Context,
25}
26
27pub trait CompileShader<T: OutputTarget> {
29 type Options;
31 type Context;
33
34 fn compile(
39 self,
40 options: Self::Options,
41 ) -> Result<ShaderCompilerOutput<T::Output, Self::Context>, ShaderCompileError>;
42
43 #[doc(hidden)]
48 fn compile_boxed(
49 self: Box<Self>,
50 options: Self::Options,
51 ) -> Result<ShaderCompilerOutput<T::Output, Self::Context>, ShaderCompileError>;
52}
53
54pub trait CompileReflectShader<T: OutputTarget, C, S>:
60 CompileShader<
61 T,
62 Options = <T as FromCompilation<C, S>>::Options,
63 Context = <T as FromCompilation<C, S>>::Context,
64 > + ReflectShader
65where
66 T: FromCompilation<C, S>,
67{
68}
69
70impl<T, C, O, S> CompileReflectShader<T, C, S> for O
71where
72 T: OutputTarget,
73 T: FromCompilation<C, S>,
74 O: ReflectShader,
75 O: CompileShader<
76 T,
77 Options = <T as FromCompilation<C, S>>::Options,
78 Context = <T as FromCompilation<C, S>>::Context,
79 >,
80{
81}
82
83impl<T, E> CompileShader<E> for CompilerBackend<T>
84where
85 T: CompileShader<E>,
86 E: OutputTarget,
87{
88 type Options = T::Options;
89 type Context = T::Context;
90
91 fn compile(
92 self,
93 options: Self::Options,
94 ) -> Result<ShaderCompilerOutput<E::Output, Self::Context>, ShaderCompileError> {
95 self.backend.compile(options)
96 }
97
98 fn compile_boxed(
99 self: Box<Self>,
100 options: Self::Options,
101 ) -> Result<ShaderCompilerOutput<E::Output, Self::Context>, ShaderCompileError> {
102 self.backend.compile(options)
103 }
104}
105
106pub trait FromCompilation<T, S> {
114 type Target: OutputTarget;
116 type Options;
118 type Context;
120
121 type Output: CompileShader<Self::Target, Context = Self::Context, Options = Self::Options>
123 + ReflectShader;
124
125 fn from_compilation(compile: T) -> Result<CompilerBackend<Self::Output>, ShaderReflectError>;
127}
128
129pub struct CompilerBackend<T> {
131 pub(crate) backend: T,
132}
133
134impl<T> ReflectShader for CompilerBackend<T>
135where
136 T: ReflectShader,
137{
138 fn reflect(
139 &mut self,
140 pass_number: usize,
141 semantics: &ShaderSemantics,
142 ) -> Result<ShaderReflection, ShaderReflectError> {
143 self.backend.reflect(pass_number, semantics)
144 }
145
146 fn validate(&mut self) -> Result<(), ShaderReflectError> {
147 self.backend.validate()
148 }
149}
150
151impl<T: ReflectShader + ?Sized> ReflectShader for Box<T> {
152 fn reflect(
153 &mut self,
154 pass_number: usize,
155 semantics: &ShaderSemantics,
156 ) -> Result<ShaderReflection, ShaderReflectError> {
157 (**self).reflect(pass_number, semantics)
158 }
159
160 fn validate(&mut self) -> Result<(), ShaderReflectError> {
161 (**self).validate()
162 }
163}
164
165impl<O, T> CompileShader<T> for Box<O>
166where
167 O: CompileShader<T> + ?Sized,
168 T: OutputTarget,
169{
170 type Options = O::Options;
171 type Context = O::Context;
172
173 fn compile(
174 self,
175 options: Self::Options,
176 ) -> Result<ShaderCompilerOutput<T::Output, Self::Context>, ShaderCompileError> {
177 O::compile_boxed(self, options)
178 }
179
180 fn compile_boxed(
181 self: Box<Self>,
182 options: Self::Options,
183 ) -> Result<ShaderCompilerOutput<T::Output, Self::Context>, ShaderCompileError> {
184 self.compile(options)
185 }
186}
187
188#[cfg(test)]
189mod test {
190 use crate::front::{Glslang, ShaderInputCompiler};
191 use librashader_preprocess::ShaderSource;
192
193 pub fn test() {
194 let result = ShaderSource::load("../test/basic.slang").unwrap();
195 let _cross = Glslang::compile(&result).unwrap();
196 }
197}