Commit Graph

400 Commits

Author SHA1 Message Date
Jim Blandy
ed3006ccc6 [naga spv-out] Spill arrays and matrices for runtime indexing.
Improve handling of `Access` expressions whose base is an array or
matrix (not a pointer to such), and whose index is not known at
compile time. SPIR-V does not have instructions that can do this
directly, so spill such values to temporary variables, and perform the
accesses using `OpAccessChain` instructions applied to the
temporaries.

When performing chains of accesses like `a[i].x[j]`, do not reify
intermediate values; generate a single `OpAccessChain` for the entire
thing.

Remove special cases for arrays; the same code now handles arrays and
matrices.

Update validation to permit dynamic indexing of matrices.

For details, see the comments on the new tracking structures in
`naga:🔙:spv::Function`.

Add snapshot test `index-by-value.wgsl`.

Fixes #6358.
Fixes #4337.
Alternative to #6362.
2024-10-11 08:27:15 -07:00
Jim Blandy
475a716822 [naga spv-out] Let write_checked_load take AccessTypeAdjustment.
Let `BlockContext::write_checked_load` take an `AccessTypeAdjustment`
argument, so that the caller can choose what adjustment to apply to
`pointer`.
2024-10-11 08:27:15 -07:00
Jim Blandy
26a95fd270 [naga spv-out] Add some tracing output to Writer::write_function. 2024-10-11 08:27:15 -07:00
Jim Blandy
436ffba77a [naga spv-out] Introduce Writer::get_resolution_pointer_id.
Introduce a new helper function,
`naga:🔙:spv::Writer::get_resolution_pointer_id`. Use it in
`BlockContext::write_expression_pointer`.
2024-10-11 08:27:15 -07:00
Jim Blandy
0f17ad6455 [naga] Add new function, GuardedIndex::from_expression.
Pull out the code to build a `naga::proc::index::GuardedIndex` from a
`Handle<Expression>` into its own function,
`GuardedIndex::from_expression`. Use that function in
`GuardedIndex::try_resolve_to_constant`.
2024-10-11 08:27:15 -07:00
Jim Blandy
0392613b5a [naga spv-out] Abstract out NumericType::from_inner.
Pull out the code for building a `naga:🔙:spv::NumericType` from a
`TypeInner` into its own function, `NumericType::from_inner`. Use that
in `LocalType::from_inner`.
2024-10-11 08:27:15 -07:00
Jim Blandy
4427ff9622 [naga spv-out] Use crate::proc::index::GuardedIndex.
Replace qualified paths with a `use` directive.
2024-10-11 08:27:15 -07:00
Jim Blandy
57b8858f96 [naga spv-out] Gather array, matrix, and vector cases.
This commit is just code motion.
2024-10-11 08:27:15 -07:00
Jim Blandy
f9075fc4b8 [naga] Test access to a member/element through a pointer. 2024-10-11 08:27:15 -07:00
Jim Blandy
b9f1e4a266 [naga spv-out] Clean up write_expression_pointer type adjustment.
Replace the `return_type_override` argument of
`BlockContext::write_expression_pointer` with an enum that says how to
derive the return type from `expr_handle`'s type.

Introduce a new type, `AccessTypeAdjustment`, that covers possible
derivation rules.

This simplifies callers and the callee, in part by making the possible
alternatives less general, and by giving them explicit names (the
variants of the `AccessTypeAdjustment` enum).
2024-10-11 08:27:15 -07:00
Jim Blandy
d034c4b428 [naga spv-out] Move code to load a pointer into its own function.
Introduce a new function,
`naga:🔙:spv::BlockContext::write_checked_load`, that does the
work of `Expression::Load`.

