2022-11-11 17:44:41 +11:00
|
|
|
use crate::error::ShaderReflectError;
|
2022-10-28 11:39:39 +11:00
|
|
|
use crate::reflect::semantics::{
|
2022-11-11 17:44:41 +11:00
|
|
|
SemanticMap, TextureImage, TextureSemantics, TextureSizeMeta, VariableMeta, VariableSemantics,
|
2022-10-28 11:39:39 +11:00
|
|
|
};
|
2022-10-26 13:13:39 +11:00
|
|
|
use rustc_hash::FxHashMap;
|
2022-11-11 17:44:41 +11:00
|
|
|
use std::str::FromStr;
|
2022-10-24 14:22:26 +11:00
|
|
|
|
2022-11-07 16:25:11 +11:00
|
|
|
pub mod cross;
|
2022-10-23 17:36:41 +11:00
|
|
|
mod naga;
|
2022-10-26 13:13:39 +11:00
|
|
|
mod rspirv;
|
2022-10-27 17:22:44 +11:00
|
|
|
pub mod semantics;
|
2022-10-24 14:22:26 +11:00
|
|
|
|
|
|
|
pub trait ReflectShader {
|
2022-11-11 17:44:41 +11:00
|
|
|
fn reflect(
|
|
|
|
&mut self,
|
|
|
|
pass_number: u32,
|
|
|
|
semantics: &ReflectSemantics,
|
|
|
|
) -> Result<ShaderReflection, ShaderReflectError>;
|
2022-10-24 14:22:26 +11:00
|
|
|
}
|
2022-10-26 13:13:39 +11:00
|
|
|
|
2022-11-09 17:51:10 +11:00
|
|
|
pub trait TextureSemanticMap<T> {
|
|
|
|
fn get_texture_semantic(&self, name: &str) -> Option<SemanticMap<TextureSemantics>>;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait VariableSemanticMap<T> {
|
|
|
|
fn get_variable_semantic(&self, name: &str) -> Option<SemanticMap<VariableSemantics>>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl VariableSemanticMap<UniformSemantic> for FxHashMap<String, UniformSemantic> {
|
|
|
|
fn get_variable_semantic(&self, name: &str) -> Option<SemanticMap<VariableSemantics>> {
|
|
|
|
match self.get(name) {
|
|
|
|
// existing uniforms in the semantic map have priority
|
|
|
|
None => match name {
|
|
|
|
"MVP" => Some(SemanticMap {
|
|
|
|
semantics: VariableSemantics::MVP,
|
|
|
|
index: 0,
|
|
|
|
}),
|
|
|
|
"OutputSize" => Some(SemanticMap {
|
|
|
|
semantics: VariableSemantics::Output,
|
|
|
|
index: 0,
|
|
|
|
}),
|
|
|
|
"FinalViewportSize" => Some(SemanticMap {
|
|
|
|
semantics: VariableSemantics::FinalViewport,
|
|
|
|
index: 0,
|
|
|
|
}),
|
|
|
|
"FrameCount" => Some(SemanticMap {
|
|
|
|
semantics: VariableSemantics::FrameCount,
|
|
|
|
index: 0,
|
|
|
|
}),
|
|
|
|
"FrameDirection" => Some(SemanticMap {
|
|
|
|
semantics: VariableSemantics::FrameDirection,
|
|
|
|
index: 0,
|
|
|
|
}),
|
|
|
|
_ => None,
|
|
|
|
},
|
|
|
|
Some(UniformSemantic::Variable(variable)) => Some(*variable),
|
|
|
|
Some(UniformSemantic::Texture(_)) => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TextureSemanticMap<UniformSemantic> for FxHashMap<String, UniformSemantic> {
|
|
|
|
fn get_texture_semantic(&self, name: &str) -> Option<SemanticMap<TextureSemantics>> {
|
|
|
|
match self.get(name) {
|
|
|
|
None => {
|
|
|
|
if let Some(semantics) = TextureSemantics::TEXTURE_SEMANTICS
|
|
|
|
.iter()
|
|
|
|
.find(|f| name.starts_with(f.size_uniform_name()))
|
|
|
|
{
|
|
|
|
if semantics.is_array() {
|
|
|
|
let index = &name[semantics.size_uniform_name().len()..];
|
|
|
|
let Ok(index) = u32::from_str(index) else {
|
|
|
|
return None;
|
|
|
|
};
|
|
|
|
return Some(SemanticMap {
|
|
|
|
semantics: *semantics,
|
|
|
|
index,
|
|
|
|
});
|
|
|
|
} else if name == semantics.size_uniform_name() {
|
|
|
|
return Some(SemanticMap {
|
|
|
|
semantics: *semantics,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
|
|
|
Some(UniformSemantic::Variable(_)) => None,
|
|
|
|
Some(UniformSemantic::Texture(texture)) => Some(*texture),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TextureSemanticMap<UniformSemantic> for FxHashMap<String, SemanticMap<TextureSemantics>> {
|
|
|
|
fn get_texture_semantic(&self, name: &str) -> Option<SemanticMap<TextureSemantics>> {
|
|
|
|
match self.get(name) {
|
|
|
|
None => {
|
|
|
|
if let Some(semantics) = TextureSemantics::TEXTURE_SEMANTICS
|
|
|
|
.iter()
|
|
|
|
.find(|f| name.starts_with(f.texture_name()))
|
|
|
|
{
|
|
|
|
if semantics.is_array() {
|
|
|
|
let index = &name[semantics.texture_name().len()..];
|
|
|
|
let Ok(index) = u32::from_str(index) else {return None};
|
|
|
|
return Some(SemanticMap {
|
|
|
|
semantics: *semantics,
|
|
|
|
index,
|
|
|
|
});
|
|
|
|
} else if name == semantics.texture_name() {
|
|
|
|
return Some(SemanticMap {
|
|
|
|
semantics: *semantics,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
|
|
|
Some(texture) => Some(*texture),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-26 16:19:04 +11:00
|
|
|
#[derive(Debug)]
|
2022-10-26 13:13:39 +11:00
|
|
|
pub enum UniformSemantic {
|
|
|
|
Variable(SemanticMap<VariableSemantics>),
|
2022-10-27 17:22:44 +11:00
|
|
|
Texture(SemanticMap<TextureSemantics>),
|
2022-10-26 13:13:39 +11:00
|
|
|
}
|
|
|
|
|
2022-10-26 16:19:04 +11:00
|
|
|
#[derive(Debug)]
|
2022-11-07 16:25:11 +11:00
|
|
|
pub struct ReflectSemantics {
|
2022-10-26 13:13:39 +11:00
|
|
|
pub uniform_semantics: FxHashMap<String, UniformSemantic>,
|
2022-10-26 16:19:04 +11:00
|
|
|
pub non_uniform_semantics: FxHashMap<String, SemanticMap<TextureSemantics>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Default)]
|
|
|
|
pub struct ReflectMeta {
|
|
|
|
pub parameter_meta: FxHashMap<u32, VariableMeta>,
|
|
|
|
pub variable_meta: FxHashMap<VariableSemantics, VariableMeta>,
|
2022-10-27 17:22:44 +11:00
|
|
|
pub texture_meta: FxHashMap<SemanticMap<TextureSemantics>, TextureImage>,
|
|
|
|
pub texture_size_meta: FxHashMap<SemanticMap<TextureSemantics>, TextureSizeMeta>,
|
2022-10-26 13:13:39 +11:00
|
|
|
}
|
|
|
|
|
2022-11-11 17:44:41 +11:00
|
|
|
pub use semantics::ShaderReflection;
|