reflect: add API to compile to DXIL

This commit is contained in:
chyyran 2023-02-04 17:53:51 -05:00
parent 5d260e77d5
commit aa87e13201
7 changed files with 106 additions and 6 deletions

View file

@ -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]

View 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: (),
})
}
}

View file

@ -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};

View file

@ -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 {

View file

@ -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;

View file

@ -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.

View file

@ -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};