reflect: add API to compile to DXIL
This commit is contained in:
parent
5d260e77d5
commit
aa87e13201
|
@ -23,11 +23,13 @@ librashader-common = { path = "../librashader-common", version = "0.1.0-beta.10"
|
|||
librashader-preprocess = { path = "../librashader-preprocess", version = "0.1.0-beta.10" }
|
||||
librashader-presets = { path = "../librashader-presets", version = "0.1.0-beta.10" }
|
||||
|
||||
spirv-to-dxil = { version = "0.2", optional = true }
|
||||
naga = { version = "0.10.0", features = ["glsl-in", "spv-in", "spv-out", "glsl-out", "wgsl-out"], optional = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
default = ["dxil"]
|
||||
unstable-naga = [ "naga" ]
|
||||
standalone = ["shaderc/build-from-source"]
|
||||
dxil = ["spirv-to-dxil"]
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
77
librashader-reflect/src/back/dxil.rs
Normal file
77
librashader-reflect/src/back/dxil.rs
Normal file
|
@ -0,0 +1,77 @@
|
|||
pub use spirv_to_dxil::DxilObject;
|
||||
pub use spirv_to_dxil::ShaderModel;
|
||||
use spirv_to_dxil::{ShaderStage, ValidatorVersion};
|
||||
use crate::back::{CompilerBackend, CompileShader, FromCompilation, ShaderCompilerOutput};
|
||||
use crate::back::spirv::WriteSpirV;
|
||||
|
||||
use crate::back::targets::{DXIL, OutputTarget};
|
||||
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<GlslangCompilation> for DXIL {
|
||||
type Target = DXIL;
|
||||
type Options = Option<ShaderModel>;
|
||||
type Context = ();
|
||||
type Output = impl CompileShader<Self::Target, Options = Self::Options, Context = Self::Context>
|
||||
+ ReflectShader;
|
||||
|
||||
fn from_compilation(
|
||||
compile: GlslangCompilation,
|
||||
) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> {
|
||||
let vertex = compile.vertex.as_binary().to_vec();
|
||||
let fragment = compile.fragment.as_binary().to_vec();
|
||||
let reflect = GlslReflect::try_from(compile)?;
|
||||
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);
|
||||
|
||||
// todo: do we want to allow other entry point names?
|
||||
let vertex =
|
||||
spirv_to_dxil::spirv_to_dxil(&self.vertex,
|
||||
None, "main",
|
||||
ShaderStage::Vertex,
|
||||
sm,
|
||||
ValidatorVersion::None,
|
||||
Default::default())
|
||||
.map_err(|s| ShaderCompileError::SpirvToDxilCompileError(s))?;
|
||||
|
||||
|
||||
let fragment =
|
||||
spirv_to_dxil::spirv_to_dxil(&self.fragment,
|
||||
None, "main",
|
||||
ShaderStage::Fragment,
|
||||
ShaderModel::ShaderModel6_0,
|
||||
ValidatorVersion::None,
|
||||
Default::default())
|
||||
.map_err(|s| ShaderCompileError::SpirvToDxilCompileError(s))?;
|
||||
|
||||
Ok(ShaderCompilerOutput {
|
||||
vertex,
|
||||
fragment,
|
||||
context: (),
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
pub mod cross;
|
||||
mod spirv;
|
||||
pub mod targets;
|
||||
pub mod dxil;
|
||||
|
||||
use crate::back::targets::OutputTarget;
|
||||
use crate::error::{ShaderCompileError, ShaderReflectError};
|
||||
|
|
|
@ -6,11 +6,11 @@ use crate::reflect::cross::GlslReflect;
|
|||
use crate::reflect::semantics::ShaderSemantics;
|
||||
use crate::reflect::{ReflectShader, ShaderReflection};
|
||||
|
||||
struct WriteSpirV {
|
||||
pub(crate) struct WriteSpirV {
|
||||
// rely on GLSL to provide out reflection but we don't actually need the AST.
|
||||
reflect: GlslReflect,
|
||||
vertex: Vec<u32>,
|
||||
fragment: Vec<u32>,
|
||||
pub(crate) reflect: GlslReflect,
|
||||
pub(crate) vertex: Vec<u32>,
|
||||
pub(crate) fragment: Vec<u32>,
|
||||
}
|
||||
|
||||
impl FromCompilation<GlslangCompilation> for SPIRV {
|
||||
|
|
|
@ -10,8 +10,13 @@ pub struct GLSL;
|
|||
pub struct HLSL;
|
||||
/// Shader compiler target for SPIR-V.
|
||||
pub struct SPIRV;
|
||||
/// Shader compiler target for MSL
|
||||
/// Shader compiler target for MSL.
|
||||
pub struct MSL;
|
||||
/// Shader compiler target for DXIL.
|
||||
///
|
||||
/// The resulting DXIL object is always unvalidated and
|
||||
/// must be validated using platform APIs before usage.
|
||||
pub struct DXIL;
|
||||
|
||||
impl OutputTarget for GLSL {
|
||||
type Output = String;
|
||||
|
|
|
@ -21,6 +21,11 @@ pub enum ShaderCompileError {
|
|||
/// Error when transpiling from spirv-cross.
|
||||
#[error("cross")]
|
||||
SpirvCrossCompileError(#[from] spirv_cross::ErrorCode),
|
||||
|
||||
/// Error when transpiling from spirv-to-dxil
|
||||
#[cfg(feature = "dxil")]
|
||||
#[error("spirv-to-dxil")]
|
||||
SpirvToDxilCompileError(String),
|
||||
}
|
||||
|
||||
/// The error kind encountered when reflecting shader semantics.
|
||||
|
|
|
@ -153,6 +153,16 @@ pub mod reflect {
|
|||
|
||||
pub use librashader_reflect::reflect::cross::CompiledProgram;
|
||||
}
|
||||
|
||||
/// DXIL reflection via spirv-to-dxil.
|
||||
pub mod dxil {
|
||||
/// The maximum shader model to use when compiling the DXIL blob.
|
||||
pub use librashader_reflect::back::dxil::ShaderModel;
|
||||
|
||||
/// A compiled DXIL artifact.
|
||||
pub use librashader_reflect::back::dxil::DxilObject;
|
||||
}
|
||||
|
||||
pub use librashader_reflect::reflect::semantics::BindingMeta;
|
||||
|
||||
pub use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
|
||||
|
|
Loading…
Reference in a new issue