reflect: clean up public reflect API a little
This commit is contained in:
parent
993359115e
commit
41f721aa6d
|
@ -11,6 +11,7 @@
|
|||
<sourceFolder url="file://$MODULE_DIR$/naga/tests" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-dx11/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-gl/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/librashader-compiler/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
|
|
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -429,7 +429,6 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"bitflags",
|
||||
"librashader",
|
||||
"librashader-preprocess",
|
||||
"naga",
|
||||
"rspirv",
|
||||
"rspirv-reflect",
|
||||
|
|
|
@ -16,5 +16,5 @@ rustc-hash = "1.1.0"
|
|||
rspirv = "0.11.0+1.5.4"
|
||||
|
||||
rspirv-reflect = { git = "https://github.com/Traverse-Research/rspirv-reflect" }
|
||||
|
||||
[dev-dependencies]
|
||||
librashader-preprocess = { path = "../librashader-preprocess", default-features = false }
|
||||
|
|
|
@ -1,4 +1,39 @@
|
|||
use crate::back::ShaderCompiler;
|
||||
use crate::back::targets::GLSL;
|
||||
use crate::error::ShaderCompileError;
|
||||
use crate::reflect::ShaderReflection;
|
||||
use crate::back::targets::{CompilerBackend, FromCompilation, GLSL, HLSL};
|
||||
use crate::back::CompileShader;
|
||||
use crate::error::{ShaderCompileError, ShaderReflectError};
|
||||
use crate::front::shaderc::GlslangCompilation;
|
||||
use crate::reflect::cross::{GlslReflect, HlslReflect};
|
||||
use crate::reflect::{ReflectShader, ShaderReflection};
|
||||
|
||||
pub type GlVersion = spirv_cross::glsl::Version;
|
||||
impl FromCompilation<GlslangCompilation> for GLSL {
|
||||
type Target = GLSL;
|
||||
type Options = GlVersion;
|
||||
|
||||
fn from_compilation(
|
||||
compile: GlslangCompilation,
|
||||
) -> Result<
|
||||
CompilerBackend<impl CompileShader<Self::Target, Options = Self::Options> + ReflectShader>,
|
||||
ShaderReflectError,
|
||||
> {
|
||||
Ok(CompilerBackend {
|
||||
backend: GlslReflect::try_from(compile)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl FromCompilation<GlslangCompilation> for HLSL {
|
||||
type Target = HLSL;
|
||||
type Options = Option<()>;
|
||||
|
||||
fn from_compilation(
|
||||
compile: GlslangCompilation,
|
||||
) -> Result<
|
||||
CompilerBackend<impl CompileShader<Self::Target, Options = Self::Options> + ReflectShader>,
|
||||
ShaderReflectError,
|
||||
> {
|
||||
Ok(CompilerBackend {
|
||||
backend: HlslReflect::try_from(compile)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
pub mod cross;
|
||||
pub mod targets;
|
||||
mod cross;
|
||||
|
||||
use std::fmt::Debug;
|
||||
pub use targets::ShaderCompiler;
|
||||
use rustc_hash::FxHashMap;
|
||||
pub use targets::CompileShader;
|
||||
use crate::reflect::semantics::{SemanticMap, TextureSemantics};
|
||||
use crate::reflect::UniformSemantic;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CompiledShader<Source, Context = ()> {
|
||||
|
@ -10,4 +13,3 @@ pub struct CompiledShader<Source, Context = ()> {
|
|||
pub fragment: Source,
|
||||
pub context: Context,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,70 +1,129 @@
|
|||
use crate::back::CompiledShader;
|
||||
use crate::error::{ShaderCompileError, ShaderReflectError};
|
||||
use crate::front::shaderc::GlslangCompilation;
|
||||
use crate::reflect::{ReflectSemantics, ReflectShader, ShaderReflection};
|
||||
use crate::reflect::cross::{GlslReflect, HlslReflect};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub trait OutputTarget { }
|
||||
pub trait OutputTarget {
|
||||
type Output;
|
||||
type AdditionalContext;
|
||||
}
|
||||
|
||||
pub struct GLSL(GlslReflect);
|
||||
pub struct HLSL(HlslReflect);
|
||||
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<T: OutputTarget>: ReflectShader {
|
||||
type Output;
|
||||
type Options = Option<()>;
|
||||
type Context = ();
|
||||
|
||||
fn compile(&mut self, options: Self::Options) -> Result<CompiledShader<Self::Output, Self::Context>, ShaderCompileError>;
|
||||
}
|
||||
|
||||
impl ReflectShader for GLSL {
|
||||
fn reflect(&mut self, pass_number: u32, semantics: &ReflectSemantics) -> Result<ShaderReflection, ShaderReflectError> {
|
||||
self.0.reflect(pass_number, semantics)
|
||||
}
|
||||
}
|
||||
|
||||
impl ShaderCompiler<GLSL> for GLSL {
|
||||
impl OutputTarget for GLSL {
|
||||
type Output = String;
|
||||
type Context = Vec<u32>;
|
||||
fn compile(&mut self, options: Self::Options) -> Result<CompiledShader<Self::Output, Self::Context>, ShaderCompileError> {
|
||||
self.0.compile(options)
|
||||
}
|
||||
type AdditionalContext = Vec<u32>;
|
||||
}
|
||||
|
||||
impl TryFrom<GlslangCompilation> for GLSL {
|
||||
type Error = ShaderReflectError;
|
||||
|
||||
fn try_from(value: GlslangCompilation) -> Result<Self, Self::Error> {
|
||||
let value = GlslReflect::try_from(value)?;
|
||||
Ok(Self(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl ReflectShader for HLSL {
|
||||
fn reflect(&mut self, pass_number: u32, semantics: &ReflectSemantics) -> Result<ShaderReflection, ShaderReflectError> {
|
||||
self.0.reflect(pass_number, semantics)
|
||||
}
|
||||
}
|
||||
|
||||
impl ShaderCompiler<HLSL> for HLSL {
|
||||
impl OutputTarget for HLSL {
|
||||
type Output = String;
|
||||
fn compile(&mut self, options: Self::Options) -> Result<CompiledShader<Self::Output, Self::Context>, ShaderCompileError> {
|
||||
self.0.compile(options)
|
||||
type AdditionalContext = ();
|
||||
}
|
||||
impl OutputTarget for SpirV {
|
||||
type Output = Vec<u32>;
|
||||
type AdditionalContext = ();
|
||||
}
|
||||
|
||||
pub struct CompilerBackend<T> {
|
||||
pub(crate) backend: T,
|
||||
}
|
||||
|
||||
pub trait FromCompilation<T> {
|
||||
type Target: OutputTarget;
|
||||
type Options;
|
||||
fn from_compilation(
|
||||
compile: T,
|
||||
) -> Result<CompilerBackend<impl CompileShader<Self::Target> + ReflectShader>, ShaderReflectError>;
|
||||
}
|
||||
|
||||
pub trait CompileShader<T: OutputTarget> {
|
||||
type Options;
|
||||
fn compile(
|
||||
&mut self,
|
||||
options: Self::Options,
|
||||
) -> Result<CompiledShader<T::Output, T::AdditionalContext>, ShaderCompileError>;
|
||||
}
|
||||
|
||||
impl<T> ReflectShader for CompilerBackend<T>
|
||||
where
|
||||
T: ReflectShader,
|
||||
{
|
||||
fn reflect(
|
||||
&mut self,
|
||||
pass_number: u32,
|
||||
semantics: &ReflectSemantics,
|
||||
) -> Result<ShaderReflection, ShaderReflectError> {
|
||||
self.backend.reflect(pass_number, semantics)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<GlslangCompilation> for HLSL {
|
||||
type Error = ShaderReflectError;
|
||||
impl<T, E> CompileShader<E> for CompilerBackend<T>
|
||||
where
|
||||
T: CompileShader<E>,
|
||||
E: OutputTarget,
|
||||
{
|
||||
type Options = T::Options;
|
||||
|
||||
fn try_from(value: GlslangCompilation) -> Result<Self, Self::Error> {
|
||||
let value = HlslReflect::try_from(value)?;
|
||||
Ok(Self(value))
|
||||
fn compile(
|
||||
&mut self,
|
||||
options: Self::Options,
|
||||
) -> Result<CompiledShader<E::Output, E::AdditionalContext>, ShaderCompileError> {
|
||||
self.backend.compile(options)
|
||||
}
|
||||
}
|
||||
|
||||
mod test {
|
||||
use crate::back::targets::{CompilerBackend, FromCompilation, GLSL};
|
||||
use crate::front::shaderc::GlslangCompilation;
|
||||
pub fn huh(value: GlslangCompilation) {
|
||||
let x = GLSL::from_compilation(value).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// impl ReflectShader for GLSL {
|
||||
// fn reflect(&mut self, pass_number: u32, semantics: &ReflectSemantics) -> Result<ShaderReflection, ShaderReflectError> {
|
||||
// self.0.reflect(pass_number, semantics)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl ShaderCompiler<GLSL> for GLSL {
|
||||
// type Output = String;
|
||||
// type Context = Vec<u32>;
|
||||
// fn compile(&mut self, options: Self::Options) -> Result<CompiledShader<Self::Output, Self::Context>, ShaderCompileError> {
|
||||
// self.0.compile(options)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl TryFrom<GlslangCompilation> for GLSL {
|
||||
// type Error = ShaderReflectError;
|
||||
//
|
||||
// fn try_from(value: GlslangCompilation) -> Result<Self, Self::Error> {
|
||||
// let value = GlslReflect::try_from(value)?;
|
||||
// Ok(Self(value))
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl ReflectShader for HLSL {
|
||||
// fn reflect(&mut self, pass_number: u32, semantics: &ReflectSemantics) -> Result<ShaderReflection, ShaderReflectError> {
|
||||
// self.0.reflect(pass_number, semantics)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl ShaderCompiler<HLSL> for HLSL {
|
||||
// type Output = String;
|
||||
// fn compile(&mut self, options: Self::Options) -> Result<CompiledShader<Self::Output, Self::Context>, ShaderCompileError> {
|
||||
// self.0.compile(options)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl TryFrom<GlslangCompilation> for HLSL {
|
||||
// type Error = ShaderReflectError;
|
||||
//
|
||||
// fn try_from(value: GlslangCompilation) -> Result<Self, Self::Error> {
|
||||
// let value = HlslReflect::try_from(value)?;
|
||||
// Ok(Self(value))
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#![feature(let_else)]
|
||||
#![feature(associated_type_defaults)]
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
||||
pub mod back;
|
||||
pub mod error;
|
||||
pub mod front;
|
||||
pub mod reflect;
|
||||
pub mod back;
|
||||
|
|
|
@ -5,15 +5,18 @@ use crate::reflect::semantics::{
|
|||
TextureSemantics, TextureSizeMeta, TypeInfo, UboReflection, ValidateTypeSemantics,
|
||||
VariableMeta, VariableSemantics, MAX_BINDINGS_COUNT, MAX_PUSH_BUFFER_SIZE,
|
||||
};
|
||||
use crate::reflect::{ReflectMeta, ReflectSemantics, ReflectShader, TextureSemanticMap, UniformSemantic, VariableSemanticMap};
|
||||
use crate::reflect::{
|
||||
ReflectMeta, ReflectSemantics, ReflectShader, TextureSemanticMap, UniformSemantic,
|
||||
VariableSemanticMap,
|
||||
};
|
||||
use rustc_hash::FxHashMap;
|
||||
use spirv_cross::hlsl::{ShaderModel};
|
||||
use spirv_cross::hlsl::ShaderModel;
|
||||
use spirv_cross::spirv::{Ast, Decoration, Module, Resource, ShaderResources, Type};
|
||||
use spirv_cross::{hlsl, ErrorCode, glsl};
|
||||
use spirv_cross::{glsl, hlsl, ErrorCode};
|
||||
|
||||
use crate::back::targets::{GLSL, HLSL};
|
||||
use crate::back::{CompileShader, CompiledShader};
|
||||
use std::str::FromStr;
|
||||
use spirv_cross::glsl::{Precision, Version};
|
||||
use crate::back::{CompiledShader, ShaderCompiler};
|
||||
|
||||
pub struct CrossReflect<T>
|
||||
where
|
||||
|
@ -23,8 +26,8 @@ where
|
|||
fragment: Ast<T>,
|
||||
}
|
||||
|
||||
pub type HlslReflect = CrossReflect<hlsl::Target>;
|
||||
pub type GlslReflect = CrossReflect<glsl::Target>;
|
||||
pub(crate) type HlslReflect = CrossReflect<hlsl::Target>;
|
||||
pub(crate) type GlslReflect = CrossReflect<glsl::Target>;
|
||||
|
||||
impl ValidateTypeSemantics<Type> for VariableSemantics {
|
||||
fn validate_type(&self, ty: &Type) -> Option<TypeInfo> {
|
||||
|
@ -84,7 +87,12 @@ impl ValidateTypeSemantics<Type> for TextureSemantics {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryFrom<GlslangCompilation> for CrossReflect<hlsl::Target> {
|
||||
impl<T> TryFrom<GlslangCompilation> for CrossReflect<T>
|
||||
where
|
||||
T: spirv_cross::spirv::Target,
|
||||
Ast<T>: spirv_cross::spirv::Compile<T>,
|
||||
Ast<T>: spirv_cross::spirv::Parse<T>,
|
||||
{
|
||||
type Error = ShaderReflectError;
|
||||
|
||||
fn try_from(value: GlslangCompilation) -> Result<Self, Self::Error> {
|
||||
|
@ -94,30 +102,6 @@ impl TryFrom<GlslangCompilation> for CrossReflect<hlsl::Target> {
|
|||
let mut vertex = Ast::parse(&vertex_module)?;
|
||||
let mut fragment = Ast::parse(&fragment_module)?;
|
||||
|
||||
let mut options = hlsl::CompilerOptions::default();
|
||||
options.shader_model = ShaderModel::V5_0;
|
||||
fragment.set_compiler_options(&options)?;
|
||||
vertex.set_compiler_options(&options)?;
|
||||
|
||||
Ok(CrossReflect { vertex, fragment })
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<GlslangCompilation> for CrossReflect<glsl::Target> {
|
||||
type Error = ShaderReflectError;
|
||||
|
||||
fn try_from(value: GlslangCompilation) -> Result<Self, Self::Error> {
|
||||
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 })
|
||||
}
|
||||
}
|
||||
|
@ -430,11 +414,13 @@ where
|
|||
fragment_ubo: Option<&Resource>,
|
||||
) -> Result<Option<UboReflection>, ShaderReflectError> {
|
||||
if let Some(vertex_ubo) = vertex_ubo {
|
||||
self.vertex.set_decoration(vertex_ubo.id, Decoration::Binding, 0)?;
|
||||
self.vertex
|
||||
.set_decoration(vertex_ubo.id, Decoration::Binding, 0)?;
|
||||
}
|
||||
|
||||
if let Some(fragment_ubo) = fragment_ubo {
|
||||
self.fragment.set_decoration(fragment_ubo.id, Decoration::Binding, 0)?;
|
||||
self.fragment
|
||||
.set_decoration(fragment_ubo.id, Decoration::Binding, 0)?;
|
||||
}
|
||||
|
||||
match (vertex_ubo, fragment_ubo) {
|
||||
|
@ -490,9 +476,7 @@ where
|
|||
return Err(SemanticErrorBlame::Fragment.error(SemanticsErrorKind::UnknownSemantics(texture.name.to_string())))
|
||||
};
|
||||
|
||||
if semantic.semantics == TextureSemantics::PassOutput
|
||||
&& semantic.index >= pass_number
|
||||
{
|
||||
if semantic.semantics == TextureSemantics::PassOutput && semantic.index >= pass_number {
|
||||
return Err(ShaderReflectError::NonCausalFilterChain {
|
||||
pass: pass_number,
|
||||
target: semantic.index,
|
||||
|
@ -542,14 +526,15 @@ where
|
|||
fragment_pcb: Option<&Resource>,
|
||||
) -> Result<Option<PushReflection>, ShaderReflectError> {
|
||||
if let Some(vertex_pcb) = vertex_pcb {
|
||||
self.vertex.set_decoration(vertex_pcb.id, Decoration::Binding, 1)?;
|
||||
self.vertex
|
||||
.set_decoration(vertex_pcb.id, Decoration::Binding, 1)?;
|
||||
}
|
||||
|
||||
if let Some(fragment_pcb) = fragment_pcb {
|
||||
self.fragment.set_decoration(fragment_pcb.id, Decoration::Binding, 1)?;
|
||||
self.fragment
|
||||
.set_decoration(fragment_pcb.id, Decoration::Binding, 1)?;
|
||||
}
|
||||
|
||||
|
||||
match (vertex_pcb, fragment_pcb) {
|
||||
(None, None) => Ok(None),
|
||||
(Some(vertex_push), Some(fragment_push)) => {
|
||||
|
@ -597,7 +582,11 @@ where
|
|||
Ast<T>: spirv_cross::spirv::Compile<T>,
|
||||
Ast<T>: spirv_cross::spirv::Parse<T>,
|
||||
{
|
||||
fn reflect(&mut self, pass_number: u32, semantics: &ReflectSemantics) -> Result<ShaderReflection, ShaderReflectError> {
|
||||
fn reflect(
|
||||
&mut self,
|
||||
pass_number: u32,
|
||||
semantics: &ReflectSemantics,
|
||||
) -> Result<ShaderReflection, ShaderReflectError> {
|
||||
let vertex_res = self.vertex.get_shader_resources()?;
|
||||
let fragment_res = self.fragment.get_shader_resources()?;
|
||||
self.validate(&vertex_res, &fragment_res)?;
|
||||
|
@ -685,19 +674,18 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub type GlslOptions = glsl::CompilerOptions;
|
||||
|
||||
impl ShaderCompiler<crate::back::targets::GLSL> for CrossReflect<glsl::Target> {
|
||||
type Output = String;
|
||||
type Context = Vec<u32>;
|
||||
impl CompileShader<GLSL> for CrossReflect<glsl::Target> {
|
||||
type Options = glsl::Version;
|
||||
|
||||
// todo: compile should consume self
|
||||
fn compile(&mut self, _options: Self::Options) -> Result<CompiledShader<Self::Output, Self::Context>, ShaderCompileError> {
|
||||
let mut options: GlslOptions = Default::default();
|
||||
// todo: allow adjust ogl version
|
||||
options.version = Version::V4_60;
|
||||
options.fragment.default_float_precision = Precision::High;
|
||||
options.fragment.default_int_precision = Precision::High;
|
||||
fn compile(
|
||||
&mut self,
|
||||
version: Self::Options,
|
||||
) -> Result<CompiledShader<String, Vec<u32>>, ShaderCompileError> {
|
||||
let mut options: glsl::CompilerOptions = Default::default();
|
||||
options.version = version;
|
||||
options.fragment.default_float_precision = glsl::Precision::High;
|
||||
options.fragment.default_int_precision = glsl::Precision::High;
|
||||
options.enable_420_pack_extension = false;
|
||||
|
||||
self.vertex.set_compiler_options(&options)?;
|
||||
|
@ -708,33 +696,46 @@ impl ShaderCompiler<crate::back::targets::GLSL> for CrossReflect<glsl::Target> {
|
|||
|
||||
for res in &vertex_resources.stage_inputs {
|
||||
let location = self.vertex.get_decoration(res.id, Decoration::Location)?;
|
||||
self.vertex.set_name(res.id, &format!("RARCH_ATTRIBUTE_{location}"))?;
|
||||
self.vertex
|
||||
.set_name(res.id, &format!("RARCH_ATTRIBUTE_{location}"))?;
|
||||
self.vertex.unset_decoration(res.id, Decoration::Location)?;
|
||||
}
|
||||
for res in &vertex_resources.stage_outputs {
|
||||
let location = self.vertex.get_decoration(res.id, Decoration::Location)?;
|
||||
self.vertex.set_name(res.id, &format!("RARCH_VARYING_{location}"))?;
|
||||
self.vertex
|
||||
.set_name(res.id, &format!("RARCH_VARYING_{location}"))?;
|
||||
self.vertex.unset_decoration(res.id, Decoration::Location)?;
|
||||
}
|
||||
for res in &fragment_resources.stage_inputs {
|
||||
let location = self.fragment.get_decoration(res.id, Decoration::Location)?;
|
||||
self.fragment.set_name(res.id, &format!("RARCH_VARYING_{location}"))?;
|
||||
self.fragment.unset_decoration(res.id, Decoration::Location)?;
|
||||
self.fragment
|
||||
.set_name(res.id, &format!("RARCH_VARYING_{location}"))?;
|
||||
self.fragment
|
||||
.unset_decoration(res.id, Decoration::Location)?;
|
||||
}
|
||||
|
||||
if vertex_resources.push_constant_buffers.len() > 1 {
|
||||
return Err(ShaderCompileError::SpirvCrossCompileError(ErrorCode::CompilationError(String::from("Cannot have more than one push constant buffer"))));
|
||||
return Err(ShaderCompileError::SpirvCrossCompileError(
|
||||
ErrorCode::CompilationError(String::from(
|
||||
"Cannot have more than one push constant buffer",
|
||||
)),
|
||||
));
|
||||
}
|
||||
for res in &vertex_resources.push_constant_buffers {
|
||||
self.vertex.set_name(res.id, "RARCH_PUSH_VERTEX_INSTANCE")?;
|
||||
self.vertex.set_name(res.base_type_id, "RARCH_PUSH_VERTEX")?;
|
||||
self.vertex
|
||||
.set_name(res.base_type_id, "RARCH_PUSH_VERTEX")?;
|
||||
}
|
||||
|
||||
// todo: options
|
||||
let flatten = false;
|
||||
|
||||
if vertex_resources.uniform_buffers.len() > 1 {
|
||||
return Err(ShaderCompileError::SpirvCrossCompileError(ErrorCode::CompilationError(String::from("Cannot have more than one uniform buffer"))));
|
||||
return Err(ShaderCompileError::SpirvCrossCompileError(
|
||||
ErrorCode::CompilationError(String::from(
|
||||
"Cannot have more than one uniform buffer",
|
||||
)),
|
||||
));
|
||||
}
|
||||
for res in &vertex_resources.uniform_buffers {
|
||||
if flatten {
|
||||
|
@ -742,56 +743,74 @@ impl ShaderCompiler<crate::back::targets::GLSL> for CrossReflect<glsl::Target> {
|
|||
}
|
||||
self.vertex.set_name(res.id, "RARCH_UBO_VERTEX_INSTANCE")?;
|
||||
self.vertex.set_name(res.base_type_id, "RARCH_UBO_VERTEX")?;
|
||||
self.vertex.unset_decoration(res.id, Decoration::DescriptorSet)?;
|
||||
self.vertex
|
||||
.unset_decoration(res.id, Decoration::DescriptorSet)?;
|
||||
self.vertex.unset_decoration(res.id, Decoration::Binding)?;
|
||||
|
||||
}
|
||||
|
||||
if fragment_resources.push_constant_buffers.len() > 1 {
|
||||
return Err(ShaderCompileError::SpirvCrossCompileError(ErrorCode::CompilationError(String::from("Cannot have more than one push constant buffer"))));
|
||||
return Err(ShaderCompileError::SpirvCrossCompileError(
|
||||
ErrorCode::CompilationError(String::from(
|
||||
"Cannot have more than one push constant buffer",
|
||||
)),
|
||||
));
|
||||
}
|
||||
for res in &fragment_resources.push_constant_buffers {
|
||||
self.fragment.set_name(res.id, "RARCH_PUSH_FRAGMENT_INSTANCE")?;
|
||||
self.fragment.set_name(res.base_type_id, "RARCH_PUSH_FRAGMENT")?;
|
||||
self.fragment
|
||||
.set_name(res.id, "RARCH_PUSH_FRAGMENT_INSTANCE")?;
|
||||
self.fragment
|
||||
.set_name(res.base_type_id, "RARCH_PUSH_FRAGMENT")?;
|
||||
}
|
||||
|
||||
if fragment_resources.uniform_buffers.len() > 1 {
|
||||
return Err(ShaderCompileError::SpirvCrossCompileError(ErrorCode::CompilationError(String::from("Cannot have more than one uniform buffer"))));
|
||||
return Err(ShaderCompileError::SpirvCrossCompileError(
|
||||
ErrorCode::CompilationError(String::from(
|
||||
"Cannot have more than one uniform buffer",
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
for res in &fragment_resources.uniform_buffers {
|
||||
if flatten {
|
||||
self.fragment.flatten_buffer_block(res.id)?;
|
||||
}
|
||||
self.fragment.set_name(res.id, "RARCH_UBO_FRAGMENT_INSTANCE")?;
|
||||
self.fragment.set_name(res.base_type_id, "RARCH_UBO_FRAGMENT")?;
|
||||
self.fragment.unset_decoration(res.id, Decoration::DescriptorSet)?;
|
||||
self.fragment.unset_decoration(res.id, Decoration::Binding)?;
|
||||
self.fragment
|
||||
.set_name(res.id, "RARCH_UBO_FRAGMENT_INSTANCE")?;
|
||||
self.fragment
|
||||
.set_name(res.base_type_id, "RARCH_UBO_FRAGMENT")?;
|
||||
self.fragment
|
||||
.unset_decoration(res.id, Decoration::DescriptorSet)?;
|
||||
self.fragment
|
||||
.unset_decoration(res.id, Decoration::Binding)?;
|
||||
}
|
||||
|
||||
let mut texture_fixups = Vec::new();
|
||||
for res in &fragment_resources.sampled_images {
|
||||
let binding = self.fragment.get_decoration(res.id, Decoration::Binding)?;
|
||||
self.fragment.set_name(res.id, &format!("RARCH_TEXTURE_{binding}"))?;
|
||||
self.fragment.unset_decoration(res.id, Decoration::DescriptorSet)?;
|
||||
self.fragment.unset_decoration(res.id, Decoration::Binding)?;
|
||||
self.fragment
|
||||
.set_name(res.id, &format!("RARCH_TEXTURE_{binding}"))?;
|
||||
self.fragment
|
||||
.unset_decoration(res.id, Decoration::DescriptorSet)?;
|
||||
self.fragment
|
||||
.unset_decoration(res.id, Decoration::Binding)?;
|
||||
texture_fixups.push(binding);
|
||||
}
|
||||
|
||||
Ok(CompiledShader {
|
||||
vertex: self.vertex.compile()?,
|
||||
fragment: self.fragment.compile()?,
|
||||
context: texture_fixups
|
||||
context: texture_fixups,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub type HlslOptions = hlsl::CompilerOptions;
|
||||
impl CompileShader<HLSL> for CrossReflect<hlsl::Target> {
|
||||
type Options = Option<()>;
|
||||
|
||||
impl ShaderCompiler<crate::back::targets::HLSL> for CrossReflect<hlsl::Target> {
|
||||
type Output = String;
|
||||
|
||||
fn compile(&mut self, _options: Self::Options) -> Result<CompiledShader<Self::Output>, ShaderCompileError> {
|
||||
fn compile(
|
||||
&mut self,
|
||||
_options: Self::Options,
|
||||
) -> Result<CompiledShader<String>, ShaderCompileError> {
|
||||
let mut options = hlsl::CompilerOptions::default();
|
||||
options.shader_model = ShaderModel::V5_0;
|
||||
|
||||
|
@ -801,47 +820,51 @@ impl ShaderCompiler<crate::back::targets::HLSL> for CrossReflect<hlsl::Target> {
|
|||
Ok(CompiledShader {
|
||||
vertex: self.vertex.compile()?,
|
||||
fragment: self.fragment.compile()?,
|
||||
context: ()
|
||||
context: (),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use rustc_hash::FxHashMap;
|
||||
use crate::reflect::cross::CrossReflect;
|
||||
use crate::reflect::{ReflectSemantics, ReflectShader, UniformSemantic};
|
||||
|
||||
use spirv_cross::{glsl, hlsl};
|
||||
use spirv_cross::glsl::{CompilerOptions, Version};
|
||||
use crate::back::ShaderCompiler;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::back::CompileShader;
|
||||
use crate::reflect::semantics::{SemanticMap, VariableSemantics};
|
||||
use spirv_cross::glsl::{CompilerOptions, Version};
|
||||
use spirv_cross::{glsl, hlsl};
|
||||
|
||||
#[test]
|
||||
pub fn test_into() {
|
||||
let result = librashader_preprocess::load_shader_source("../test/basic.slang").unwrap();
|
||||
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
|
||||
|
||||
|
||||
for (index, param) in result.parameters.iter().enumerate() {
|
||||
uniform_semantics.insert(param.id.clone(), UniformSemantic::Variable(SemanticMap {
|
||||
semantics: VariableSemantics::FloatParameter,
|
||||
index: index as u32
|
||||
}));
|
||||
uniform_semantics.insert(
|
||||
param.id.clone(),
|
||||
UniformSemantic::Variable(SemanticMap {
|
||||
semantics: VariableSemantics::FloatParameter,
|
||||
index: index as u32,
|
||||
}),
|
||||
);
|
||||
}
|
||||
let spirv = crate::front::shaderc::compile_spirv(&result).unwrap();
|
||||
let mut reflect = CrossReflect::<glsl::Target>::try_from(spirv).unwrap();
|
||||
let shader_reflection = reflect
|
||||
.reflect(0, &ReflectSemantics {
|
||||
uniform_semantics,
|
||||
non_uniform_semantics: Default::default(),
|
||||
})
|
||||
.reflect(
|
||||
0,
|
||||
&ReflectSemantics {
|
||||
uniform_semantics,
|
||||
non_uniform_semantics: Default::default(),
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
let mut opts = CompilerOptions::default();
|
||||
opts.version = Version::V4_60;
|
||||
opts.enable_420_pack_extension = false;
|
||||
let compiled = reflect.compile(&opts, &shader_reflection)
|
||||
.unwrap();
|
||||
let compiled = reflect.compile(&opts, &shader_reflection).unwrap();
|
||||
// eprintln!("{shader_reflection:#?}");
|
||||
eprintln!("{:#}", compiled.fragment)
|
||||
// let mut loader = rspirv::dr::Loader::new();
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use std::str::FromStr;
|
||||
use crate::error::{ShaderReflectError};
|
||||
use crate::error::ShaderReflectError;
|
||||
use crate::reflect::semantics::{
|
||||
SemanticMap, TextureImage, TextureSemantics, TextureSizeMeta, VariableMeta,
|
||||
VariableSemantics,
|
||||
SemanticMap, TextureImage, TextureSemantics, TextureSizeMeta, VariableMeta, VariableSemantics,
|
||||
};
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub mod cross;
|
||||
mod naga;
|
||||
|
@ -12,7 +11,11 @@ mod rspirv;
|
|||
pub mod semantics;
|
||||
|
||||
pub trait ReflectShader {
|
||||
fn reflect(&mut self, pass_number: u32, semantics: &ReflectSemantics) -> Result<ShaderReflection, ShaderReflectError>;
|
||||
fn reflect(
|
||||
&mut self,
|
||||
pass_number: u32,
|
||||
semantics: &ReflectSemantics,
|
||||
) -> Result<ShaderReflection, ShaderReflectError>;
|
||||
}
|
||||
|
||||
pub trait TextureSemanticMap<T> {
|
||||
|
@ -137,4 +140,4 @@ pub struct ReflectMeta {
|
|||
pub texture_size_meta: FxHashMap<SemanticMap<TextureSemantics>, TextureSizeMeta>,
|
||||
}
|
||||
|
||||
pub use semantics::ShaderReflection;
|
||||
pub use semantics::ShaderReflection;
|
||||
|
|
|
@ -38,9 +38,6 @@ impl TryFrom<GlslangCompilation> for NagaReflect {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
|
||||
|
||||
|
||||
#[test]
|
||||
pub fn test_into() {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
use crate::reflect::ReflectMeta;
|
||||
use bitflags::bitflags;
|
||||
|
||||
|
@ -143,4 +142,3 @@ pub struct ShaderReflection {
|
|||
pub push_constant: Option<PushReflection>,
|
||||
pub meta: ReflectMeta,
|
||||
}
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ use std::path::Path;
|
|||
use rustc_hash::FxHashMap;
|
||||
use librashader::ShaderSource;
|
||||
use librashader_presets::ShaderPassConfig;
|
||||
use librashader_reflect::back::ShaderCompiler;
|
||||
use librashader_reflect::back::targets::HLSL;
|
||||
use librashader_reflect::back::{CompileShader, ShaderCompiler};
|
||||
use librashader_reflect::back::targets::{FromCompilation, HLSL};
|
||||
use librashader_reflect::front::shaderc::GlslangCompilation;
|
||||
use librashader_reflect::reflect::cross::{CrossReflect, HlslOptions, HlslReflect};
|
||||
use librashader_reflect::reflect::cross::{CrossReflect};
|
||||
use librashader_reflect::reflect::{ReflectSemantics, ReflectShader, UniformSemantic};
|
||||
use librashader_reflect::reflect::semantics::{SemanticMap, TextureSemantics, VariableSemantics};
|
||||
|
||||
|
@ -49,13 +49,13 @@ pub fn load_pass_semantics(uniform_semantics: &mut FxHashMap<String, UniformSema
|
|||
|
||||
pub fn load(path: impl AsRef<Path>) -> Result<(), Box<dyn Error>>{
|
||||
let preset = librashader_presets::ShaderPreset::try_parse(path)?;
|
||||
let mut passes: Vec<(&ShaderPassConfig, ShaderSource, HLSL)> = preset.shaders.iter()
|
||||
let mut passes: Vec<(&ShaderPassConfig, ShaderSource, _)> = preset.shaders.iter()
|
||||
.map(|shader| {
|
||||
let source = librashader_preprocess::load_shader_source(&shader.name)
|
||||
.unwrap();
|
||||
let spirv = librashader_reflect::front::shaderc::compile_spirv(&source)
|
||||
.unwrap();
|
||||
let mut reflect = librashader_reflect::back::targets::HLSL::try_from(spirv).unwrap();
|
||||
let mut reflect = HLSL::from_compilation(spirv).unwrap();
|
||||
(shader, source, reflect)
|
||||
}).collect();
|
||||
|
||||
|
|
|
@ -5,10 +5,11 @@ use rustc_hash::FxHashMap;
|
|||
|
||||
use librashader::ShaderSource;
|
||||
use librashader_presets::ShaderPassConfig;
|
||||
use librashader_reflect::back::ShaderCompiler;
|
||||
use librashader_reflect::back::targets::GLSL;
|
||||
use librashader_reflect::back::CompileShader;
|
||||
use librashader_reflect::back::cross::GlVersion;
|
||||
use librashader_reflect::back::targets::{FromCompilation, GLSL};
|
||||
use librashader_reflect::front::shaderc::GlslangCompilation;
|
||||
use librashader_reflect::reflect::cross::{CrossReflect, GlslOptions, GlslReflect, HlslOptions, HlslReflect};
|
||||
use librashader_reflect::reflect::cross::CrossReflect;
|
||||
use librashader_reflect::reflect::{ReflectSemantics, ReflectShader, UniformSemantic};
|
||||
use librashader_reflect::reflect::semantics::{SemanticMap, TextureSemantics, VariableSemantics};
|
||||
use librashader_reflect::reflect::{TextureSemanticMap, VariableSemanticMap};
|
||||
|
@ -50,13 +51,13 @@ pub fn load_pass_semantics(uniform_semantics: &mut FxHashMap<String, UniformSema
|
|||
|
||||
pub fn load(path: impl AsRef<Path>) -> Result<(), Box<dyn Error>>{
|
||||
let preset = librashader_presets::ShaderPreset::try_parse(path)?;
|
||||
let mut passes: Vec<(&ShaderPassConfig, ShaderSource, GLSL)> = preset.shaders.iter()
|
||||
let mut passes: Vec<(&ShaderPassConfig, ShaderSource, _)> = preset.shaders.iter()
|
||||
.map(|shader| {
|
||||
let source = librashader_preprocess::load_shader_source(&shader.name)
|
||||
.unwrap();
|
||||
let spirv = librashader_reflect::front::shaderc::compile_spirv(&source)
|
||||
.unwrap();
|
||||
let mut reflect = librashader_reflect::back::targets::GLSL::try_from(spirv).unwrap();
|
||||
let mut reflect = GLSL::from_compilation(spirv).unwrap();
|
||||
(shader, source, reflect)
|
||||
}).collect();
|
||||
|
||||
|
@ -97,17 +98,17 @@ pub fn load(path: impl AsRef<Path>) -> Result<(), Box<dyn Error>>{
|
|||
.unwrap();
|
||||
|
||||
|
||||
let glsl = reflect.compile(None)
|
||||
let glsl = reflect.compile(GlVersion::V4_60)
|
||||
.unwrap();
|
||||
|
||||
eprintln!("{:#}", glsl.vertex);
|
||||
eprintln!("{:#}", glsl.fragment);
|
||||
|
||||
// shader_gl3: 1375
|
||||
reflection.meta.texture_meta.get(&SemanticMap {
|
||||
semantics: TextureSemantics::PassOutput,
|
||||
index: 0
|
||||
}).unwrap().binding;
|
||||
// reflection.meta.texture_meta.get(&SemanticMap {
|
||||
// semantics: TextureSemantics::PassOutput,
|
||||
// index: 0
|
||||
// }).unwrap().binding;
|
||||
|
||||
compiled.push(glsl);
|
||||
reflections.push(reflection);
|
||||
|
|
Loading…
Reference in a new issue