2022-10-26 16:19:04 +11:00
|
|
|
use crate::reflect::ReflectMeta;
|
2022-10-27 17:22:44 +11:00
|
|
|
use bitflags::bitflags;
|
2022-10-24 14:22:26 +11:00
|
|
|
|
|
|
|
pub const BASE_SEMANTICS_COUNT: usize = 5;
|
|
|
|
pub const MAX_BINDINGS_COUNT: u32 = 16;
|
2022-10-26 13:13:39 +11:00
|
|
|
pub const MAX_PUSH_BUFFER_SIZE: u32 = 128;
|
2022-10-24 14:22:26 +11:00
|
|
|
|
2022-11-20 10:48:54 +11:00
|
|
|
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Hash)]
|
|
|
|
pub enum UniformType {
|
|
|
|
MVP,
|
|
|
|
Size,
|
|
|
|
Unsigned,
|
|
|
|
Signed,
|
|
|
|
Float
|
|
|
|
}
|
|
|
|
|
2022-10-26 16:19:04 +11:00
|
|
|
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Hash)]
|
2022-10-24 14:22:26 +11:00
|
|
|
#[repr(i32)]
|
|
|
|
pub enum VariableSemantics {
|
|
|
|
// mat4, MVP
|
|
|
|
MVP = 0,
|
|
|
|
// vec4, viewport size of current pass
|
|
|
|
Output = 1,
|
|
|
|
// vec4, viewport size of final pass
|
|
|
|
FinalViewport = 2,
|
|
|
|
// uint, frame count with modulo
|
|
|
|
FrameCount = 3,
|
|
|
|
// int, frame direction
|
|
|
|
FrameDirection = 4,
|
|
|
|
// float, user defined parameter, array
|
|
|
|
FloatParameter = 5,
|
|
|
|
}
|
|
|
|
|
2022-11-14 17:49:51 +11:00
|
|
|
impl VariableSemantics {
|
|
|
|
pub const fn semantics(self) -> SemanticMap<VariableSemantics, ()> {
|
|
|
|
SemanticMap {
|
|
|
|
semantics: self,
|
|
|
|
index: ()
|
|
|
|
}
|
|
|
|
}
|
2022-11-20 10:48:54 +11:00
|
|
|
|
|
|
|
pub const fn binding_type(&self) -> UniformType {
|
|
|
|
match self {
|
|
|
|
VariableSemantics::MVP => UniformType::MVP,
|
|
|
|
VariableSemantics::Output => UniformType::Size,
|
|
|
|
VariableSemantics::FinalViewport => UniformType::Size,
|
|
|
|
VariableSemantics::FrameCount => UniformType::Unsigned,
|
|
|
|
VariableSemantics::FrameDirection => UniformType::Signed,
|
|
|
|
VariableSemantics::FloatParameter => UniformType::Float
|
|
|
|
}
|
|
|
|
}
|
2022-11-14 17:49:51 +11:00
|
|
|
}
|
|
|
|
|
2022-10-26 16:19:04 +11:00
|
|
|
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Hash)]
|
2022-10-24 14:22:26 +11:00
|
|
|
#[repr(i32)]
|
|
|
|
pub enum TextureSemantics {
|
|
|
|
Original = 0,
|
|
|
|
Source = 1,
|
|
|
|
OriginalHistory = 2,
|
|
|
|
PassOutput = 3,
|
|
|
|
PassFeedback = 4,
|
|
|
|
User = 5,
|
|
|
|
}
|
|
|
|
|
2022-10-27 17:22:44 +11:00
|
|
|
impl TextureSemantics {
|
2022-11-21 18:13:10 +11:00
|
|
|
pub(crate) const TEXTURE_SEMANTICS: [TextureSemantics; 6] = [
|
2022-10-27 17:22:44 +11:00
|
|
|
TextureSemantics::Source,
|
2022-11-21 18:13:10 +11:00
|
|
|
// originalhistory needs to come first, otherwise
|
|
|
|
// the name lookup implementation will prioritize Original
|
|
|
|
// when reflecting semantics.
|
2022-10-27 17:22:44 +11:00
|
|
|
TextureSemantics::OriginalHistory,
|
2022-11-21 18:13:10 +11:00
|
|
|
TextureSemantics::Original,
|
2022-10-27 17:22:44 +11:00
|
|
|
TextureSemantics::PassOutput,
|
|
|
|
TextureSemantics::PassFeedback,
|
|
|
|
TextureSemantics::User,
|
|
|
|
];
|
|
|
|
|
|
|
|
pub fn size_uniform_name(&self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
TextureSemantics::Original => "OriginalSize",
|
|
|
|
TextureSemantics::Source => "SourceSize",
|
|
|
|
TextureSemantics::OriginalHistory => "OriginalHistorySize",
|
|
|
|
TextureSemantics::PassOutput => "PassOutputSize",
|
|
|
|
TextureSemantics::PassFeedback => "PassFeedbackSize",
|
|
|
|
TextureSemantics::User => "UserSize",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn texture_name(&self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
TextureSemantics::Original => "Original",
|
|
|
|
TextureSemantics::Source => "Source",
|
|
|
|
TextureSemantics::OriginalHistory => "OriginalHistory",
|
|
|
|
TextureSemantics::PassOutput => "PassOutput",
|
|
|
|
TextureSemantics::PassFeedback => "PassFeedback",
|
|
|
|
TextureSemantics::User => "User",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_array(&self) -> bool {
|
|
|
|
!matches!(self, TextureSemantics::Original | TextureSemantics::Source)
|
|
|
|
}
|
2022-11-14 17:49:51 +11:00
|
|
|
|
2022-11-20 10:48:54 +11:00
|
|
|
pub const fn semantics(self, index: usize) -> SemanticMap<TextureSemantics> {
|
2022-11-14 17:49:51 +11:00
|
|
|
SemanticMap {
|
|
|
|
semantics: self,
|
|
|
|
index
|
|
|
|
}
|
|
|
|
}
|
2022-10-27 17:22:44 +11:00
|
|
|
}
|
|
|
|
|
2022-10-26 16:19:04 +11:00
|
|
|
pub struct TypeInfo {
|
|
|
|
pub size: u32,
|
|
|
|
pub columns: u32,
|
|
|
|
}
|
|
|
|
pub trait ValidateTypeSemantics<T> {
|
|
|
|
fn validate_type(&self, ty: &T) -> Option<TypeInfo>;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
2022-11-20 10:48:54 +11:00
|
|
|
pub struct SemanticMap<T, I=usize> {
|
2022-11-07 16:25:11 +11:00
|
|
|
pub semantics: T,
|
2022-11-13 18:05:49 +11:00
|
|
|
pub index: I,
|
2022-10-26 13:13:39 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
bitflags! {
|
|
|
|
pub struct BindingStage: u8 {
|
|
|
|
const NONE = 0b00000000;
|
|
|
|
const VERTEX = 0b00000001;
|
|
|
|
const FRAGMENT = 0b00000010;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BindingStage {
|
|
|
|
pub fn clear(&mut self) {
|
|
|
|
self.bits = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-26 16:19:04 +11:00
|
|
|
#[derive(Debug)]
|
2022-10-26 13:13:39 +11:00
|
|
|
pub struct UboReflection {
|
|
|
|
pub binding: u32,
|
|
|
|
pub size: u32,
|
|
|
|
pub stage_mask: BindingStage,
|
|
|
|
}
|
|
|
|
|
2022-10-26 16:19:04 +11:00
|
|
|
#[derive(Debug)]
|
2022-10-26 13:13:39 +11:00
|
|
|
pub struct PushReflection {
|
|
|
|
pub size: u32,
|
|
|
|
pub stage_mask: BindingStage,
|
2022-10-24 14:22:26 +11:00
|
|
|
}
|
|
|
|
|
2022-10-26 16:19:04 +11:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
|
|
|
pub enum MemberOffset {
|
|
|
|
Ubo(usize),
|
2022-10-27 17:22:44 +11:00
|
|
|
PushConstant(usize),
|
2022-10-26 16:19:04 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct VariableMeta {
|
|
|
|
// this might bite us in the back because retroarch keeps separate UBO/push offsets.. eh
|
|
|
|
pub offset: MemberOffset,
|
2022-10-27 17:22:44 +11:00
|
|
|
pub components: u32,
|
2022-11-12 17:23:49 +11:00
|
|
|
pub id: String,
|
2022-10-26 16:19:04 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
2022-10-27 17:22:44 +11:00
|
|
|
pub struct TextureSizeMeta {
|
2022-10-26 16:19:04 +11:00
|
|
|
// this might bite us in the back because retroarch keeps separate UBO/push offsets..
|
|
|
|
pub offset: MemberOffset,
|
|
|
|
pub stage_mask: BindingStage,
|
2022-11-12 17:23:49 +11:00
|
|
|
pub id: String,
|
2022-10-27 17:22:44 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct TextureImage {
|
|
|
|
pub binding: u32,
|
2022-10-26 16:19:04 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
2022-10-24 14:22:26 +11:00
|
|
|
pub struct ShaderReflection {
|
2022-10-26 13:13:39 +11:00
|
|
|
pub ubo: Option<UboReflection>,
|
|
|
|
pub push_constant: Option<PushReflection>,
|
2022-10-27 17:22:44 +11:00
|
|
|
pub meta: ReflectMeta,
|
2022-10-24 14:22:26 +11:00
|
|
|
}
|
2022-11-20 10:48:54 +11:00
|
|
|
|
|
|
|
pub trait UniformMeta {
|
|
|
|
fn offset(&self) -> MemberOffset;
|
|
|
|
fn id(&self) -> &str;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl UniformMeta for VariableMeta {
|
|
|
|
fn offset(&self) -> MemberOffset {
|
|
|
|
self.offset
|
|
|
|
}
|
|
|
|
|
|
|
|
fn id(&self) -> &str {
|
|
|
|
&self.id
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl UniformMeta for TextureSizeMeta {
|
|
|
|
fn offset(&self) -> MemberOffset {
|
|
|
|
self.offset
|
|
|
|
}
|
|
|
|
|
|
|
|
fn id(&self) -> &str {
|
|
|
|
&self.id
|
|
|
|
}
|
|
|
|
}
|