librashader_presets/
preset.rs

1use crate::error::ParsePresetError;
2use librashader_common::map::ShortString;
3use librashader_common::{FilterMode, ImageFormat, WrapMode};
4use std::ops::Mul;
5use std::path::PathBuf;
6use std::str::FromStr;
7
8pub use librashader_common::shader_features::ShaderFeatures;
9
10/// The configuration for a single shader pass.
11pub type PassConfig = PathReference<PassMeta>;
12
13/// Configuration options for a lookup texture used in the shader.
14pub type TextureConfig = PathReference<TextureMeta>;
15
16/// A reference to a resource on disk.
17#[derive(Debug, Clone)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19pub struct PathReference<M> {
20    /// The fully qualified path to the resource, often a shader source file or a texture.
21    pub path: PathBuf,
22    /// Meta information about the resource.
23    pub meta: M,
24}
25
26/// Meta information about a shader pass.
27#[derive(Debug, Clone)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
29pub struct PassMeta {
30    /// The index of the shader pass relative to its parent preset.
31    pub id: i32,
32    /// The alias of the shader pass if available.
33    pub alias: Option<ShortString>,
34    /// The filtering mode that this shader pass should expect.
35    pub filter: FilterMode,
36    /// The texture addressing (wrap) mode that this shader pass expects.
37    pub wrap_mode: WrapMode,
38    /// The number to which to wrap the frame count before passing it to the uniforms.
39    pub frame_count_mod: u32,
40    /// Whether or not this shader pass expects an SRGB framebuffer output.
41    pub srgb_framebuffer: bool,
42    /// Whether or not this shader pass expects an float framebuffer output.
43    pub float_framebuffer: bool,
44    /// Whether or not to generate mipmaps for the input texture before passing to the shader.
45    pub mipmap_input: bool,
46    /// Specifies the scaling of the output framebuffer for this shader pass.
47    pub scaling: Scale2D,
48}
49
50impl PassMeta {
51    /// If the framebuffer expects a different format than what was defined in the
52    /// shader source, returns such format.
53    #[inline(always)]
54    pub fn get_format_override(&self) -> Option<ImageFormat> {
55        if self.srgb_framebuffer {
56            return Some(ImageFormat::R8G8B8A8Srgb);
57        } else if self.float_framebuffer {
58            return Some(ImageFormat::R16G16B16A16Sfloat);
59        }
60        None
61    }
62
63    #[inline(always)]
64    pub fn get_frame_count(&self, count: usize) -> u32 {
65        (if self.frame_count_mod > 0 {
66            count % self.frame_count_mod as usize
67        } else {
68            count
69        }) as u32
70    }
71}
72
73#[repr(i32)]
74#[derive(Default, Copy, Clone, Debug)]
75#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
76/// The scaling type for the shader pass.
77pub enum ScaleType {
78    #[default]
79    /// Scale by the size of the input quad.
80    Input = 0,
81    /// Scale the framebuffer in absolute units.
82    Absolute,
83    /// Scale by the size of the viewport.
84    Viewport,
85    /// Scale by the size of the original input quad.
86    Original,
87}
88
89/// The scaling factor for framebuffer scaling.
90#[derive(Copy, Clone, Debug)]
91#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
92pub enum ScaleFactor {
93    /// Scale by a fractional float factor.
94    Float(f32),
95    /// Scale by an absolute factor.
96    Absolute(i32),
97}
98
99impl Default for ScaleFactor {
100    fn default() -> Self {
101        ScaleFactor::Float(1.0f32)
102    }
103}
104
105impl From<ScaleFactor> for f32 {
106    fn from(value: ScaleFactor) -> Self {
107        match value {
108            ScaleFactor::Float(f) => f,
109            ScaleFactor::Absolute(f) => f as f32,
110        }
111    }
112}
113
114impl Mul<ScaleFactor> for f32 {
115    type Output = f32;
116
117    fn mul(self, rhs: ScaleFactor) -> Self::Output {
118        match rhs {
119            ScaleFactor::Float(f) => f * self,
120            ScaleFactor::Absolute(f) => f as f32 * self,
121        }
122    }
123}
124
125impl Mul<ScaleFactor> for u32 {
126    type Output = f32;
127
128    fn mul(self, rhs: ScaleFactor) -> Self::Output {
129        match rhs {
130            ScaleFactor::Float(f) => f * self as f32,
131            ScaleFactor::Absolute(f) => (f as u32 * self) as f32,
132        }
133    }
134}
135
136impl FromStr for ScaleType {
137    type Err = ParsePresetError;
138
139    fn from_str(s: &str) -> Result<Self, Self::Err> {
140        match s {
141            "source" => Ok(ScaleType::Input),
142            "viewport" => Ok(ScaleType::Viewport),
143            "absolute" => Ok(ScaleType::Absolute),
144            "original" => Ok(ScaleType::Original),
145            _ => Err(ParsePresetError::InvalidScaleType(s.to_string())),
146        }
147    }
148}
149
150/// Framebuffer scaling parameters.
151#[derive(Debug, Clone)]
152#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
153pub struct Scaling {
154    /// The method to scale the framebuffer with.
155    pub scale_type: ScaleType,
156    /// The factor to scale by.
157    pub factor: ScaleFactor,
158}
159
160/// 2D quad scaling parameters.
161#[derive(Debug, Clone)]
162#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
163pub struct Scale2D {
164    /// Whether or not this combination of scaling factors is valid.
165    pub valid: bool,
166    /// Scaling parameters for the X axis.
167    pub x: Scaling,
168    /// Scaling parameters for the Y axis.
169    pub y: Scaling,
170}
171
172/// Configuration options for a lookup texture used in the shader.
173#[derive(Debug, Clone)]
174#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
175pub struct TextureMeta {
176    /// The name of the texture.
177    pub name: ShortString,
178    /// The wrap (addressing) mode to use when sampling the texture.
179    pub wrap_mode: WrapMode,
180    /// The filter mode to use when sampling the texture.
181    pub filter_mode: FilterMode,
182    /// Whether to generate mipmaps for this texture.
183    pub mipmap: bool,
184}
185
186/// Configuration options for a shader parameter.
187#[derive(Debug, Clone)]
188#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
189pub struct ParameterMeta {
190    /// The name of the parameter.
191    pub name: ShortString,
192    /// The value it is set to in the preset.
193    pub value: f32,
194}
195
196/// A shader preset including all specified parameters, textures, and paths to specified shaders.
197///
198/// A shader preset can be used to create a filter chain runtime instance, or reflected to get
199/// parameter metadata.
200#[derive(Debug, Clone)]
201#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
202pub struct ShaderPreset {
203    /// Used in legacy GLSL shader semantics. If < 0, no feedback pass is used.
204    /// Otherwise, the FBO after pass #N is passed a texture to next frame
205    #[cfg(feature = "parse_legacy_glsl")]
206    pub feedback_pass: i32,
207
208    /// The number of shaders enabled in the filter chain.
209    pub pass_count: i32,
210    // Everything is in Vecs because the expect number of values is well below 64.
211    /// Preset information for each shader.
212    pub passes: Vec<PassConfig>,
213
214    /// Preset information for each texture.
215    pub textures: Vec<TextureConfig>,
216
217    /// Preset information for each user parameter.
218    pub parameters: Vec<ParameterMeta>,
219
220    /// Shader features to enable.
221    pub features: ShaderFeatures,
222}