Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[naga wgsl-in] Ensure constant evaluation correctly handles Composes of vector ZeroValues #7138

Merged
merged 1 commit into from
Feb 14, 2025

Conversation

jamienicol
Copy link
Contributor

Connections
Fixes #7137

Description
Constant evaluation often relies on the expressions being evaluated being either a Literal, or a vector Compose for which it can iterate over each component.

Currently this is achieved by calling two functions:

  • eval_zero_value_and_splat() which transforms a scalar ZeroValue into a Literal, or a Splat or vector ZeroValue into a Compose of Literals.

  • proc::flatten_compose() takes potentially nested nested Compose and Splat expressions and produces an flat iterator that yields each component. eg vec3(vec2(0), 0) would yield Literal(0), Literal(0), Literal(0).

For component-wise vector operations, we can then iterate through each component of the flattened compose and apply the operation. When there are multiple operands it is crucial they have both been flattened correctly so that we use the corresponding component from each operand together.

Where this falls short is if a vector ZeroValue is nested within a Compose. eg vec3(vec2(), 0). flatten_compose() is unable to flatten this, and the resulting iterator will yield ZeroValue, Literal(0)

This causes various issues. Take binary_op(), for example. If we attempt to add vec3(1, 2, 3) to our unflattenable vec3(vec2(), 0) this should be evaluated component-wise as 0 + 1, 0 + 2, and 0 + 3. As this has not been correctly flattened, however, we will evaluate vec2() + 1, and 0 + 2, which is simply incorrect.

To solve this, we make eval_zero_value_and_splat() recursively call itself for each component if the expression is a Compose. This ensures no ZeroValues will be present during flatten_compose(), meaning it will successfully fully flatten the expression.

Testing
Added snapshot tests

Checklist

  • Run cargo fmt.
  • Run cargo clippy. If applicable, add:
  • Run cargo xtask test to run tests.
  • Add change to CHANGELOG.md. See simple instructions inside file.

…of vector ZeroValues

Constant evaluation often relies on the expressions being evaluated
being either a Literal, or a vector Compose for which it can iterate
over each component.

Currently this is achieved by calling two functions:

* eval_zero_value_and_splat() which transforms a scalar ZeroValue into a
  Literal, or a Splat or vector ZeroValue into a Compose of Literals.

* proc::flatten_compose() takes potentially nested nested Compose and
  Splat expressions and produces an flat iterator that yields each
  component. eg `vec3(vec2(0), 0)` would yield `Literal(0), Literal(0),
  Literal(0)`.

For component-wise vector operations, we can then iterate through each
component of the flattened compose and apply the operation. When there
are multiple operands it is crucial they have both been flattened
correctly so that we use the corresponding component from each operand
together.

Where this falls short is if a *vector* ZeroValue is nested within a
Compose. eg `vec3(vec2(), 0)`. flatten_compose() is unable to flatten
this, and the resulting iterator will yield `ZeroValue, Literal(0)`

This causes various issues. Take binary_op(), for example. If we attempt
to add `vec3(1, 2, 3)` to our unflattenable `vec3(vec2(), 0)` this
should be evaluated component-wise as 0 + 1, 0 + 2, and 0 + 3. As this
has not been correctly flattened, however, we will evaluate vec2() + 1,
and 0 + 2, which is simply incorrect.

To solve this, we make eval_zero_value_and_splat() recursively call
itself for each component if the expression is a Compose. This ensures
no ZeroValues will be present during flatten_compose(), meaning it will
successfully fully flatten the expression.
@cwfitzgerald cwfitzgerald merged commit 4bb09e1 into gfx-rs:trunk Feb 14, 2025
34 checks passed
@jamienicol jamienicol deleted the compose-vec-zeroval branch February 14, 2025 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Naga: Composes of vector ZeroValues trips up constant evaluation
3 participants