reflect: document and rename some structs

This commit is contained in:
chyyran 2022-12-01 01:50:16 -05:00
parent 5d668a2233
commit e804ffd310
17 changed files with 356 additions and 219 deletions

1
.gitignore vendored
View file

@ -5,3 +5,4 @@
*.rdc
*.cap
/.vs/
librashader_runtime_*.exe

View file

@ -5,17 +5,22 @@ use crate::front::shaderc::GlslangCompilation;
use crate::reflect::cross::{CompiledProgram, GlslReflect, HlslReflect};
use crate::reflect::ReflectShader;
pub type GlVersion = spirv_cross::glsl::Version;
pub struct GlslangGlslContext {
/// The GLSL version to use.
pub type GlslVersion = spirv_cross::glsl::Version;
/// The context for a GLSL compilation via spirv-cross.
pub struct CrossGlslContext {
/// A map of bindings of sampler names to binding locations.
pub sampler_bindings: Vec<(String, u32)>,
pub compiler: CompiledProgram<spirv_cross::glsl::Target>,
/// The compiled program artifact after compilation.
pub artifact: CompiledProgram<spirv_cross::glsl::Target>,
}
impl FromCompilation<GlslangCompilation> for GLSL {
type Target = GLSL;
type Options = GlVersion;
type Context = GlslangGlslContext;
type Output = impl CompileShader<Self::Target, Options = GlVersion, Context = GlslangGlslContext>
type Options = GlslVersion;
type Context = CrossGlslContext;
type Output = impl CompileShader<Self::Target, Options = GlslVersion, Context = CrossGlslContext>
+ ReflectShader;
fn from_compilation(
@ -27,14 +32,15 @@ impl FromCompilation<GlslangCompilation> for GLSL {
}
}
pub struct GlslangHlslContext {
/// The context for a HLSL compilation via spirv-cross.
pub struct CrossHlslContext {
pub compiler: CompiledProgram<spirv_cross::hlsl::Target>,
}
impl FromCompilation<GlslangCompilation> for HLSL {
type Target = HLSL;
type Options = Option<()>;
type Context = GlslangHlslContext;
type Context = CrossHlslContext;
type Output = impl CompileShader<Self::Target, Options = Self::Options, Context = Self::Context>
+ ReflectShader;

View file

@ -3,21 +3,29 @@ pub mod targets;
use crate::back::targets::OutputTarget;
use crate::error::{ShaderCompileError, ShaderReflectError};
use crate::reflect::semantics::ReflectSemantics;
use crate::reflect::semantics::ShaderSemantics;
use crate::reflect::{ReflectShader, ShaderReflection};
use std::fmt::Debug;
/// The output of the shader compiler.
#[derive(Debug)]
pub struct ShaderCompilerOutput<T, Context = ()> {
/// The output for the vertex shader.
pub vertex: T,
/// The output for the fragment shader.
pub fragment: T,
/// Additional context provided by the shader compiler.
pub context: Context,
}
/// A trait for objects that can be compiled into a shader.
pub trait CompileShader<T: OutputTarget> {
/// Options provided to the compiler.
type Options;
/// Additional context returned by the compiler after compilation.
type Context;
/// Consume the object and return the compiled output of the shader.
fn compile(
self,
options: Self::Options,
@ -40,17 +48,24 @@ where
}
}
/// A trait for reflectable compilations that can be transformed into an object ready for reflection or compilation.
pub trait FromCompilation<T> {
/// The target that the transformed object is expected to compile for.
type Target: OutputTarget;
/// Options provided to the compiler.
type Options;
/// Additional context returned by the compiler after compilation.
type Context;
/// The output type after conversion.
type Output: CompileShader<Self::Target, Context = Self::Context, Options = Self::Options>
+ ReflectShader;
/// Tries to convert the input object into an object ready for compilation.
fn from_compilation(compile: T) -> Result<CompilerBackend<Self::Output>, ShaderReflectError>;
}
/// A wrapper for a compiler backend.
pub struct CompilerBackend<T> {
pub(crate) backend: T,
}
@ -62,7 +77,7 @@ where
fn reflect(
&mut self,
pass_number: usize,
semantics: &ReflectSemantics,
semantics: &ShaderSemantics,
) -> Result<ShaderReflection, ShaderReflectError> {
self.backend.reflect(pass_number, semantics)
}

View file

@ -1,10 +1,16 @@
/// Marker trait for shader compiler targets.
pub trait OutputTarget {
/// The output format for the target.
type Output;
}
/// Shader compiler target for GLSL.
pub struct GLSL;
/// Shader compiler target for HLSL.
pub struct HLSL;
/// Shader compiler target for SPIR-V.
pub struct SPIRV;
/// Shader compiler target for MSL
pub struct MSL;
impl OutputTarget for GLSL {

View file

@ -1,69 +1,100 @@
use crate::reflect::semantics::MemberOffset;
use thiserror::Error;
/// Error type for shader compilation.
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum ShaderCompileError {
/// Compile error from naga.
#[cfg(feature = "unstable-rust-pipeline")]
#[error("shader")]
NagaCompileError(Vec<naga::front::glsl::Error>),
/// Compilation error from shaderc (glslang).
#[error("shaderc")]
ShaderCCompileError(#[from] shaderc::Error),
/// Error when initializing the shaderc compiler.
#[error("shaderc init")]
ShaderCInitError,
/// Error when transpiling from spirv-cross.
#[error("cross")]
SpirvCrossCompileError(#[from] spirv_cross::ErrorCode),
}
/// The error kind encountered when reflecting shader semantics.
#[derive(Debug)]
pub enum SemanticsErrorKind {
/// The number of uniform buffers was invalid. Only one UBO is permitted.
InvalidUniformBufferCount(usize),
/// The number of push constant blocks was invalid. Only one push constant block is permitted.
InvalidPushBufferSize(u32),
/// The location of a varying was invalid.
InvalidLocation(u32),
/// The requested descriptor set was invalid. Only descriptor set 0 is available.
InvalidDescriptorSet(u32),
/// The number of inputs to the shader was invalid.
InvalidInputCount(usize),
/// The number of outputs declared was invalid.
InvalidOutputCount(usize),
/// The declared binding point was invalid.
InvalidBinding(u32),
/// The declared resource type was invalid.
InvalidResourceType,
/// The range of a struct member was invalid.
InvalidRange(u32),
/// The requested uniform or texture name was not provided semantics.
UnknownSemantics(String),
/// The type of the requested uniform was not compatible with the provided semantics.
InvalidTypeForSemantic(String),
}
/// Error type for shader reflection.
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum ShaderReflectError {
/// Compile error from naga.
#[cfg(feature = "unstable-rust-pipeline")]
#[error("shader")]
NagaCompileError(#[from] naga::front::spv::Error),
/// Parse error from rspirv.
#[cfg(feature = "unstable-rust-pipeline")]
#[error("rspirv")]
RspirvParseError(#[from] rspirv::binary::ParseState),
/// Reflection error from spirv-cross.
#[error("spirv")]
SpirvCrossError(#[from] spirv_cross::ErrorCode),
/// Error when validating vertex shader semantics.
#[error("error when verifying vertex semantics")]
VertexSemanticError(SemanticsErrorKind),
/// Error when validating fragment shader semantics.
#[error("error when verifying texture semantics")]
FragmentSemanticError(SemanticsErrorKind),
#[error("vertx and fragment shader must have same binding")]
/// The vertex and fragment shader must have the same UBO binding location.
#[error("vertex and fragment shader must have same binding")]
MismatchedUniformBuffer { vertex: u32, fragment: u32 },
/// The filter chain was found to be non causal. A pass tried to access the target output
/// in the future.
#[error("filter chain is non causal")]
NonCausalFilterChain { pass: usize, target: usize },
/// The offset of the given uniform did not match up in both the vertex and fragment shader.
#[error("mismatched offset")]
MismatchedOffset {
semantic: String,
vertex: MemberOffset,
fragment: MemberOffset,
},
/// The size of the given uniform did not match up in both the vertex and fragment shader.
#[error("mismatched component")]
MismatchedComponent {
MismatchedSize {
semantic: String,
vertex: u32,
fragment: u32,
},
/// The binding number is already in use.
#[error("the binding is already in use")]
BindingInUse(u32),
}

View file

@ -3,6 +3,7 @@ use librashader_preprocess::ShaderSource;
use naga::front::glsl::{Options, Parser};
use naga::{Module, ShaderStage};
/// A reflectable shader compilation via naga.
#[derive(Debug)]
pub struct NagaCompilation {
pub(crate) vertex: Module,

View file

@ -2,6 +2,7 @@ use crate::error::ShaderCompileError;
use librashader_preprocess::ShaderSource;
use shaderc::{CompilationArtifact, CompileOptions, Limit, ShaderKind};
/// A reflectable shader compilation via glslang (shaderc).
pub struct GlslangCompilation {
pub(crate) vertex: CompilationArtifact,
pub(crate) fragment: CompilationArtifact,

View file

@ -1,19 +1,14 @@
use crate::error::{SemanticsErrorKind, ShaderCompileError, ShaderReflectError};
use crate::front::shaderc::GlslangCompilation;
use crate::reflect::semantics::{
BindingStage, MemberOffset, PushReflection, ReflectSemantics, ShaderReflection, TextureBinding,
TextureSemanticMap, TextureSemantics, TextureSizeMeta, TypeInfo, UboReflection,
ValidateTypeSemantics, VariableMeta, VariableSemanticMap, VariableSemantics,
MAX_BINDINGS_COUNT, MAX_PUSH_BUFFER_SIZE,
};
use crate::reflect::{align_uniform_size, ReflectMeta, ReflectShader};
use crate::reflect::semantics::{BindingStage, MAX_BINDINGS_COUNT, MAX_PUSH_BUFFER_SIZE, MemberOffset, PushReflection, BindingMeta, ShaderSemantics, ShaderReflection, TextureBinding, TextureSemanticMap, TextureSemantics, TextureSizeMeta, TypeInfo, UboReflection, UniqueSemantics, ValidateTypeSemantics, VariableMeta, UniqueSemanticMap};
use crate::reflect::{align_uniform_size, ReflectShader};
use std::ops::Deref;
use spirv_cross::hlsl::ShaderModel;
use spirv_cross::spirv::{Ast, Decoration, Module, Resource, ShaderResources, Type};
use spirv_cross::{glsl, hlsl, ErrorCode};
use spirv_cross::{ErrorCode, glsl, hlsl};
use crate::back::cross::{GlslangGlslContext, GlslangHlslContext};
use crate::back::cross::{CrossGlslContext, CrossHlslContext};
use crate::back::targets::{GLSL, HLSL};
use crate::back::{CompileShader, ShaderCompilerOutput};
@ -49,7 +44,7 @@ where
pub(crate) type HlslReflect = CrossReflect<hlsl::Target>;
pub(crate) type GlslReflect = CrossReflect<glsl::Target>;
impl ValidateTypeSemantics<Type> for VariableSemantics {
impl ValidateTypeSemantics<Type> for UniqueSemantics {
fn validate_type(&self, ty: &Type) -> Option<TypeInfo> {
let (Type::Float { ref array, vecsize, columns } | Type::Int { ref array, vecsize, columns } | Type::UInt { ref array, vecsize, columns }) = *ty else {
return None
@ -60,16 +55,16 @@ impl ValidateTypeSemantics<Type> for VariableSemantics {
}
let valid = match self {
VariableSemantics::MVP => {
UniqueSemantics::MVP => {
matches!(ty, Type::Float { .. }) && vecsize == 4 && columns == 4
}
VariableSemantics::FrameCount => {
UniqueSemantics::FrameCount => {
matches!(ty, Type::UInt { .. }) && vecsize == 1 && columns == 1
}
VariableSemantics::FrameDirection => {
UniqueSemantics::FrameDirection => {
matches!(ty, Type::Int { .. }) && vecsize == 1 && columns == 1
}
VariableSemantics::FloatParameter => {
UniqueSemantics::FloatParameter => {
matches!(ty, Type::Float { .. }) && vecsize == 1 && columns == 1
}
_ => matches!(ty, Type::Float { .. }) && vecsize == 4 && columns == 1,
@ -299,8 +294,8 @@ where
ast: &Ast<T>,
resource: &Resource,
pass_number: usize,
semantics: &ReflectSemantics,
meta: &mut ReflectMeta,
semantics: &ShaderSemantics,
meta: &mut BindingMeta,
offset_type: impl Fn(usize) -> MemberOffset,
blame: SemanticErrorBlame,
) -> Result<(), ShaderReflectError> {
@ -319,13 +314,13 @@ where
_ => return Err(blame.error(SemanticsErrorKind::InvalidResourceType)),
};
if let Some(parameter) = semantics.uniform_semantics.get_variable_semantic(&name) {
if let Some(parameter) = semantics.uniform_semantics.get_unique_semantic(&name) {
let Some(typeinfo) = parameter.semantics.validate_type(&range_type) else {
return Err(blame.error(SemanticsErrorKind::InvalidTypeForSemantic(name)))
};
match &parameter.semantics {
VariableSemantics::FloatParameter => {
UniqueSemantics::FloatParameter => {
let offset = offset_type(range.offset);
if let Some(meta) = meta.parameter_meta.get(&name) {
if offset != meta.offset {
@ -335,10 +330,10 @@ where
fragment: offset,
});
}
if meta.components != typeinfo.size {
return Err(ShaderReflectError::MismatchedComponent {
if meta.size != typeinfo.size {
return Err(ShaderReflectError::MismatchedSize {
semantic: name,
vertex: meta.components,
vertex: meta.size,
fragment: typeinfo.size,
});
}
@ -348,14 +343,14 @@ where
VariableMeta {
id: name,
offset,
components: typeinfo.size,
size: typeinfo.size,
},
);
}
}
semantics => {
let offset = offset_type(range.offset);
if let Some(meta) = meta.variable_meta.get(semantics) {
if let Some(meta) = meta.unique_meta.get(semantics) {
if offset != meta.offset {
return Err(ShaderReflectError::MismatchedOffset {
semantic: name,
@ -363,20 +358,20 @@ where
fragment: offset,
});
}
if meta.components != typeinfo.size * typeinfo.columns {
return Err(ShaderReflectError::MismatchedComponent {
if meta.size != typeinfo.size * typeinfo.columns {
return Err(ShaderReflectError::MismatchedSize {
semantic: name,
vertex: meta.components,
vertex: meta.size,
fragment: typeinfo.size,
});
}
} else {
meta.variable_meta.insert(
meta.unique_meta.insert(
*semantics,
VariableMeta {
id: name,
offset,
components: typeinfo.size * typeinfo.columns,
size: typeinfo.size * typeinfo.columns,
},
);
}
@ -493,8 +488,8 @@ where
&self,
texture: TextureData,
pass_number: usize,
semantics: &ReflectSemantics,
meta: &mut ReflectMeta,
semantics: &ShaderSemantics,
meta: &mut BindingMeta,
) -> Result<(), ShaderReflectError> {
let Some(semantic) = semantics.texture_semantics.get_texture_semantic(texture.name) else {
return Err(SemanticErrorBlame::Fragment.error(SemanticsErrorKind::UnknownSemantics(texture.name.to_string())))
@ -609,7 +604,7 @@ where
fn reflect(
&mut self,
pass_number: usize,
semantics: &ReflectSemantics,
semantics: &ShaderSemantics,
) -> Result<ShaderReflection, ShaderReflectError> {
let vertex_res = self.vertex.get_shader_resources()?;
let fragment_res = self.fragment.get_shader_resources()?;
@ -625,7 +620,7 @@ where
let push_constant = self.reflect_push_constant_buffer(vertex_push, fragment_push)?;
let mut meta = ReflectMeta::default();
let mut meta = BindingMeta::default();
if let Some(ubo) = vertex_ubo {
Self::reflect_buffer_range_metas(
@ -700,7 +695,7 @@ where
impl CompileShader<GLSL> for CrossReflect<glsl::Target> {
type Options = glsl::Version;
type Context = GlslangGlslContext;
type Context = CrossGlslContext;
fn compile(
mut self,
@ -820,9 +815,9 @@ impl CompileShader<GLSL> for CrossReflect<glsl::Target> {
Ok(ShaderCompilerOutput {
vertex: self.vertex.compile()?,
fragment: self.fragment.compile()?,
context: GlslangGlslContext {
context: CrossGlslContext {
sampler_bindings: texture_fixups,
compiler: CompiledProgram {
artifact: CompiledProgram {
vertex: CompiledAst(self.vertex),
fragment: CompiledAst(self.fragment),
},
@ -833,12 +828,12 @@ impl CompileShader<GLSL> for CrossReflect<glsl::Target> {
impl CompileShader<HLSL> for CrossReflect<hlsl::Target> {
type Options = Option<()>;
type Context = GlslangHlslContext;
type Context = CrossHlslContext;
fn compile(
mut self,
_options: Self::Options,
) -> Result<ShaderCompilerOutput<String, GlslangHlslContext>, ShaderCompileError> {
) -> Result<ShaderCompilerOutput<String, CrossHlslContext>, ShaderCompileError> {
let mut options = hlsl::CompilerOptions::default();
options.shader_model = ShaderModel::V5_0;
@ -848,7 +843,7 @@ impl CompileShader<HLSL> for CrossReflect<hlsl::Target> {
Ok(ShaderCompilerOutput {
vertex: self.vertex.compile()?,
fragment: self.fragment.compile()?,
context: GlslangHlslContext {
context: CrossHlslContext {
compiler: CompiledProgram {
vertex: CompiledAst(self.vertex),
fragment: CompiledAst(self.fragment),
@ -867,7 +862,7 @@ mod test {
use crate::back::CompileShader;
use crate::front::shaderc::GlslangCompilation;
use crate::reflect::semantics::{
ReflectSemantics, SemanticMap, UniformSemantic, VariableSemantics,
ShaderSemantics, Semantic, UniformSemantic, UniqueSemantics,
};
use librashader_preprocess::ShaderSource;
use spirv_cross::glsl;
@ -881,8 +876,8 @@ mod test {
for (_index, param) in result.parameters.iter().enumerate() {
uniform_semantics.insert(
param.id.clone(),
UniformSemantic::Variable(SemanticMap {
semantics: VariableSemantics::FloatParameter,
UniformSemantic::Unique(Semantic {
semantics: UniqueSemantics::FloatParameter,
index: (),
}),
);
@ -892,7 +887,7 @@ mod test {
let _shader_reflection = reflect
.reflect(
0,
&ReflectSemantics {
&ShaderSemantics {
uniform_semantics,
texture_semantics: Default::default(),
},

View file

@ -1,12 +1,14 @@
use crate::error::ShaderReflectError;
use crate::reflect::semantics::{
SemanticMap, TextureBinding, TextureSemantics, TextureSizeMeta, VariableMeta, VariableSemantics,
Semantic, TextureBinding, TextureSemantics, TextureSizeMeta, UniqueSemantics, VariableMeta,
};
use rustc_hash::FxHashMap;
use semantics::ReflectSemantics;
use semantics::ShaderSemantics;
/// Reflection via spirv-cross.
pub mod cross;
/// Shader semantics and reflection information.
pub mod semantics;
#[cfg(feature = "unstable-rust-pipeline")]
@ -14,22 +16,17 @@ mod naga;
#[cfg(feature = "unstable-rust-pipeline")]
mod rspirv;
/// A trait for compilation outputs that can provide reflection information.
pub trait ReflectShader {
/// Reflect the shader as the given pass within the shader preset, against the provided
/// semantic map.
fn reflect(
&mut self,
pass_number: usize,
semantics: &ReflectSemantics,
semantics: &ShaderSemantics,
) -> Result<ShaderReflection, ShaderReflectError>;
}
#[derive(Debug, Default)]
pub struct ReflectMeta {
pub parameter_meta: FxHashMap<String, VariableMeta>,
pub variable_meta: FxHashMap<VariableSemantics, VariableMeta>,
pub texture_meta: FxHashMap<SemanticMap<TextureSemantics>, TextureBinding>,
pub texture_size_meta: FxHashMap<SemanticMap<TextureSemantics>, TextureSizeMeta>,
}
pub use semantics::ShaderReflection;
#[inline(always)]

View file

@ -1,65 +1,91 @@
use crate::reflect::ReflectMeta;
use bitflags::bitflags;
use rustc_hash::FxHashMap;
use std::str::FromStr;
/// The maximum number of bindings allowed in a shader.
pub const MAX_BINDINGS_COUNT: u32 = 16;
/// The maximum size of the push constant range.
pub const MAX_PUSH_BUFFER_SIZE: u32 = 128;
/// The type of a uniform.
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Hash)]
pub enum UniformType {
MVP,
Size,
/// A matrix of 4x4 floats (`mat4`).
Mat4,
/// A vector of 4 floats (`vec4`).
Vec4,
/// An unsigned integer (`uint`).
Unsigned,
/// A signed integer (`int`).
Signed,
/// A floating point number (`float`).
Float,
}
/// Unique semantics are builtin uniforms passed by the shader runtime
/// that are always available.
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Hash)]
#[repr(i32)]
pub enum VariableSemantics {
pub enum UniqueSemantics {
// mat4, MVP
/// The Model View Projection matrix for the frame.
MVP = 0,
// vec4, viewport size of current pass
/// The viewport size of the current pass.
Output = 1,
// vec4, viewport size of final pass
/// The viewport size of the final pass.
FinalViewport = 2,
// uint, frame count with modulo
/// The frame count, possibly with shader-defined modulo.
FrameCount = 3,
// int, frame direction
/// The frame direction.
FrameDirection = 4,
/// A user defined float parameter.
// float, user defined parameter, array
FloatParameter = 5,
}
impl VariableSemantics {
pub const fn semantics(self) -> SemanticMap<VariableSemantics, ()> {
SemanticMap {
impl UniqueSemantics {
/// Produce a `Semantic` for this `UniqueSemantics`.
pub const fn semantics(self) -> Semantic<UniqueSemantics, ()> {
Semantic {
semantics: self,
index: (),
}
}
/// Get the type of the uniform when bound.
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,
UniqueSemantics::MVP => UniformType::Mat4,
UniqueSemantics::Output => UniformType::Vec4,
UniqueSemantics::FinalViewport => UniformType::Vec4,
UniqueSemantics::FrameCount => UniformType::Unsigned,
UniqueSemantics::FrameDirection => UniformType::Signed,
UniqueSemantics::FloatParameter => UniformType::Float,
}
}
}
/// Texture semantics relate to input or output textures.
///
/// Texture semantics are used to relate both texture samplers and `*Size` uniforms.
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Hash)]
#[repr(i32)]
pub enum TextureSemantics {
/// The original input of the filter chain.
Original = 0,
/// The input from the previous shader pass, or the input on the first shader pass.
Source = 1,
/// The input frames from previous frames.
OriginalHistory = 2,
/// The output from previous shader passes in the same frame.
PassOutput = 3,
/// The output from previous shader passes in the previous frame.
PassFeedback = 4,
/// A user provided lookup texture.
User = 5,
}
@ -76,6 +102,7 @@ impl TextureSemantics {
TextureSemantics::User,
];
/// Get the name of the size uniform for this semantics when bound.
pub fn size_uniform_name(&self) -> &'static str {
match self {
TextureSemantics::Original => "OriginalSize",
@ -87,6 +114,7 @@ impl TextureSemantics {
}
}
/// Get the name of the texture sampler for this semantics when bound.
pub fn texture_name(&self) -> &'static str {
match self {
TextureSemantics::Original => "Original",
@ -98,33 +126,42 @@ impl TextureSemantics {
}
}
pub fn is_array(&self) -> bool {
/// Returns whether or not textures of this semantics are indexed or unique.
///
/// Only Original and Source are unique, all other textures can be indexed.
pub fn is_indexed(&self) -> bool {
!matches!(self, TextureSemantics::Original | TextureSemantics::Source)
}
pub const fn semantics(self, index: usize) -> SemanticMap<TextureSemantics> {
SemanticMap {
/// Produce a `Semantic` for this `TextureSemantics` of the given index.
pub const fn semantics(self, index: usize) -> Semantic<TextureSemantics> {
Semantic {
semantics: self,
index,
}
}
}
pub struct TypeInfo {
pub(crate) struct TypeInfo {
pub size: u32,
pub columns: u32,
}
pub trait ValidateTypeSemantics<T> {
pub(crate) trait ValidateTypeSemantics<T> {
fn validate_type(&self, ty: &T) -> Option<TypeInfo>;
}
/// A unit of unique or indexed semantic.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct SemanticMap<T, I = usize> {
pub struct Semantic<T, I = usize> {
/// The semantics of this unit.
pub semantics: T,
/// The index of the semantic if not unique.
pub index: I,
}
bitflags! {
/// The pipeline stage for which a uniform is bound.
pub struct BindingStage: u8 {
const NONE = 0b00000000;
const VERTEX = 0b00000001;
@ -132,64 +169,86 @@ bitflags! {
}
}
impl BindingStage {
pub fn clear(&mut self) {
self.bits = 0;
}
}
/// Reflection information for the Uniform Buffer
#[derive(Debug)]
pub struct UboReflection {
/// The binding point for this UBO.
pub binding: u32,
/// Get this size of this UBO buffer.
/// The size returned by reflection is always aligned to a 16 byte boundary.
/// The size of the UBO buffer. UBO sizes returned by reflection is always aligned to a 16 byte boundary.
pub size: u32,
/// The mask indicating for which stages the UBO should be bound.
pub stage_mask: BindingStage,
}
/// Reflection information for the Push Constant Block
#[derive(Debug)]
pub struct PushReflection {
/// The size returned by reflection is always aligned to a 16 byte boundary.
/// The size of the Push Constant range. The size returned by reflection is always aligned to a 16 byte boundary.
pub size: u32,
/// The mask indicating for which stages the Push Constant range should be bound.
pub stage_mask: BindingStage,
}
/// The offset of a uniform member.
///
/// A uniform can be bound to **either** the UBO, or as a Push Constant. Binding
/// the same variable name to both locations will result in indeterminate results.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum MemberOffset {
/// The offset of the uniform member within the UBO.
Ubo(usize),
/// The offset of the uniform member within the Push Constant range.
PushConstant(usize),
}
/// Reflection information about a non-texture related uniform variable.
#[derive(Debug)]
pub struct VariableMeta {
// this might bite us in the back because retroarch keeps separate UBO/push offsets.. eh
/// The offset of this variable uniform.
pub offset: MemberOffset,
pub components: u32,
/// The size of the uniform.
pub size: u32,
/// The name of the uniform.
pub id: String,
}
/// Reflection information about a texture size uniform variable.
#[derive(Debug)]
pub struct TextureSizeMeta {
// this might bite us in the back because retroarch keeps separate UBO/push offsets..
/// The offset of this size uniform.
pub offset: MemberOffset,
/// The mask indicating for which stages the texture size uniform should be bound.
pub stage_mask: BindingStage,
/// The name of the uniform.
pub id: String,
}
/// Reflection information about texture samplers.
#[derive(Debug)]
pub struct TextureBinding {
/// The binding index of the texture.
pub binding: u32,
}
/// Reflection information about a shader.
#[derive(Debug)]
pub struct ShaderReflection {
/// Reflection information about the UBO for this shader.
pub ubo: Option<UboReflection>,
/// Reflection information about the Push Constant range for this shader.
pub push_constant: Option<PushReflection>,
pub meta: ReflectMeta,
/// Metadata about the bindings required for this shader.
pub meta: BindingMeta,
}
/// Metadata about a uniform variable.
pub trait UniformMeta {
/// The offset of this uniform.
fn offset(&self) -> MemberOffset;
/// The name of this uniform in the shader.
fn id(&self) -> &str;
}
@ -207,35 +266,36 @@ impl UniformMeta for TextureSizeMeta {
fn offset(&self) -> MemberOffset {
self.offset
}
fn id(&self) -> &str {
&self.id
}
}
pub trait TextureSemanticMap<T> {
fn get_texture_semantic(&self, name: &str) -> Option<SemanticMap<TextureSemantics>>;
/// A trait for maps that can return texture semantic units.
pub trait TextureSemanticMap {
/// Get the texture semantic for the given variable name.
fn get_texture_semantic(&self, name: &str) -> Option<Semantic<TextureSemantics>>;
}
impl TextureSemanticMap<UniformSemantic> for FxHashMap<String, UniformSemantic> {
fn get_texture_semantic(&self, name: &str) -> Option<SemanticMap<TextureSemantics>> {
impl TextureSemanticMap for FxHashMap<String, UniformSemantic> {
fn get_texture_semantic(&self, name: &str) -> Option<Semantic<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() {
if semantics.is_indexed() {
let index = &name[semantics.size_uniform_name().len()..];
let Ok(index) = usize::from_str(index) else {
return None;
};
return Some(SemanticMap {
return Some(Semantic {
semantics: *semantics,
index,
});
} else if name == semantics.size_uniform_name() {
return Some(SemanticMap {
return Some(Semantic {
semantics: *semantics,
index: 0,
});
@ -243,29 +303,29 @@ impl TextureSemanticMap<UniformSemantic> for FxHashMap<String, UniformSemantic>
}
None
}
Some(UniformSemantic::Variable(_)) => None,
Some(UniformSemantic::Unique(_)) => 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>> {
impl TextureSemanticMap for FxHashMap<String, Semantic<TextureSemantics>> {
fn get_texture_semantic(&self, name: &str) -> Option<Semantic<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() {
if semantics.is_indexed() {
let index = &name[semantics.texture_name().len()..];
let Ok(index) = usize::from_str(index) else {return None};
return Some(SemanticMap {
return Some(Semantic {
semantics: *semantics,
index,
});
} else if name == semantics.texture_name() {
return Some(SemanticMap {
return Some(Semantic {
semantics: *semantics,
index: 0,
});
@ -278,70 +338,98 @@ impl TextureSemanticMap<UniformSemantic> for FxHashMap<String, SemanticMap<Textu
}
}
pub trait VariableSemanticMap<T> {
fn get_variable_semantic(&self, name: &str) -> Option<SemanticMap<VariableSemantics, ()>>;
/// A trait for maps that can return unique semantic units.
pub trait UniqueSemanticMap {
/// Get the unique semantic for the given variable name.
fn get_unique_semantic(&self, name: &str) -> Option<Semantic<UniqueSemantics, ()>>;
}
impl VariableSemanticMap<UniformSemantic> for FxHashMap<String, UniformSemantic> {
fn get_variable_semantic(&self, name: &str) -> Option<SemanticMap<VariableSemantics, ()>> {
impl UniqueSemanticMap for FxHashMap<String, UniformSemantic> {
fn get_unique_semantic(&self, name: &str) -> Option<Semantic<UniqueSemantics, ()>> {
match self.get(name) {
// existing uniforms in the semantic map have priority
None => match name {
"MVP" => Some(SemanticMap {
semantics: VariableSemantics::MVP,
"MVP" => Some(Semantic {
semantics: UniqueSemantics::MVP,
index: (),
}),
"OutputSize" => Some(SemanticMap {
semantics: VariableSemantics::Output,
"OutputSize" => Some(Semantic {
semantics: UniqueSemantics::Output,
index: (),
}),
"FinalViewportSize" => Some(SemanticMap {
semantics: VariableSemantics::FinalViewport,
"FinalViewportSize" => Some(Semantic {
semantics: UniqueSemantics::FinalViewport,
index: (),
}),
"FrameCount" => Some(SemanticMap {
semantics: VariableSemantics::FrameCount,
"FrameCount" => Some(Semantic {
semantics: UniqueSemantics::FrameCount,
index: (),
}),
"FrameDirection" => Some(SemanticMap {
semantics: VariableSemantics::FrameDirection,
"FrameDirection" => Some(Semantic {
semantics: UniqueSemantics::FrameDirection,
index: (),
}),
_ => None,
},
Some(UniformSemantic::Variable(variable)) => Some(*variable),
Some(UniformSemantic::Unique(variable)) => Some(*variable),
Some(UniformSemantic::Texture(_)) => None,
}
}
}
/// Semantic assignment of a shader uniform to filter chain semantics.
#[derive(Debug, Clone)]
pub enum UniformSemantic {
Variable(SemanticMap<VariableSemantics, ()>),
Texture(SemanticMap<TextureSemantics>),
/// A unique semantic.
Unique(Semantic<UniqueSemantics, ()>),
/// A texture related semantic.
Texture(Semantic<TextureSemantics>),
}
/// The runtime provided maps of uniform and texture variables to filter chain semantics.
#[derive(Debug, Clone)]
pub struct ReflectSemantics {
pub struct ShaderSemantics {
/// A map of uniform names to filter chain semantics.
pub uniform_semantics: FxHashMap<String, UniformSemantic>,
pub texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>>,
/// A map of texture names to filter chain semantics.
pub texture_semantics: FxHashMap<String, Semantic<TextureSemantics>>,
}
/// The binding of a uniform after the shader has been linked.
///
/// Used in combination with [`MemberOffset`](crate::reflect::semantics::MemberOffset) to keep track
/// of semantics at each frame pass.
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
pub enum UniformBinding {
/// A user parameter (`float`) binding.
Parameter(String),
SemanticVariable(VariableSemantics),
TextureSize(SemanticMap<TextureSemantics>),
/// A known semantic binding.
SemanticVariable(UniqueSemantics),
/// A texture size (`float4`) binding.
TextureSize(Semantic<TextureSemantics>),
}
impl From<VariableSemantics> for UniformBinding {
fn from(value: VariableSemantics) -> Self {
impl From<UniqueSemantics> for UniformBinding {
fn from(value: UniqueSemantics) -> Self {
UniformBinding::SemanticVariable(value)
}
}
impl From<SemanticMap<TextureSemantics>> for UniformBinding {
fn from(value: SemanticMap<TextureSemantics>) -> Self {
impl From<Semantic<TextureSemantics>> for UniformBinding {
fn from(value: Semantic<TextureSemantics>) -> Self {
UniformBinding::TextureSize(value)
}
}
/// Reflection metadata about the various bindings for this shader.
#[derive(Debug, Default)]
pub struct BindingMeta {
/// A map of parameter names to uniform binding metadata.
pub parameter_meta: FxHashMap<String, VariableMeta>,
/// A map of unique semantics to uniform binding metadata.
pub unique_meta: FxHashMap<UniqueSemantics, VariableMeta>,
/// A map of texture semantics to texture binding points.
pub texture_meta: FxHashMap<Semantic<TextureSemantics>, TextureBinding>,
/// A map of texture semantics to texture size uniform binding metadata.
pub texture_size_meta: FxHashMap<Semantic<TextureSemantics>, TextureSizeMeta>,
}

View file

@ -3,13 +3,13 @@ use librashader_common::image::{Image, UVDirection};
use librashader_common::{ImageFormat, Size};
use librashader_preprocess::ShaderSource;
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
use librashader_reflect::back::cross::GlslangHlslContext;
use librashader_reflect::back::cross::CrossHlslContext;
use librashader_reflect::back::targets::HLSL;
use librashader_reflect::back::{CompileShader, CompilerBackend, FromCompilation};
use librashader_reflect::front::shaderc::GlslangCompilation;
use librashader_reflect::reflect::semantics::{
ReflectSemantics, SemanticMap, TextureSemantics, UniformBinding, UniformSemantic,
VariableSemantics,
ShaderSemantics, Semantic, TextureSemantics, UniformBinding, UniformSemantic,
UniqueSemantics,
};
use librashader_reflect::reflect::ReflectShader;
use rustc_hash::FxHashMap;
@ -45,7 +45,7 @@ type ShaderPassMeta = (
ShaderPassConfig,
ShaderSource,
CompilerBackend<
impl CompileShader<HLSL, Options = Option<()>, Context = GlslangHlslContext> + ReflectShader,
impl CompileShader<HLSL, Options = Option<()>, Context =CrossHlslContext> + ReflectShader,
>,
);
@ -218,7 +218,7 @@ impl FilterChain {
fn init_passes(
device: &ID3D11Device,
passes: Vec<ShaderPassMeta>,
semantics: &ReflectSemantics,
semantics: &ShaderSemantics,
) -> error::Result<Vec<FilterPass>> {
// let mut filters = Vec::new();
let mut filters = Vec::new();
@ -290,7 +290,7 @@ impl FilterChain {
uniform_bindings.insert(UniformBinding::Parameter(param.id.clone()), param.offset);
}
for (semantics, param) in &reflection.meta.variable_meta {
for (semantics, param) in &reflection.meta.unique_meta {
uniform_bindings.insert(UniformBinding::SemanticVariable(*semantics), param.offset);
}
@ -414,9 +414,9 @@ impl FilterChain {
fn load_preset(
passes: Vec<ShaderPassConfig>,
textures: &[TextureConfig],
) -> error::Result<(Vec<ShaderPassMeta>, ReflectSemantics)> {
) -> error::Result<(Vec<ShaderPassMeta>, ShaderSemantics)> {
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
let mut texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>> =
let mut texture_semantics: FxHashMap<String, Semantic<TextureSemantics>> =
Default::default();
let passes = passes
@ -431,8 +431,8 @@ impl FilterChain {
for parameter in source.parameters.iter() {
uniform_semantics.insert(
parameter.id.clone(),
UniformSemantic::Variable(SemanticMap {
semantics: VariableSemantics::FloatParameter,
UniformSemantic::Unique(Semantic {
semantics: UniqueSemantics::FloatParameter,
index: (),
}),
);
@ -456,7 +456,7 @@ impl FilterChain {
&mut texture_semantics,
);
let semantics = ReflectSemantics {
let semantics = ShaderSemantics {
uniform_semantics,
texture_semantics,
};

View file

@ -3,10 +3,10 @@ use crate::texture::Texture;
use librashader_common::{ImageFormat, Size};
use librashader_preprocess::ShaderSource;
use librashader_presets::ShaderPassConfig;
use librashader_reflect::back::cross::GlslangHlslContext;
use librashader_reflect::back::cross::CrossHlslContext;
use librashader_reflect::back::ShaderCompilerOutput;
use librashader_reflect::reflect::semantics::{
BindingStage, MemberOffset, TextureBinding, TextureSemantics, UniformBinding, VariableSemantics,
BindingStage, MemberOffset, TextureBinding, TextureSemantics, UniformBinding, UniqueSemantics,
};
use librashader_reflect::reflect::ShaderReflection;
use rustc_hash::FxHashMap;
@ -32,7 +32,7 @@ pub struct ConstantBufferBinding {
// slang_process.cpp 141
pub struct FilterPass {
pub reflection: ShaderReflection,
pub compiled: ShaderCompilerOutput<String, GlslangHlslContext>,
pub compiled: ShaderCompilerOutput<String, CrossHlslContext>,
pub vertex_shader: ID3D11VertexShader,
pub vertex_layout: ID3D11InputLayout,
pub pixel_shader: ID3D11PixelShader,
@ -95,19 +95,19 @@ impl FilterPass {
let mut samplers: [Option<ID3D11SamplerState>; 16] = std::array::from_fn(|_| None);
// Bind MVP
if let Some(offset) = self.uniform_bindings.get(&VariableSemantics::MVP.into()) {
if let Some(offset) = self.uniform_bindings.get(&UniqueSemantics::MVP.into()) {
self.uniform_storage.bind_mat4(*offset, mvp, None);
}
// bind OutputSize
if let Some(offset) = self.uniform_bindings.get(&VariableSemantics::Output.into()) {
if let Some(offset) = self.uniform_bindings.get(&UniqueSemantics::Output.into()) {
self.uniform_storage.bind_vec4(*offset, fb_size, None);
}
// bind FinalViewportSize
if let Some(offset) = self
.uniform_bindings
.get(&VariableSemantics::FinalViewport.into())
.get(&UniqueSemantics::FinalViewport.into())
{
self.uniform_storage.bind_vec4(*offset, viewport_size, None);
}
@ -115,7 +115,7 @@ impl FilterPass {
// bind FrameCount
if let Some(offset) = self
.uniform_bindings
.get(&VariableSemantics::FrameCount.into())
.get(&UniqueSemantics::FrameCount.into())
{
self.uniform_storage.bind_scalar(*offset, frame_count, None);
}
@ -123,7 +123,7 @@ impl FilterPass {
// bind FrameDirection
if let Some(offset) = self
.uniform_bindings
.get(&VariableSemantics::FrameDirection.into())
.get(&UniqueSemantics::FrameDirection.into())
{
self.uniform_storage
.bind_scalar(*offset, frame_direction, None);

View file

@ -1,9 +1,9 @@
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
use librashader_reflect::reflect::semantics::{MemberOffset, ReflectSemantics, SemanticMap, TextureSemantics, UniformBinding, UniformMeta, UniformSemantic, VariableSemantics};
use librashader_reflect::reflect::semantics::{MemberOffset, ShaderSemantics, Semantic, TextureSemantics, UniformBinding, UniformMeta, UniformSemantic, UniqueSemantics};
use rustc_hash::FxHashMap;
use librashader_preprocess::ShaderSource;
use librashader_reflect::back::{CompilerBackend, CompileShader, FromCompilation};
use librashader_reflect::back::cross::{GlslangGlslContext, GlVersion};
use librashader_reflect::back::cross::{CrossGlslContext, GlslVersion};
use librashader_reflect::back::targets::GLSL;
use librashader_reflect::front::shaderc::GlslangCompilation;
use spirv_cross::spirv::Decoration;
@ -79,7 +79,7 @@ type ShaderPassMeta = (
ShaderPassConfig,
ShaderSource,
CompilerBackend<
impl CompileShader<GLSL, Options = GlVersion, Context = GlslangGlslContext> + ReflectShader,
impl CompileShader<GLSL, Options =GlslVersion, Context =CrossGlslContext> + ReflectShader,
>,
);
@ -154,9 +154,9 @@ impl<T: GLInterface> FilterChainImpl<T> {
fn load_preset(
passes: Vec<ShaderPassConfig>,
textures: &[TextureConfig],
) -> error::Result<(Vec<ShaderPassMeta>, ReflectSemantics)> {
) -> error::Result<(Vec<ShaderPassMeta>, ShaderSemantics)> {
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
let mut texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>> =
let mut texture_semantics: FxHashMap<String, Semantic<TextureSemantics>> =
Default::default();
let passes = passes
@ -171,8 +171,8 @@ impl<T: GLInterface> FilterChainImpl<T> {
for parameter in source.parameters.iter() {
uniform_semantics.insert(
parameter.id.clone(),
UniformSemantic::Variable(SemanticMap {
semantics: VariableSemantics::FloatParameter,
UniformSemantic::Unique(Semantic {
semantics: UniqueSemantics::FloatParameter,
index: (),
}),
);
@ -196,7 +196,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
&mut texture_semantics,
);
let semantics = ReflectSemantics {
let semantics = ShaderSemantics {
uniform_semantics,
texture_semantics,
};
@ -205,9 +205,9 @@ impl<T: GLInterface> FilterChainImpl<T> {
}
fn init_passes(
version: GlVersion,
version: GlslVersion,
passes: Vec<ShaderPassMeta>,
semantics: &ReflectSemantics,
semantics: &ShaderSemantics,
) -> error::Result<Box<[FilterPass<T>]>> {
let mut filters = Vec::new();
@ -216,7 +216,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
let reflection = reflect.reflect(index, semantics)?;
let glsl = reflect.compile(version)?;
let vertex_resources = glsl.context.compiler.vertex.get_shader_resources()?;
let vertex_resources = glsl.context.artifact.vertex.get_shader_resources()?;
// todo: split this out.
let (program, ubo_location) = unsafe {
@ -230,7 +230,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
for res in vertex_resources.stage_inputs {
let loc = glsl
.context
.compiler
.artifact
.vertex
.get_decoration(res.id, Decoration::Location)?;
let mut name = res.name;
@ -302,7 +302,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
);
}
for (semantics, param) in &reflection.meta.variable_meta {
for (semantics, param) in &reflection.meta.unique_meta {
uniform_bindings.insert(
UniformBinding::SemanticVariable(*semantics),
(Self::reflect_uniform_location(program, param), param.offset),

View file

@ -1,5 +1,5 @@
use gl::types::{GLsizei, GLuint};
use librashader_reflect::back::cross::GlslangGlslContext;
use librashader_reflect::back::cross::CrossGlslContext;
use librashader_reflect::back::ShaderCompilerOutput;
use librashader_reflect::reflect::ShaderReflection;
@ -7,7 +7,7 @@ use librashader_common::{ImageFormat, Size};
use librashader_preprocess::ShaderSource;
use librashader_presets::ShaderPassConfig;
use librashader_reflect::reflect::semantics::{
MemberOffset, TextureSemantics, UniformBinding, VariableSemantics,
MemberOffset, TextureSemantics, UniformBinding, UniqueSemantics,
};
use rustc_hash::FxHashMap;
@ -21,7 +21,7 @@ use crate::texture::Texture;
pub struct FilterPass<T: GLInterface> {
pub reflection: ShaderReflection,
pub compiled: ShaderCompilerOutput<String, GlslangGlslContext>,
pub compiled: ShaderCompilerOutput<String, CrossGlslContext>,
pub program: GLuint,
pub ubo_location: UniformLocation<GLuint>,
pub ubo_ring: Option<T::UboRing>,
@ -127,7 +127,7 @@ impl<T: GLInterface> FilterPass<T> {
source: &Texture,
) {
// Bind MVP
if let Some((location, offset)) = self.uniform_bindings.get(&VariableSemantics::MVP.into())
if let Some((location, offset)) = self.uniform_bindings.get(&UniqueSemantics::MVP.into())
{
self.uniform_storage
.bind_mat4(*offset, mvp, location.location());
@ -135,7 +135,7 @@ impl<T: GLInterface> FilterPass<T> {
// bind OutputSize
if let Some((location, offset)) =
self.uniform_bindings.get(&VariableSemantics::Output.into())
self.uniform_bindings.get(&UniqueSemantics::Output.into())
{
self.uniform_storage
.bind_vec4(*offset, fb_size, location.location());
@ -144,7 +144,7 @@ impl<T: GLInterface> FilterPass<T> {
// bind FinalViewportSize
if let Some((location, offset)) = self
.uniform_bindings
.get(&VariableSemantics::FinalViewport.into())
.get(&UniqueSemantics::FinalViewport.into())
{
self.uniform_storage
.bind_vec4(*offset, viewport.output.size, location.location());
@ -153,7 +153,7 @@ impl<T: GLInterface> FilterPass<T> {
// bind FrameCount
if let Some((location, offset)) = self
.uniform_bindings
.get(&VariableSemantics::FrameCount.into())
.get(&UniqueSemantics::FrameCount.into())
{
self.uniform_storage
.bind_scalar(*offset, frame_count, location.location());
@ -162,7 +162,7 @@ impl<T: GLInterface> FilterPass<T> {
// bind FrameDirection
if let Some((location, offset)) = self
.uniform_bindings
.get(&VariableSemantics::FrameDirection.into())
.get(&UniqueSemantics::FrameDirection.into())
{
self.uniform_storage
.bind_scalar(*offset, frame_direction, location.location());

View file

@ -1,6 +1,6 @@
use gl::types::{GLenum, GLuint};
use librashader_reflect::back::cross::GlVersion;
use librashader_reflect::back::cross::GlslVersion;
pub trait RingBuffer<T> {
fn current(&self) -> &T;
@ -69,7 +69,7 @@ pub unsafe fn gl_compile_shader(stage: GLenum, source: &str) -> GLuint {
shader
}
pub fn gl_get_version() -> GlVersion {
pub fn gl_get_version() -> GlslVersion {
let mut maj_ver = 0;
let mut min_ver = 0;
unsafe {
@ -79,40 +79,40 @@ pub fn gl_get_version() -> GlVersion {
match maj_ver {
3 => match min_ver {
3 => GlVersion::V3_30,
2 => GlVersion::V1_50,
1 => GlVersion::V1_40,
0 => GlVersion::V1_30,
_ => GlVersion::V1_50,
3 => GlslVersion::V3_30,
2 => GlslVersion::V1_50,
1 => GlslVersion::V1_40,
0 => GlslVersion::V1_30,
_ => GlslVersion::V1_50,
},
4 => match min_ver {
6 => GlVersion::V4_60,
5 => GlVersion::V4_50,
4 => GlVersion::V4_40,
3 => GlVersion::V4_30,
2 => GlVersion::V4_20,
1 => GlVersion::V4_10,
0 => GlVersion::V4_00,
_ => GlVersion::V1_50,
6 => GlslVersion::V4_60,
5 => GlslVersion::V4_50,
4 => GlslVersion::V4_40,
3 => GlslVersion::V4_30,
2 => GlslVersion::V4_20,
1 => GlslVersion::V4_10,
0 => GlslVersion::V4_00,
_ => GlslVersion::V1_50,
},
_ => GlVersion::V1_50,
_ => GlslVersion::V1_50,
}
}
pub fn gl_u16_to_version(version: u16) -> GlVersion {
pub fn gl_u16_to_version(version: u16) -> GlslVersion {
match version {
0 => gl_get_version(),
300 => GlVersion::V1_30,
310 => GlVersion::V1_40,
320 => GlVersion::V1_50,
330 => GlVersion::V3_30,
400 => GlVersion::V4_00,
410 => GlVersion::V4_10,
420 => GlVersion::V4_20,
430 => GlVersion::V4_30,
440 => GlVersion::V4_40,
450 => GlVersion::V4_50,
460 => GlVersion::V4_60,
_ => GlVersion::V1_50,
300 => GlslVersion::V1_30,
310 => GlslVersion::V1_40,
320 => GlslVersion::V1_50,
330 => GlslVersion::V3_30,
400 => GlslVersion::V4_00,
410 => GlslVersion::V4_10,
420 => GlslVersion::V4_20,
430 => GlslVersion::V4_30,
440 => GlslVersion::V4_40,
450 => GlslVersion::V4_50,
460 => GlslVersion::V4_60,
_ => GlslVersion::V1_50,
}
}

View file

@ -1,12 +1,12 @@
use librashader_presets::{ShaderPassConfig, TextureConfig};
use librashader_reflect::reflect::semantics::{SemanticMap, TextureSemantics, UniformSemantic};
use librashader_reflect::reflect::semantics::{Semantic, TextureSemantics, UniformSemantic};
use rustc_hash::FxHashMap;
/// A map for variable names and uniform semantics
pub type UniformSemanticsMap = FxHashMap<String, UniformSemantic>;
/// A map for sampler names and texture semantics.
pub type TextureSemanticsMap = FxHashMap<String, SemanticMap<TextureSemantics>>;
pub type TextureSemanticsMap = FxHashMap<String, Semantic<TextureSemantics>>;
/// Insert the available semantics for the input pass config into the provided semantic maps.
pub fn insert_pass_semantics(
@ -28,14 +28,14 @@ pub fn insert_pass_semantics(
// PassOutput
texture_semantics.insert(
alias.clone(),
SemanticMap {
Semantic {
semantics: TextureSemantics::PassOutput,
index,
},
);
uniform_semantics.insert(
format!("{alias}Size"),
UniformSemantic::Texture(SemanticMap {
UniformSemantic::Texture(Semantic {
semantics: TextureSemantics::PassOutput,
index,
}),
@ -44,14 +44,14 @@ pub fn insert_pass_semantics(
// PassFeedback
texture_semantics.insert(
format!("{alias}Feedback"),
SemanticMap {
Semantic {
semantics: TextureSemantics::PassFeedback,
index,
},
);
uniform_semantics.insert(
format!("{alias}FeedbackSize"),
UniformSemantic::Texture(SemanticMap {
UniformSemantic::Texture(Semantic {
semantics: TextureSemantics::PassFeedback,
index,
}),
@ -67,7 +67,7 @@ pub fn insert_lut_semantics(
for (index, texture) in textures.iter().enumerate() {
texture_semantics.insert(
texture.name.clone(),
SemanticMap {
Semantic {
semantics: TextureSemantics::User,
index,
},
@ -75,7 +75,7 @@ pub fn insert_lut_semantics(
uniform_semantics.insert(
format!("{}Size", texture.name),
UniformSemantic::Texture(SemanticMap {
UniformSemantic::Texture(Semantic {
semantics: TextureSemantics::User,
index,
}),

View file

@ -38,27 +38,23 @@ pub mod preprocess {
pub mod reflect {
/// Supported shader compiler targets.
pub mod targets {
/// Shader compiler target for GLSL.
pub use librashader_reflect::back::targets::GLSL;
/// Shader compiler target for HLSL.
pub use librashader_reflect::back::targets::HLSL;
/// Shader compiler target for SPIR-V.
pub use librashader_reflect::back::targets::SPIRV;
}
pub use librashader_reflect::error::*;
pub use librashader_reflect::reflect::{
semantics, ReflectMeta, ReflectShader, ShaderReflection,
ReflectShader, semantics, ShaderReflection,
};
pub use librashader_reflect::back::{
targets::OutputTarget, CompileShader, CompilerBackend, FromCompilation,
ShaderCompilerOutput,
CompilerBackend, CompileShader, FromCompilation, ShaderCompilerOutput,
targets::OutputTarget,
};
pub use librashader_reflect::front::shaderc::GlslangCompilation;
pub use librashader_reflect::reflect::semantics::BindingMeta;
}
/// Shader runtimes to execute a filter chain on a GPU surface.