use crate::back::spirv::WriteSpirV; use crate::back::{CompileShader, CompilerBackend, FromCompilation, ShaderCompilerOutput}; pub use spirv_to_dxil::DxilObject; pub use spirv_to_dxil::ShaderModel; use spirv_to_dxil::{ PushConstantBufferConfig, RuntimeConfig, RuntimeDataBufferConfig, ShaderStage, ValidatorVersion, }; use crate::back::targets::{OutputTarget, DXIL}; use crate::error::{ShaderCompileError, ShaderReflectError}; use crate::front::GlslangCompilation; use crate::reflect::cross::GlslReflect; use crate::reflect::ReflectShader; impl OutputTarget for DXIL { type Output = DxilObject; } impl FromCompilation for DXIL { type Target = DXIL; type Options = Option; type Context = (); type Output = impl CompileShader + ReflectShader; fn from_compilation( compile: GlslangCompilation, ) -> Result, ShaderReflectError> { let reflect = GlslReflect::try_from(&compile)?; let vertex = compile.vertex; let fragment = compile.fragment; Ok(CompilerBackend { // we can just reuse WriteSpirV as the backend. backend: WriteSpirV { reflect, vertex, fragment, }, }) } } impl CompileShader for WriteSpirV { type Options = Option; type Context = (); fn compile( self, options: Self::Options, ) -> Result, ShaderCompileError> { let sm = options.unwrap_or(ShaderModel::ShaderModel6_0); let config = RuntimeConfig { runtime_data_cbv: RuntimeDataBufferConfig { register_space: 0, base_shader_register: u32::MAX, }, push_constant_cbv: PushConstantBufferConfig { register_space: 0, base_shader_register: 1, }, shader_model_max: sm, ..RuntimeConfig::default() }; // todo: do we want to allow other entry point names? let vertex = spirv_to_dxil::spirv_to_dxil( &self.vertex, None, "main", ShaderStage::Vertex, ValidatorVersion::None, &config, ) .map_err(ShaderCompileError::SpirvToDxilCompileError)?; let fragment = spirv_to_dxil::spirv_to_dxil( &self.fragment, None, "main", ShaderStage::Fragment, ValidatorVersion::None, &config, ) .map_err(ShaderCompileError::SpirvToDxilCompileError)?; Ok(ShaderCompilerOutput { vertex, fragment, context: (), }) } }