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-preprocess = { path = "../librashader-preprocess", version = "0.1.0-beta.10" }
|
||||||
librashader-presets = { path = "../librashader-presets", 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 }
|
naga = { version = "0.10.0", features = ["glsl-in", "spv-in", "spv-out", "glsl-out", "wgsl-out"], optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = ["dxil"]
|
||||||
unstable-naga = [ "naga" ]
|
unstable-naga = [ "naga" ]
|
||||||
standalone = ["shaderc/build-from-source"]
|
standalone = ["shaderc/build-from-source"]
|
||||||
|
dxil = ["spirv-to-dxil"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[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;
|
pub mod cross;
|
||||||
mod spirv;
|
mod spirv;
|
||||||
pub mod targets;
|
pub mod targets;
|
||||||
|
pub mod dxil;
|
||||||
|
|
||||||
use crate::back::targets::OutputTarget;
|
use crate::back::targets::OutputTarget;
|
||||||
use crate::error::{ShaderCompileError, ShaderReflectError};
|
use crate::error::{ShaderCompileError, ShaderReflectError};
|
||||||
|
|
|
@ -6,11 +6,11 @@ use crate::reflect::cross::GlslReflect;
|
||||||
use crate::reflect::semantics::ShaderSemantics;
|
use crate::reflect::semantics::ShaderSemantics;
|
||||||
use crate::reflect::{ReflectShader, ShaderReflection};
|
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.
|
// rely on GLSL to provide out reflection but we don't actually need the AST.
|
||||||
reflect: GlslReflect,
|
pub(crate) reflect: GlslReflect,
|
||||||
vertex: Vec<u32>,
|
pub(crate) vertex: Vec<u32>,
|
||||||
fragment: Vec<u32>,
|
pub(crate) fragment: Vec<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromCompilation<GlslangCompilation> for SPIRV {
|
impl FromCompilation<GlslangCompilation> for SPIRV {
|
||||||
|
|
|
@ -10,8 +10,13 @@ pub struct GLSL;
|
||||||
pub struct HLSL;
|
pub struct HLSL;
|
||||||
/// Shader compiler target for SPIR-V.
|
/// Shader compiler target for SPIR-V.
|
||||||
pub struct SPIRV;
|
pub struct SPIRV;
|
||||||
/// Shader compiler target for MSL
|
/// Shader compiler target for MSL.
|
||||||
pub struct 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 {
|
impl OutputTarget for GLSL {
|
||||||
type Output = String;
|
type Output = String;
|
||||||
|
|
|
@ -21,6 +21,11 @@ pub enum ShaderCompileError {
|
||||||
/// Error when transpiling from spirv-cross.
|
/// Error when transpiling from spirv-cross.
|
||||||
#[error("cross")]
|
#[error("cross")]
|
||||||
SpirvCrossCompileError(#[from] spirv_cross::ErrorCode),
|
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.
|
/// The error kind encountered when reflecting shader semantics.
|
||||||
|
|
|
@ -153,6 +153,16 @@ pub mod reflect {
|
||||||
|
|
||||||
pub use librashader_reflect::reflect::cross::CompiledProgram;
|
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::semantics::BindingMeta;
|
||||||
|
|
||||||
pub use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
|
pub use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
|
||||||
|
|
Loading…
Reference in a new issue