Fixes#1745: Support out-of-order module scope declarations in WGSL
Fixes#1044: Forbid local variable shadowing in WGSL
Fixes#2076: [wgsl-in] no error for duplicated type definition
Fixes#2071: Global item does not support 'const'
Fixes#2105: [wgsl-in] Type aliases for a vecN<T> doesn't work when constructing vec from a single argument
Fixes#1775: Referencing a function without a return type yields an unknown identifier error.
Fixes#2089: Error span reported on the declaration of a variable instead of its use
Fixes#1996: [wgsl-in] Confusing error: "expected unsigned/signed integer literal, found '1'"
Separate parsing from lowering by generating an AST, which desugars as
much as possible down to something like Naga IR. The AST is then used
to resolve identifiers while lowering to Naga IR.
Co-authored-by: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com>
Co-authored-by: Jim Blandy <jimb@red-bean.com>
* Add support for WGSL's `atomicCompareExchangeWeak` with the `__atomic_compare_exchange_result` struct, and add SPIR-V codegen for it.
Partially addresses https://github.com/gpuweb/gpuweb/pull/2113, #1755.
* Add tests for `atomicCompareExchangeWeak`, and support both u32 and i32 atomics with it.
* More thorough typechecking of the struct returned by `atomicCompareExchangeWeak`.
This is for the same reason that we ignore `dead_code`:
// A lot of the code can be unused based on configuration flags,
// the corresponding warnings aren't helpful.
When lowering `Select` expressions the position could be wrongfully
updated from `AccessBase { constant_index: false }` to
`AccessBase { constant_index: true }` this caused dynamic indexing
in an array behind a structure to fail if it was stored in a constant.
Furthermore the position could also be updated from `Rhs` to
`AccessBase`, this could cause issues because `AccessBase` doesn't
load variables (which `Rhs` does), so accessing a member from a
structure behind a pointer would return the wrong result.
* fix(glsl-out,hlsl-out,msl-out): parenthesize unary negations a la `wgsl` everywhere
Unify parenthesization of unary negations across all backends with what the `wgsl` backend does,
which is `<op>(<expr>)`. This avoids ambiguity with output languages for which `--` is a different
operation; in this case, we've been accidentally emitting prefix decrements.
* build: update `rspirv` 0.11 -> 0.12 (FIXME: use upstream release)
* test: add `operators::negation_avoids_prefix_decrement` test
Co-authored-by: Dzmitry Malyshau <kvark@fastmail.com>
* refactor: satisfy `clippy::borrow_deref_ref`
* chore: satisfy `clippy::ptr_arg`
* refactor: satisfy `clippy::needless_update`
* chore: `allow(clippy::too_many_arguments)` on `write_output_glsl` test
Since this is test code, I don't think there's a strong impetus to refactor types to consolidate
or otherwise alter arguments here. Let's just `allow` this.
* refactor: satisfy `clippy::single_match`
I think it's sixes whether to keep this code as-is or to `allow(...)` as-is. 🤷🏻♂️
* refactor: satisfy `clippy::single_char_pattern`
* refactor: satisfy `clippy::reversed_empty_ranges`
The lint fires because it generally doesn't make sense to use a `Range` built this way; [upstream
`Range` docs]) states:
> It is empty if `start >= end`.
`clippy` wants to help us from naively iterating over a `Range` like this! Thanks, `clippy`!
However, we're not actually using the offending `addresses` variables for iteration. We're using
them as a flat data structure with fields that happen to conceptually match. We can, therefore,
sidestep this lint by "just" inlining into separate variables for start and end instead.
[upstream `Range` docs]: https://doc.rust-lang.org/stable/std/ops/struct.Range.html
* refactor: satisfy `clippy::pattern_type_mismatch`
* chore: `allow(clippy::panic)` for `test`
We definitely should let `panic!(...)` calls exist in `cfg(test)`! It's a very standard way to fail
`#[test]` functions. It seems that previous test authors agree! 😅
* fixup! refactor: satisfy `clippy::pattern_type_mismatch`
* fixup! refactor: satisfy `clippy::single_match`
* Fix incorrect atomic bounds check on metal back-end
Generalize put_atomic_fetch to handle `exchange` as well, rather than special-cased code which didn't do the bounds check (the check handling as fixed in #1703 but only for the fetch cases, exchange was skipped).
Fixes#1848
* Add tests for atomic exchange
Compound assignments on wgsl follow the same semantics as their
underlying operation, this includes the splatting behavior when mixing
scalar and vector operands, which was done for binary operations but not
for compound assignments.
Previously the wgsl frontend wasn't aware of lexical scopes causing all
variables and named expressions to share a single function scope, this
meant that if a variable was defined in a block with the same name as a
variable in the function body, the variable in the function body would
be lost and exiting the block all references to the variable in the
function body would be replaced with the variable of the block.
This commit fixes that by using the previously introduced `SymbolTable`
to track the lexical and perform the variable lookups, scopes are pushed
and popped as defined in the wgsl specification.
The Vulkan decoration rules require us to distinguish vertex shader
inputs, fragment shader inputs, and everything else, so just pass the
stage to `Writer::write_varying`. Together with the SPIRV storage
class, this is sufficient to distinguish all the cases in a way that
closely follows the spec language.
Previously, if a local variable was declared with a constant value, we
would elide the store and instead give the variable an initial value (as
if it was a global variable). This caused variables to not be
re-initialized each time through a loop.
Adds parsing support for methods on the glsl frontend, while `.length` is the only method in the base extensions, there might be more in extensions.
Adds support for the `.length` method and tests for it.
Improves the dot backend output by:
- Linking new nodes to the end of other blocks, instead of the beginning
- Generating merge nodes for conditional statements
- Generating connections from break/continue nodes to their target
- Introducing a "cfg only" mode that only generates statements
* Make some (currently hacky) changes to enable multiview in webgl
* Fix ViewIndex built in for this extension
* Run cargo fmt, fix tests
* Allow specifying if we're targetting webgl in the glsl version
* Document multiview2 extension
* fn embedded -> const fn embedded
* Fix tests
* Fix benches
* Add snapshot tests
* Revamp so that the glsl options have some multiview options. Also add tests
* Make clippy happier
* Go back to having is_webgl be part of Version
* Use wgsl as input for tests
* Rename Version::new_embedded to Version::new_gles, fix glsl validation
* Run cargo fmt
* Fix brand new clippy warnings
* [hlsl-out] fix matCx2 as global uniform
* [hlsl-out] update comments
* [hlsl-out] fix `row_major` not being written on global arrays of matrices and also write it on nested arrays of matrices
* [hlsl-out] fix matCx2's nested inside global arrays
* [hlsl-out] fix struct members of type array<matCx2>
* [hlsl-out] test mat2x4 to make sure our matCx2 code behaves properly
Require at least version 0.7.1 of ron, this version changed how floating points are
serialized by forcing them to always have the decimal part, this makes it backwards
incompatible with our tests because we do a syntatic diff and not a semantic one.
GLSL allows the last case of a switch statement to not have a `break`
statement causing it to be marked as fall-trough, naga's IR on the other
hand doesn't allow the last case to be fall-trough, this is fixed by
force marking it in the glsl frontend as not fall-trough.
GLSL also allows empty switch statements and without default cases,
naga's IR requires there be a default case, this is fixed by adding an
empty default case in the glsl frontend if no default case was present
in the switch statement.
Glsl defines two overloads for smoothstep that accept `min` and `max` as
scalars and the value as a vector, naga's IR is stricter and only allows
operators with the same dimensions, so this inputs must be splatted.