2023-02-06 08:17:23 +11:00
|
|
|
use crate::back::spirv::WriteSpirV;
|
|
|
|
use crate::back::{CompileShader, CompilerBackend, FromCompilation, ShaderCompilerOutput};
|
2023-02-05 09:53:51 +11:00
|
|
|
pub use spirv_to_dxil::DxilObject;
|
|
|
|
pub use spirv_to_dxil::ShaderModel;
|
2023-02-07 13:56:30 +11:00
|
|
|
use spirv_to_dxil::{
|
|
|
|
PushConstantBufferConfig, RuntimeConfig, RuntimeDataBufferConfig, ShaderStage, ValidatorVersion,
|
|
|
|
};
|
2023-02-05 09:53:51 +11:00
|
|
|
|
2023-02-06 08:17:23 +11:00
|
|
|
use crate::back::targets::{OutputTarget, DXIL};
|
2023-02-05 09:53:51 +11:00
|
|
|
use crate::error::{ShaderCompileError, ShaderReflectError};
|
2024-02-11 09:47:05 +11:00
|
|
|
use crate::front::SpirvCompilation;
|
2024-02-11 12:46:35 +11:00
|
|
|
use crate::reflect::cross::{GlslReflect, SpirvCross};
|
|
|
|
use crate::reflect::ReflectShader;
|
2023-02-05 09:53:51 +11:00
|
|
|
|
|
|
|
impl OutputTarget for DXIL {
|
|
|
|
type Output = DxilObject;
|
|
|
|
}
|
|
|
|
|
2024-02-11 12:46:35 +11:00
|
|
|
impl FromCompilation<SpirvCompilation, SpirvCross<DXIL>> for DXIL {
|
2023-02-05 09:53:51 +11:00
|
|
|
type Target = DXIL;
|
|
|
|
type Options = Option<ShaderModel>;
|
|
|
|
type Context = ();
|
|
|
|
type Output = impl CompileShader<Self::Target, Options = Self::Options, Context = Self::Context>
|
2023-02-06 08:17:23 +11:00
|
|
|
+ ReflectShader;
|
2023-02-05 09:53:51 +11:00
|
|
|
|
|
|
|
fn from_compilation(
|
2024-02-11 09:47:05 +11:00
|
|
|
compile: SpirvCompilation,
|
2023-02-05 09:53:51 +11:00
|
|
|
) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> {
|
2024-02-11 12:46:35 +11:00
|
|
|
let reflect = GlslReflect::try_from(&compile)?;
|
2023-02-06 11:48:24 +11:00
|
|
|
let vertex = compile.vertex;
|
|
|
|
let fragment = compile.fragment;
|
2023-02-05 09:53:51 +11:00
|
|
|
Ok(CompilerBackend {
|
|
|
|
// we can just reuse WriteSpirV as the backend.
|
|
|
|
backend: WriteSpirV {
|
|
|
|
reflect,
|
|
|
|
vertex,
|
|
|
|
fragment,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CompileShader<DXIL> for WriteSpirV {
|
|
|
|
type Options = Option<ShaderModel>;
|
|
|
|
type Context = ();
|
|
|
|
|
|
|
|
fn compile(
|
|
|
|
self,
|
|
|
|
options: Self::Options,
|
|
|
|
) -> Result<ShaderCompilerOutput<DxilObject, Self::Context>, ShaderCompileError> {
|
|
|
|
let sm = options.unwrap_or(ShaderModel::ShaderModel6_0);
|
|
|
|
|
2023-02-05 16:55:46 +11:00
|
|
|
let config = RuntimeConfig {
|
2023-02-07 11:22:53 +11:00
|
|
|
runtime_data_cbv: RuntimeDataBufferConfig {
|
2023-02-05 16:55:46 +11:00
|
|
|
register_space: 0,
|
|
|
|
base_shader_register: u32::MAX,
|
|
|
|
},
|
2023-02-07 11:22:53 +11:00
|
|
|
push_constant_cbv: PushConstantBufferConfig {
|
2023-02-05 16:55:46 +11:00
|
|
|
register_space: 0,
|
|
|
|
base_shader_register: 1,
|
|
|
|
},
|
2023-07-20 15:13:05 +10:00
|
|
|
shader_model_max: sm,
|
2023-02-05 16:55:46 +11:00
|
|
|
..RuntimeConfig::default()
|
|
|
|
};
|
|
|
|
|
2023-02-05 09:53:51 +11:00
|
|
|
// todo: do we want to allow other entry point names?
|
2023-02-06 08:17:23 +11:00
|
|
|
let vertex = spirv_to_dxil::spirv_to_dxil(
|
|
|
|
&self.vertex,
|
|
|
|
None,
|
|
|
|
"main",
|
|
|
|
ShaderStage::Vertex,
|
|
|
|
ValidatorVersion::None,
|
2023-02-07 11:22:53 +11:00
|
|
|
&config,
|
2023-02-06 08:17:23 +11:00
|
|
|
)
|
2023-02-06 10:34:30 +11:00
|
|
|
.map_err(ShaderCompileError::SpirvToDxilCompileError)?;
|
2023-02-05 09:53:51 +11:00
|
|
|
|
2023-02-06 08:17:23 +11:00
|
|
|
let fragment = spirv_to_dxil::spirv_to_dxil(
|
|
|
|
&self.fragment,
|
|
|
|
None,
|
|
|
|
"main",
|
|
|
|
ShaderStage::Fragment,
|
|
|
|
ValidatorVersion::None,
|
2023-02-07 11:22:53 +11:00
|
|
|
&config,
|
2023-02-06 08:17:23 +11:00
|
|
|
)
|
2023-02-06 10:34:30 +11:00
|
|
|
.map_err(ShaderCompileError::SpirvToDxilCompileError)?;
|
2023-02-05 09:53:51 +11:00
|
|
|
|
|
|
|
Ok(ShaderCompilerOutput {
|
|
|
|
vertex,
|
|
|
|
fragment,
|
|
|
|
context: (),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|