#[derive(Debug, Clone)] pubstruct ParameterInfo { pub qualifier: ParameterQualifier, /// Whether the parameter should be treated as a depth image instead of a /// sampled image. pub depth: bool,
}
/// How the function is implemented #[derive(Clone, Copy)] pubenum FunctionKind { /// The function is user defined
Call(Handle<Function>), /// The function is a builtin Macro(MacroCall),
}
#[derive(Debug)] pubstruct Overload { /// Normalized function parameters, modifiers are not applied pub parameters: Vec<Handle<Type>>, pub parameters_info: Vec<ParameterInfo>, /// How the function is implemented pub kind: FunctionKind, /// Whether this function was already defined or is just a prototype pub defined: bool, /// Whether this overload is the one provided by the language or has /// been redeclared by the user (builtins only) pub internal: bool, /// Whether or not this function returns void (nothing) pub void: bool,
}
bitflags::bitflags! { /// Tracks the variations of the builtin already generated, this is needed because some /// builtins overloads can't be generated unless explicitly used, since they might cause /// unneeded capabilities to be requested #[derive(Default)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] pubstruct BuiltinVariations: u32 { /// Request the standard overloads const STANDARD = 1 << 0; /// Request overloads that use the double type const DOUBLE = 1 << 1; /// Request overloads that use `samplerCubeArray(Shadow)` const CUBE_TEXTURES_ARRAY = 1 << 2; /// Request overloads that use `sampler2DMSArray` const D2_MULTI_TEXTURES_ARRAY = 1 << 3;
}
}
#[derive(Debug, Default)] pubstruct FunctionDeclaration { pub overloads: Vec<Overload>, /// Tracks the builtin overload variations that were already generated pub variations: BuiltinVariations,
}
#[derive(Debug, Clone)] pubstruct VariableReference { pub expr: Handle<Expression>, /// Whether the variable is of a pointer type (and needs loading) or not pub load: bool, /// Whether the value of the variable can be changed or not pub mutable: bool, pub constant: Option<(Handle<Constant>, Handle<Type>)>, pub entry_arg: Option<usize>,
}
#[derive(Debug, Clone)] pubenum HirExprKind {
Access {
base: Handle<HirExpr>,
index: Handle<HirExpr>,
},
Select {
base: Handle<HirExpr>,
field: String,
},
Literal(Literal),
Binary {
left: Handle<HirExpr>,
op: BinaryOperator,
right: Handle<HirExpr>,
},
Unary {
op: UnaryOperator,
expr: Handle<HirExpr>,
},
Variable(VariableReference),
Call(FunctionCall), /// Represents the ternary operator in glsl (`:?`)
Conditional { /// The expression that will decide which branch to take, must evaluate to a boolean
condition: Handle<HirExpr>, /// The expression that will be evaluated if [`condition`] returns `true` /// /// [`condition`]: Self::Conditional::condition
accept: Handle<HirExpr>, /// The expression that will be evaluated if [`condition`] returns `false` /// /// [`condition`]: Self::Conditional::condition
reject: Handle<HirExpr>,
},
Assign {
tgt: Handle<HirExpr>,
value: Handle<HirExpr>,
}, /// A prefix/postfix operator like `++`
PrePostfix { /// The operation to be performed
op: BinaryOperator, /// Whether this is a postfix or a prefix
postfix: bool, /// The target expression
expr: Handle<HirExpr>,
}, /// A method call like `what.something(a, b, c)`
Method { /// expression the method call applies to (`what` in the example)
expr: Handle<HirExpr>, /// the method name (`something` in the example)
name: String, /// the arguments to the method (`a`, `b`, and `c` in the example)
args: Vec<Handle<HirExpr>>,
},
}
#[derive(Debug, Hash, PartialEq, Eq)] pubenum QualifierKey<'a> {
String(Cow<'a, str>), /// Used for `std140` and `std430` layout qualifiers
Layout, /// Used for image formats
Format,
}
#[derive(Debug, Default)] pubstruct TypeQualifiers<'a> { pub span: Span, pub storage: (StorageQualifier, Span), pub invariant: Option<Span>, pub interpolation: Option<(Interpolation, Span)>, pub precision: Option<(Precision, Span)>, pub sampling: Option<(Sampling, Span)>, /// Memory qualifiers used in the declaration to set the storage access to be used /// in declarations that support it (storage images and buffers) pub storage_access: Option<(StorageAccess, Span)>, pub layout_qualifiers: crate::FastHashMap<QualifierKey<'a>, (QualifierValue, Span)>,
}
impl<'a> TypeQualifiers<'a> { /// Appends `errors` with errors for all unused qualifiers pubfn unused_errors(&self, errors: &mutVec<super::Error>) { iflet Some(meta) = self.invariant {
errors.push(super::Error {
kind: super::ErrorKind::SemanticError( "Invariant qualifier can only be used in in/out variables".into(),
),
meta,
});
}
iflet Some((_, meta)) = self.interpolation {
errors.push(super::Error {
kind: super::ErrorKind::SemanticError( "Interpolation qualifiers can only be used in in/out variables".into(),
),
meta,
});
}
iflet Some((_, meta)) = self.sampling {
errors.push(super::Error {
kind: super::ErrorKind::SemanticError( "Sampling qualifiers can only be used in in/out variables".into(),
),
meta,
});
}
iflet Some((_, meta)) = self.storage_access {
errors.push(super::Error {
kind: super::ErrorKind::SemanticError( "Memory qualifiers can only be used in storage variables".into(),
),
meta,
});
}
/// Removes the layout qualifier with `name`, if it exists and adds an error if it isn't /// a [`QualifierValue::Uint`] pubfn uint_layout_qualifier(
&mutself,
name: &'a str,
errors: &mut Vec<super::Error>,
) -> Option<u32> { matchself
.layout_qualifiers
.remove(&QualifierKey::String(name.into()))
{
Some((QualifierValue::Uint(v), _)) => Some(v),
Some((_, meta)) => {
errors.push(super::Error {
kind: super::ErrorKind::SemanticError("Qualifier expects a uint value".into()),
meta,
}); // Return a dummy value instead of `None` to differentiate from // the qualifier not existing, since some parts might require the // qualifier to exist and throwing another error that it doesn't // exist would be unhelpful
Some(0)
}
_ => None,
}
}
/// Removes the layout qualifier with `name`, if it exists and adds an error if it isn't /// a [`QualifierValue::None`] pubfn none_layout_qualifier(&mutself, name: &'a str, errors: &mut Vec<super::Error>) -> bool { matchself
.layout_qualifiers
.remove(&QualifierKey::String(name.into()))
{
Some((QualifierValue::None, _)) => true,
Some((_, meta)) => {
errors.push(super::Error {
kind: super::ErrorKind::SemanticError( "Qualifier doesn't expect a value".into(),
),
meta,
}); // Return a `true` to since the qualifier is defined and adding // another error for it not being defined would be unhelpful true
}
_ => false,
}
}
}
// TODO: Encode precision hints in the IR /// A precision hint used in GLSL declarations. /// /// Precision hints can be used to either speed up shader execution or control /// the precision of arithmetic operations. /// /// To use a precision hint simply add it before the type in the declaration. /// ```glsl /// mediump float a; /// ``` /// /// The default when no precision is declared is `highp` which means that all /// operations operate with the type defined width. /// /// For `mediump` and `lowp` operations follow the spir-v /// [`RelaxedPrecision`][RelaxedPrecision] decoration semantics. /// /// [RelaxedPrecision]: https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#_a_id_relaxedprecisionsection_a_relaxed_precision #[derive(Debug, Clone, PartialEq, Copy)] pubenum Precision { /// `lowp` precision
Low, /// `mediump` precision
Medium, /// `highp` precision
High,
}
impl ParameterQualifier { /// Returns true if the argument should be passed as a lhs expression pubconstfn is_lhs(&self) -> bool { match *self {
ParameterQualifier::Out | ParameterQualifier::InOut => true,
_ => false,
}
}
}
/// The GLSL profile used by a shader. #[derive(Debug, Clone, Copy, PartialEq)] pubenum Profile { /// The `core` profile, default when no profile is specified.
Core,
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-06-19)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.