librashader/librashader-reflect/src/reflect/mod.rs

140 lines
5.1 KiB
Rust
Raw Normal View History

use std::str::FromStr;
2022-11-01 11:29:25 +11:00
use crate::error::{ShaderReflectError};
2022-10-28 11:39:39 +11:00
use crate::reflect::semantics::{
2022-11-07 16:25:11 +11:00
SemanticMap, TextureImage, TextureSemantics, TextureSizeMeta, VariableMeta,
2022-10-28 11:39:39 +11:00
VariableSemantics,
};
use rustc_hash::FxHashMap;
2022-11-07 16:25:11 +11:00
pub mod cross;
2022-10-23 17:36:41 +11:00
mod naga;
mod rspirv;
2022-10-27 17:22:44 +11:00
pub mod semantics;
pub trait ReflectShader {
2022-11-07 16:25:11 +11:00
fn reflect(&mut self, pass_number: u32, semantics: &ReflectSemantics) -> Result<ShaderReflection, ShaderReflectError>;
}
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),
}
}
}
#[derive(Debug)]
pub enum UniformSemantic {
Variable(SemanticMap<VariableSemantics>),
2022-10-27 17:22:44 +11:00
Texture(SemanticMap<TextureSemantics>),
}
#[derive(Debug)]
2022-11-07 16:25:11 +11:00
pub struct ReflectSemantics {
pub uniform_semantics: FxHashMap<String, UniformSemantic>,
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-11-07 16:25:11 +11:00
pub use semantics::ShaderReflection;