summaryrefslogtreecommitdiffstats
path: root/third_party/rust/naga/src/valid
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/naga/src/valid')
-rw-r--r--third_party/rust/naga/src/valid/analyzer.rs69
-rw-r--r--third_party/rust/naga/src/valid/type.rs2
2 files changed, 59 insertions, 12 deletions
diff --git a/third_party/rust/naga/src/valid/analyzer.rs b/third_party/rust/naga/src/valid/analyzer.rs
index df6fc5e9b0..03fbc4089b 100644
--- a/third_party/rust/naga/src/valid/analyzer.rs
+++ b/third_party/rust/naga/src/valid/analyzer.rs
@@ -145,10 +145,35 @@ pub struct SamplingKey {
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
+/// Information about an expression in a function body.
pub struct ExpressionInfo {
+ /// Whether this expression is uniform, and why.
+ ///
+ /// If this expression's value is not uniform, this is the handle
+ /// of the expression from which this one's non-uniformity
+ /// originates. Otherwise, this is `None`.
pub uniformity: Uniformity,
+
+ /// The number of statements and other expressions using this
+ /// expression's value.
pub ref_count: usize,
+
+ /// The global variable into which this expression produces a pointer.
+ ///
+ /// This is `None` unless this expression is either a
+ /// [`GlobalVariable`], or an [`Access`] or [`AccessIndex`] that
+ /// ultimately refers to some part of a global.
+ ///
+ /// [`Load`] expressions applied to pointer-typed arguments could
+ /// refer to globals, but we leave this as `None` for them.
+ ///
+ /// [`GlobalVariable`]: crate::Expression::GlobalVariable
+ /// [`Access`]: crate::Expression::Access
+ /// [`AccessIndex`]: crate::Expression::AccessIndex
+ /// [`Load`]: crate::Expression::Load
assignable_global: Option<Handle<crate::GlobalVariable>>,
+
+ /// The type of this expression.
pub ty: TypeResolution,
}
@@ -311,14 +336,20 @@ pub enum UniformityDisruptor {
}
impl FunctionInfo {
- /// Adds a value-type reference to an expression.
+ /// Record a use of `expr` of the sort given by `global_use`.
+ ///
+ /// Bump `expr`'s reference count, and return its uniformity.
+ ///
+ /// If `expr` is a pointer to a global variable, or some part of
+ /// a global variable, add `global_use` to that global's set of
+ /// uses.
#[must_use]
fn add_ref_impl(
&mut self,
- handle: Handle<crate::Expression>,
+ expr: Handle<crate::Expression>,
global_use: GlobalUse,
) -> NonUniformResult {
- let info = &mut self.expressions[handle.index()];
+ let info = &mut self.expressions[expr.index()];
info.ref_count += 1;
// mark the used global as read
if let Some(global) = info.assignable_global {
@@ -327,22 +358,38 @@ impl FunctionInfo {
info.uniformity.non_uniform_result
}
- /// Adds a value-type reference to an expression.
+ /// Record a use of `expr` for its value.
+ ///
+ /// This is used for almost all expression references. Anything
+ /// that writes to the value `expr` points to, or otherwise wants
+ /// contribute flags other than `GlobalUse::READ`, should use
+ /// `add_ref_impl` directly.
#[must_use]
- fn add_ref(&mut self, handle: Handle<crate::Expression>) -> NonUniformResult {
- self.add_ref_impl(handle, GlobalUse::READ)
+ fn add_ref(&mut self, expr: Handle<crate::Expression>) -> NonUniformResult {
+ self.add_ref_impl(expr, GlobalUse::READ)
}
- /// Adds a potentially assignable reference to an expression.
- /// These are destinations for `Store` and `ImageStore` statements,
- /// which can transit through `Access` and `AccessIndex`.
+ /// Record a use of `expr`, and indicate which global variable it
+ /// refers to, if any.
+ ///
+ /// Bump `expr`'s reference count, and return its uniformity.
+ ///
+ /// If `expr` is a pointer to a global variable, or some part
+ /// thereof, store that global in `*assignable_global`. Leave the
+ /// global's uses unchanged.
+ ///
+ /// This is used to determine the [`assignable_global`] for
+ /// [`Access`] and [`AccessIndex`] expressions that ultimately
+ /// refer to a global variable. Those expressions don't contribute
+ /// any usage to the global themselves; that depends on how other
+ /// expressions use them.
#[must_use]
fn add_assignable_ref(
&mut self,
- handle: Handle<crate::Expression>,
+ expr: Handle<crate::Expression>,
assignable_global: &mut Option<Handle<crate::GlobalVariable>>,
) -> NonUniformResult {
- let info = &mut self.expressions[handle.index()];
+ let info = &mut self.expressions[expr.index()];
info.ref_count += 1;
// propagate the assignable global up the chain, till it either hits
// a value-type expression, or the assignment statement.
diff --git a/third_party/rust/naga/src/valid/type.rs b/third_party/rust/naga/src/valid/type.rs
index d44a295b1a..b8eb618ed4 100644
--- a/third_party/rust/naga/src/valid/type.rs
+++ b/third_party/rust/naga/src/valid/type.rs
@@ -510,7 +510,6 @@ impl super::Validator {
ti.uniform_layout = Ok(Alignment::MIN_UNIFORM);
let mut min_offset = 0;
-
let mut prev_struct_data: Option<(u32, u32)> = None;
for (i, member) in members.iter().enumerate() {
@@ -662,6 +661,7 @@ impl super::Validator {
// Currently Naga only supports binding arrays of structs for non-handle types.
match gctx.types[base].inner {
crate::TypeInner::Struct { .. } => {}
+ crate::TypeInner::Array { .. } => {}
_ => return Err(TypeError::BindingArrayBaseTypeNotStruct(base)),
};
}