diff --git a/.idea/src.iml b/.idea/src.iml
index 15bef57..a3a4323 100644
--- a/.idea/src.iml
+++ b/.idea/src.iml
@@ -9,6 +9,7 @@
+
diff --git a/Cargo.lock b/Cargo.lock
index 3f9fde3..5280748 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -439,6 +439,18 @@ dependencies = [
"thiserror",
]
+[[package]]
+name = "librashader-runtime-dx11"
+version = "0.1.0"
+dependencies = [
+ "librashader",
+ "librashader-preprocess",
+ "librashader-presets",
+ "librashader-reflect",
+ "rustc-hash",
+ "spirv_cross",
+]
+
[[package]]
name = "log"
version = "0.4.17"
diff --git a/Cargo.toml b/Cargo.toml
index 1da16fc..eb130fc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,5 +4,6 @@ members = [
"librashader-presets",
"librashader-preprocess",
"librashader-reflect",
+ "librashader-runtime-dx11",
"naga"
]
\ No newline at end of file
diff --git a/librashader-reflect/src/back/cross.rs b/librashader-reflect/src/back/cross.rs
new file mode 100644
index 0000000..ef87031
--- /dev/null
+++ b/librashader-reflect/src/back/cross.rs
@@ -0,0 +1,5 @@
+use crate::back::ShaderCompiler;
+use crate::back::targets::GLSL;
+use crate::error::ShaderCompileError;
+use crate::reflect::ShaderReflection;
+
diff --git a/librashader-reflect/src/back/mod.rs b/librashader-reflect/src/back/mod.rs
new file mode 100644
index 0000000..bdfc268
--- /dev/null
+++ b/librashader-reflect/src/back/mod.rs
@@ -0,0 +1,11 @@
+pub mod targets;
+mod cross;
+
+use std::fmt::Debug;
+pub use targets::ShaderCompiler;
+
+#[derive(Debug)]
+pub struct CompiledShader {
+ pub vertex: T,
+ pub fragment: T,
+}
diff --git a/librashader-reflect/src/back/targets.rs b/librashader-reflect/src/back/targets.rs
new file mode 100644
index 0000000..841b7a3
--- /dev/null
+++ b/librashader-reflect/src/back/targets.rs
@@ -0,0 +1,22 @@
+use crate::back::CompiledShader;
+use crate::error::ShaderCompileError;
+use crate::reflect::ShaderReflection;
+
+pub trait OutputTarget { }
+
+pub struct GLSL;
+pub struct HLSL;
+pub struct SpirV;
+pub struct MSL;
+
+impl OutputTarget for GLSL {}
+impl OutputTarget for HLSL {}
+impl OutputTarget for SpirV {}
+impl OutputTarget for MSL {}
+
+pub trait ShaderCompiler {
+ type Output;
+ type Options;
+
+ fn compile(&mut self, options: &Self::Options, reflection: &ShaderReflection) -> Result, ShaderCompileError>;
+}
diff --git a/librashader-reflect/src/error.rs b/librashader-reflect/src/error.rs
index e4e7295..54d8059 100644
--- a/librashader-reflect/src/error.rs
+++ b/librashader-reflect/src/error.rs
@@ -11,6 +11,9 @@ pub enum ShaderCompileError {
#[error("shaderc init")]
ShaderCInitError,
+
+ #[error("cross")]
+ SpirvCrossCompileError(#[from] spirv_cross::ErrorCode),
}
#[derive(Debug)]
diff --git a/librashader-reflect/src/lib.rs b/librashader-reflect/src/lib.rs
index c27070e..cf915a0 100644
--- a/librashader-reflect/src/lib.rs
+++ b/librashader-reflect/src/lib.rs
@@ -1,5 +1,6 @@
#![feature(let_else)]
-mod error;
-mod front;
-mod reflect;
+pub mod error;
+pub mod front;
+pub mod reflect;
+pub mod back;
diff --git a/librashader-reflect/src/reflect/cross.rs b/librashader-reflect/src/reflect/cross.rs
index 17085f9..ce29476 100644
--- a/librashader-reflect/src/reflect/cross.rs
+++ b/librashader-reflect/src/reflect/cross.rs
@@ -1,17 +1,19 @@
-use crate::error::{SemanticsErrorKind, ShaderReflectError};
+use crate::error::{SemanticsErrorKind, ShaderCompileError, ShaderReflectError};
use crate::front::shaderc::GlslangCompilation;
use crate::reflect::semantics::{
BindingStage, MemberOffset, PushReflection, SemanticMap, ShaderReflection, TextureImage,
TextureSemantics, TextureSizeMeta, TypeInfo, UboReflection, ValidateTypeSemantics,
VariableMeta, VariableSemantics, MAX_BINDINGS_COUNT, MAX_PUSH_BUFFER_SIZE,
};
-use crate::reflect::{ReflectMeta, ReflectOptions, ReflectShader, UniformSemantic};
+use crate::reflect::{ReflectMeta, ReflectSemantics, ReflectShader, UniformSemantic};
use rustc_hash::FxHashMap;
-use spirv_cross::hlsl::{CompilerOptions, ShaderModel};
+use spirv_cross::hlsl::{ShaderModel};
use spirv_cross::spirv::{Ast, Decoration, Module, Resource, ShaderResources, Type};
-use spirv_cross::{hlsl, ErrorCode};
+use spirv_cross::{hlsl, ErrorCode, glsl};
use std::str::FromStr;
+use spirv_cross::glsl::Version;
+use crate::back::{CompiledShader, ShaderCompiler};
pub struct CrossReflect
where
@@ -21,6 +23,7 @@ where
fragment: Ast,
}
+pub type HlslReflect = CrossReflect;
impl ValidateTypeSemantics for VariableSemantics {
fn validate_type(&self, ty: &Type) -> Option {
let (Type::Float { ref array, vecsize, columns } | Type::Int { ref array, vecsize, columns } | Type::UInt { ref array, vecsize, columns }) = *ty else {
@@ -89,7 +92,7 @@ impl TryFrom for CrossReflect {
let mut vertex = Ast::parse(&vertex_module)?;
let mut fragment = Ast::parse(&fragment_module)?;
- let mut options = CompilerOptions::default();
+ let mut options = hlsl::CompilerOptions::default();
options.shader_model = ShaderModel::V5_0;
fragment.set_compiler_options(&options)?;
vertex.set_compiler_options(&options)?;
@@ -98,6 +101,25 @@ impl TryFrom for CrossReflect {
}
}
+impl TryFrom for CrossReflect {
+ type Error = ShaderReflectError;
+
+ fn try_from(value: GlslangCompilation) -> Result {
+ let vertex_module = Module::from_words(value.vertex.as_binary());
+ let fragment_module = Module::from_words(value.fragment.as_binary());
+
+ let mut vertex = Ast::parse(&vertex_module)?;
+ let mut fragment = Ast::parse(&fragment_module)?;
+
+ let mut options = glsl::CompilerOptions::default();
+ options.version = Version::V3_30;
+ fragment.set_compiler_options(&options)?;
+ vertex.set_compiler_options(&options)?;
+
+ Ok(CrossReflect { vertex, fragment })
+ }
+}
+
impl CrossReflect
where
T: spirv_cross::spirv::Target,
@@ -371,7 +393,8 @@ where
fn reflect_buffer_range_metas(
ast: &Ast,
resource: &Resource,
- options: &ReflectOptions,
+ pass_number: u32,
+ semantics: &ReflectSemantics,
meta: &mut ReflectMeta,
offset_type: impl Fn(usize) -> MemberOffset,
blame: SemanticErrorBlame,
@@ -392,7 +415,7 @@ where
_ => return Err(blame.error(SemanticsErrorKind::InvalidResourceType)),
};
- if let Some(parameter) = options.uniform_semantics.get_variable_semantic(&name) {
+ if let Some(parameter) = semantics.uniform_semantics.get_variable_semantic(&name) {
let Some(typeinfo) = parameter.semantics.validate_type(&range_type) else {
return Err(blame.error(SemanticsErrorKind::InvalidTypeForSemantic(name)))
};
@@ -453,15 +476,15 @@ where
}
}
}
- } else if let Some(texture) = options.uniform_semantics.get_texture_semantic(&name) {
+ } else if let Some(texture) = semantics.uniform_semantics.get_texture_semantic(&name) {
let Some(_typeinfo) = texture.semantics.validate_type(&range_type) else {
return Err(blame.error(SemanticsErrorKind::InvalidTypeForSemantic(name)))
};
if let TextureSemantics::PassOutput = texture.semantics {
- if texture.index >= options.pass_number {
+ if texture.index >= pass_number {
return Err(ShaderReflectError::NonCausalFilterChain {
- pass: options.pass_number,
+ pass: pass_number,
target: texture.index,
});
}
@@ -486,7 +509,7 @@ where
texture,
TextureSizeMeta {
offset,
- // todo: fix this.
+ // todo: fix this. to allow both
stage_mask: match blame {
SemanticErrorBlame::Vertex => BindingStage::VERTEX,
SemanticErrorBlame::Fragment => BindingStage::FRAGMENT,
@@ -502,10 +525,18 @@ where
}
fn reflect_ubos(
- &self,
+ &mut self,
vertex_ubo: Option<&Resource>,
fragment_ubo: Option<&Resource>,
) -> Result