This change is just code motion, and should have no effect on
behavior. The new function will be used in later commits.
2024-10-11 08:27:15 -07:00
Ronny Chan
73764fdc6a
[naga/wgsl-out]: polyfill inverse function (#6385) 2024-10-11 15:56:12 +02:00
Jim Blandy
ae52e5dc96 [naga spv-out] Delete BlockContext::is_intermediate; use types.
Delete the function `BlockContext::is_intermediate`. Instead, have
`Access` and `AccessIndex` instructions decide whether to defer code
generation based on the type of the base expression: indexing
operations on pointers are deferred; anything else is not.
2024-10-10 07:42:02 -07:00
Jim Blandy
5c6b00886e [naga spv-out] Simplify Writer::get_pointer_id.
Simplify the definition of `naga:🔙:spv::Writer::get_pointer_id`
by using `get_type_id`'s ability to handle `LocalType::Pointer`.

This means that `get_pointer_id` is no longer fallible, and no longer
needs a type arena. Simplify callers, as well as the
`BlockContext::get_pointer_id` convenience function.
2024-10-10 07:41:35 -07:00
Jim Blandy
908e8353a8 [naga spv-out] Expand LocalType to permit pointers to matrices.
In `back::spv`:

- Factor out the numeric variants of `LocalType` into a
  new enum, `NumericType`.

- Split the `Value` variant into `Numeric` and `LocalPointer`
  variants, and let `LocalPointer` point to any numeric type,
  including matrices.

In subsequent commits, we'll need to spill matrices out into temporary
local variables. This means we'll need to generate SPIR-V
pointer-to-matrix types, so `LocalType` needs to be able to represent
that.
2024-10-10 07:41:15 -07:00
Jim Blandy
0392cb783d [naga spv-out] Rename make_local to LocalType::from_inner.
Change the free function `back::spv::make_local` into an associated
function `LocalType::from_inner`.
2024-10-10 07:41:15 -07:00
Asher Jingkong Chen
bf33e481f3
[naga msl-out] Implement atomicCompareExchangeWeak for MSL backend (#6265) 2024-10-10 12:45:24 +02:00
Jim Blandy
3693da27f9 [naga spv-out] Bounds-check runtime-sized array access correctly.
Do not neglect to apply bounds checks to indexing operations on
runtime-sized arrays, even when they are accessed via an `AccessIndex`
instruction.

Before this commit, `BlockContext::write_expression_pointer` would not
apply bounds checks to `OpAccessChain` indices provided by an
`AccessIndex` instruction, apparently with the rationale that any
out-of-bounds accesses should have been reported by constant
evaluation.

While it is true that the `index` operand of an `AccessIndex`
expression is known at compile time, and that the WGSL constant
evaluation rules require accesses that can be statically determined to
be out-of-bounds to be shader creation or pipeline creation time
errors, accesses to runtime-sized arrays don't follow this pattern:
even if the index is known, the length with which it must be compared
is not.

Fixes #4441.
2024-10-08 11:53:15 -07:00
Jim Blandy
7283185305 [naga] Extend snapshot tests for bounds checks.
Extend the snapshot tests for bounds checking to cover the case where
a runtime-sized array is indexed by a constant.
2024-10-08 11:53:15 -07:00
Jim Blandy
5a6b749335 [naga spv-out] Let BoundsCheckResult supply the index value.
Let `BoundsCheckResult::Conditional` provide both the condition to
check before carrying out the access, and the index to use for that
access. The `Conditional` variant indicates that we generated a
runtime bounds check, which implies we must have had a SPIR-V id for
the index to pass to that check, so there's no reason not to provide
that to the callers - especially if the bounds check code was able to
reduce it to a known constant.

At the moment, this is not much of a refactor, but later commits will
use `GuardedIndex` in more places, at which point this will avoid a
re-matching and assertion.
2024-10-08 11:53:15 -07:00
Jim Blandy
69ab63ca34 [naga spv-out] Abstract out OpAccessChain index production.
Abstract the code from `write_expression_pointer` to handle one
indexing operation out into its own function,
`BlockContext::write_access_chain_index`.
2024-10-08 11:53:15 -07:00
Jim Blandy
3d85781f05 [naga spv-out] Consolidate code to find index values.
Let the SPIR-V backend use `GuardedIndex::try_resolve_to_constant`,
rather than writing out its definition in `write_restricted_index` and
`write_index_comparison`.

Call `try_resolve_to_constant` in one place, in `write_bounds_check`,
and simply pass the `GuardedIndex` into subroutines.

Reduce `write_restricted_index` and `write_index_comparison` to case
analysis and code generation.

Note that this commit does have a benign effect on SPIR-V snapshot
output for programs like this:

    let one_i = 1i;
    var vec0 = vec3<i32>();
    vec0[one_i] = 1;

The value indexing `vec0` here is an `i32`, but after this commit, the
operand to `OpAccessChain` becomes a `u32` constant (with the same
value).

This is because `write_bounds_check` now calls
`try_resolve_to_constant` itself, rather than deferring this work to
its callees, so it may return `BoundsCheckResult::KnownInBounds` even
when the `Unchecked` policy is in force. This directs the caller,
`write_expression_pointer`, to treat the `OpAccessChain` operand as a
fresh `u32` constant, rather than simply passing through the original
`i32` expression.
2024-10-08 11:53:15 -07:00
Jim Blandy
287ca16b52 [naga spv-out] Abstract extending a bounds check condition chain.
Introduce a new function,
`BlockContext::extend_bounds_check_condition_chain`, which adds a new
boolean condition to the chain of bounds checks guarding an
`OpAccessChain` instruction.
2024-10-08 11:53:15 -07:00
Jim Blandy
21c527a458 [naga spv-out] Doc fix: typo 2024-10-08 11:53:15 -07:00
Jim Blandy
634a97fcb8 [naga spv-out] Abstract out non-uniform binding array access test.
Introduce a new function,
`BlockContext::is_nonuniform_binding_array_access`, which determines
whether a given array access expression means that the `OpAccessChain`
instruction must have a `NonUniform` decoration.
2024-10-08 11:53:15 -07:00
ChosenName
43cb730d58
[naga] added DrawID (#6325) 2024-10-08 13:00:00 +00:00
Jim Blandy
e432980a73 [naga spv-out] Don't emit unreachable blocks that jump into loops.
When generating SPIR-V, avoid generating unreachable blocks following
statements like `break`, `return`, and so on that cause non-local
exits. These unreachable blocks can cause SPIR-V validation to fail.

Fixes #6220.
2024-10-03 21:07:18 -07:00
Jim Blandy
04182c24ec [naga spv-out] Make write_block and its types private.
Make `naga:🔙:spv::BlockContext::write_block` private to
`naga:🔙:spv::block`. Introduce a new `pub(super)` function,
`write_function_body`, for `Writer::write_function` to call.

Make `BlockExit` private to `naga:🔙:spv::block`.

Move `LoopContext` from `naga:🔙:spv` into
`naga:🔙:spv::block`, and make it private.
2024-10-03 21:07:18 -07:00
Jim Blandy
d3e09dd63a [naga spv-out] Consolidate explanation of global wrapping.
Consolidate the explanation of why and how we wrap Naga global
variables in structs to satisfy Vulkan's requirements, and include it
in the documentation for `back::spv::GlobalVariable`.

Clarify `GlobalVariable`'s members documentation.
2024-10-03 10:13:08 -07:00
Erich Gubler
6e528aaf24 style: split (most) string literals over 100-column line width limit 2024-10-03 10:57:28 -04:00
Erich Gubler
9f275f7655 style: remove comments from MathFunction type res. that stop rustfmt 2024-10-03 10:57:28 -04:00
Erich Gubler
25b2b6afa1 style: newline b/w Span::{UNDEFINED, new} 2024-10-03 10:57:28 -04:00
Erich Gubler
78928654a2 style(wgsl-in): unblock rustfmt in Error::as_parse_error 2024-10-03 10:57:28 -04:00
Erich Gubler
3d584f99ed refactor(spv-out): linkify docs. ref. to write_bounds_check 2024-10-02 22:35:09 -04:00
Jim Blandy
215f0fc887 [naga spv-out] Internal doc fixes for back::spv::index.
In `naga:🔙:spv::index`, clarify documentation for:
- `BoundsCheckResult`
- `write_index_comparison`
- `write_bounds_check`
2024-10-02 22:35:09 -04:00
sagudev
2d82054ae4 [wgsl-in, spv-out] Allow dynamic indexing of arrays by value.
Bring https://github.com/gfx-rs/naga/pull/723 back from the dead.

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
Co-authored-by: Jim Blandy <jimb@red-bean.com>
2024-10-02 18:07:02 -07:00
Jim Blandy
2021e7f29f [naga spv-out] Document and refactor write_runtime_array_length.
Document and refactor
`naga:🔙:spv::BlockContext::write_runtime_array_length`.

Don't try to handle finding the length of a particular element of a
`binding_array<array<T>>`. The SPIR-V backend doesn't wrap that type
correctly anyway; #6333 changes the validator to forbid such types.
Instead, assume that the elements of a `binding_array<T>` are always
structs whose final members may be a runtime-sized array.

Pull out consistency checks after the analysis of the array
expression, so that we always carry out all the checks regardless of
what path we took to produce the information.
2024-09-27 17:02:34 -07:00
Jim Blandy
259592b926 [naga spv-out] Update Vulkan spec section number, and provide link. 2024-09-27 17:02:34 -07:00
Jim Blandy
04032905ef [naga spv-out] Replace match with equivalent !=. 2024-09-27 17:02:34 -07:00
Jim Blandy
98c4d6f42e
[naga] Permit only structs as binding array elements. (#6333)
Require `T` to be a struct in `binding_array<T, ...>`; do not permit
arrays.

In #5428, the validator was changed to accept binding array types that
the SPIR-V backend couldn't properly emit. Specifically, the validator
was changed to accept `binding_array<array<T>>`, but the SPIR-V
backend wasn't changed to wrap the binding array elements in a SPIR-V
struct type, as Vulkan requires. So the type would be accepted by the
validator, and then rejected by the backend.
2024-09-27 17:00:21 -07:00
Samson
866be693d6
[naga] Handle phony statements properly by treating them as named expressions (#6328)
* [naga wgsl-in] phony assignments add named expressions

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* [naga wgsl-out] write out _naga_phony as phony

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* Add test

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* use statement span

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* every phony has same name

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

---------

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
2024-09-27 14:52:53 -07:00
Jim Blandy
e7f891bf2b
[naga] Remove redundant handle ordering check from validator. (#6321)
`Validator::validate_module_handles` already ensures that types refer
only to other types appearing earlier in the arena than themselves, so
this check in `Validator::validate_type` is redundant.
2024-09-25 17:10:27 -04:00
Hamir Mahal
8e787eb70a
style: simplify string formatting for readability (#6316) 2024-09-24 23:40:53 -04:00
dependabot[bot]
e7c139b1d4
build(deps): bump the patch-updates group with 9 updates (#6312)
Bumps the patch-updates group with 9 updates:

| Package | From | To |
| --- | --- | --- |
| [thiserror](https://github.com/dtolnay/thiserror) | `1.0.63` | `1.0.64` |
| [unicode-xid](https://github.com/unicode-rs/unicode-xid) | `0.2.5` | `0.2.6` |
| [clap](https://github.com/clap-rs/clap) | `4.5.17` | `4.5.18` |
| [clap_builder](https://github.com/clap-rs/clap) | `4.5.17` | `4.5.18` |
| [clap_derive](https://github.com/clap-rs/clap) | `4.5.13` | `4.5.18` |
| [quick-xml](https://github.com/tafia/quick-xml) | `0.36.1` | `0.36.2` |
| [thiserror-impl](https://github.com/dtolnay/thiserror) | `1.0.63` | `1.0.64` |
| [unicode-id-start](https://github.com/Boshen/unicode-id-start) | `1.2.0` | `1.3.0` |
| [unicode-width](https://github.com/unicode-rs/unicode-width) | `0.1.13` | `0.1.14` |


Updates `thiserror` from 1.0.63 to 1.0.64
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.63...1.0.64)

Updates `unicode-xid` from 0.2.5 to 0.2.6
- [Changelog](https://github.com/unicode-rs/unicode-xid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/unicode-rs/unicode-xid/compare/v0.2.5...v0.2.6)

Updates `clap` from 4.5.17 to 4.5.18
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.17...clap_complete-v4.5.18)

Updates `clap_builder` from 4.5.17 to 4.5.18
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.5.17...v4.5.18)

Updates `clap_derive` from 4.5.13 to 4.5.18
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.5.13...v4.5.18)

Updates `quick-xml` from 0.36.1 to 0.36.2
- [Release notes](https://github.com/tafia/quick-xml/releases)
- [Changelog](https://github.com/tafia/quick-xml/blob/master/Changelog.md)
- [Commits](https://github.com/tafia/quick-xml/compare/v0.36.1...v0.36.2)

Updates `thiserror-impl` from 1.0.63 to 1.0.64
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.63...1.0.64)

Updates `unicode-id-start` from 1.2.0 to 1.3.0
- [Commits](https://github.com/Boshen/unicode-id-start/commits)

Updates `unicode-width` from 0.1.13 to 0.1.14
- [Commits](https://github.com/unicode-rs/unicode-width/compare/v0.1.13...v0.1.14)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: unicode-xid
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: clap
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: clap_builder
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: clap_derive
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: quick-xml
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: thiserror-impl
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: unicode-id-start
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: patch-updates
- dependency-name: unicode-width
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-22 23:24:12 -04:00
Jasper St. Pierre
390a4169fb naga: Don't consider per-polygon inputs to be subgroup uniform
Implementations can absolutely pack multiple triangles per subgroup.

Fixes #6270.
2024-09-22 03:57:41 -04:00
Erich Gubler
b54fb72d4a
chore: un-regress unused_qualifications lint in naga::front::spv (#6297)
Regressed in #5824.
2024-09-20 09:29:05 +02:00
Erich Gubler
f942ceef9b docs(msl-out): note that Dawn also avoids loop UB like we do 2024-09-18 09:12:58 -07:00
Jim Blandy
3fda684eb9 [naga msl-out] Defeat the MSL compiler's infinite loop analysis.
See the comments in the code for details.

This patch emits the definition of the macro only when the first loop
is encountered. This does make that first loop's code look a bit odd:
it would be more natural to define the macro at the top of the
file. (See the modified files in `naga/tests/out/msl`.)

Rejected alternatives:

- We could emit the macro definition unconditionally at the top of the
  file. But this changes every MSL snapshot output file, whereas only
  eight of them actually contain loops.

- We could have the validator flag modules that contain loops. But the
  changes end up being not small, and spread across the validator, so
  this seems disproportionate. If we had other consumers of this
  information, it might make sense.

- We could change the MSL backend to allow text to be generated out of
  order, so that we can decide whether to define the macro after we've
  generated all the function bodies. But at the moment this seems like
  unnecessary complexity, although it might be worth doing in the
  future if we had additional uses for it - say, to conditionally emit
  helper function definitions.

Fixes #4972.
2024-09-18 11:01:51 -04:00
Schell Carl Scivally
fc85e4f970
spv-in parse more atomic ops (#5824)
* add parsing for spirv::Op::AtomicLoad and spirv::Op::AtomicStore

* spv-in parse AtomicExchange and AtomicCompareExchange

* add atomic i decrement

* bookend atomic store statement with emmitter.finish/emitter.start to suppress a double load expression

bookend atomic result expressions with emitter.finish/start to prevent double defs

* add atomic iadd, isub, smin, umin, smax, umax, and, or, xor

* parse atomic flag test and set, parse atomic flag clear

* remove atomic compare exchange work

* changelog

* moved spirv tests into front/spv/mod.rs

* feature gate atomic spv tests because they require wgsl-[in,out]

* BlockContext::get_contained_global_variable returns Result

* Generate spans covering the entire instruction.

Granted, there is pre-existing code in the SPIR-V front end that gets
this wrong, but:

It doesn't make sense to read `self.data_offset`, and then immediately
pass that to `self.span_from_with_op`. The point of that function is
to make the span cover the entire instruction, operands included.

* Move `From` implementation into spv front end

* doc comments, minor cleanups

* remove parsing of OpAtomicFlagClear and OpAtomicFlagTestAndSet

* sync atomic spvasm files

---------

Co-authored-by: Jim Blandy <jimb@red-bean.com>
2024-09-18 05:39:36 +00:00
Dzmitry Malyshau
eb18854b46 spv-out: configure source language in debug info 2024-09-13 11:37:23 -07:00