254 Commits

Author SHA1 Message Date
Erich Gubler
5146b3f8ae fix(namer): normalize ":<>," characters to a snake case separator 2025-10-01 08:50:37 -04:00
Erich Gubler
90702156af fix(namer): escape, rather than strip, non-ASCII ident. characters
Escape non-ASCII identifier characters with `write!(…, "u{:04x}", …)`,
surrounding with `_` as appropriate. This solves (1) a debugging issue
where stripped characters would otherwise be invisible, and (2) failure
to re-validate that stripped identifiers didn't start with an ASCII
digit.

I've confirmed that this fixes [bug
1978197](https://bugzilla.mozilla.org/show_bug.cgi?id=1978197) on the
Firefox side.
2025-10-01 08:50:37 -04:00
Nils Hasenbanck
8c4aebc0c1
(Naga) Implement OpImageGather and OpImageDrefGather when ingesting SPIR-V (#8280) 2025-09-29 13:15:32 -04:00
Nils Hasenbanck
8cb94db802
(Naga) Add support for Storage Image Multisample when ingesting SPIR-V (#8270) 2025-09-29 11:45:39 -04:00
Nils Hasenbanck
2f7ebf1401
(Naga) Add support for Descriptor Runtime Indexing when ingesting SPIR-V (#8256) 2025-09-25 08:25:04 -04:00
Cai Bear
d2ee4b8be5
Fix #8151. (#8215) 2025-09-24 16:03:58 +00:00
Teodor Tanasoaia
0b38e96379
[msl] vertex pulling: fix unpacking snorm16x2 & snorm16x4 (#8249) 2025-09-19 18:11:31 -04:00
Matthias Reitinger
b55c24cf27
[naga wgsl-in] Allow trailing comma in switch cases (#8165) 2025-09-16 07:58:23 -04:00
Andy Leiserson
4a7b6abb19 Add F16_IN_F32 downlevel flag for pack/unpack/quantize f16 (#8130)
Although the operation of these functions is defined in terms of f16
semantics, the input/output types are not f16, and they are generally
available even when native `f16` support is not. But in at least one
case, they are only available with `f16` support, so add a new downlevel
flag that is cleared when these functions are not available.

Add some infrastructure to simplify testing of missing
capabilities/extensions, and add tests for a few more kinds of f16
usage.

Co-authored-by: Erich Gubler <erichdongubler@gmail.com>
2025-08-28 13:58:36 -07:00
Jamie Nicol
2c6f06a82b [naga msl-out] Implement support for external textures
This adds MSL backend support for `ImageClass::External`. (ie WGSL's
`external_texture` texture type). This is implemented very similarily
to the HLSL implementation in #7826.

Each external texture global variable is lowered to 3 `texture2d`s and
a buffer of type NagaExternalTextureParams. As usual in Naga's MSL
backend, these are passed as arguments to the entry point. The
bindings for each of these arguments are provided via the usual
binding map, using a new `BindExternalTextureTarget` variant of
`BindTarget`.

Unlike HLSL, MSL allows textures to be used as fields in structs. We
therefore immediately wrap these variables in a
`NagaExternalTextureWrapper` struct. This wrapper can then
conveniently be passed to either user-defined functions or builtin
implementations that accept an external texture.

The WGSL builtins `textureDimensions()`, `textureLoad()`, and
`textureSampleBaseClampToEdge()` are implemented using wrapper
functions using the regular `write_wrapped_functions()` machinery.
2025-08-21 12:35:19 +01:00
Jamie Nicol
2cada72dfb [naga] Make external texture snapshot test call textureLoad() with both vec2<i32> and vec2<i32> coordinates
The HLSL external texture implementation didn't have to do anything in
particular to handle both coordinate types, as int2 automatically gets
promoted to uint2. But in MSL this is not the case, and it is
therefore important to test that we correctly handle both coordinate
types.
2025-08-21 12:35:19 +01:00
cryvosh
4b5e38ab49
[naga spv-out] Add f16 io polyfill (#7884) 2025-08-21 10:50:32 +02:00
Vecvec
54be6a2b5b
Fix empty ifs causing errors on spirv 1.6 (#7883) 2025-08-13 15:27:51 +00:00
Jamie Nicol
8cd4bd602f [naga hlsl-out] Handle external texture color space conversion
This adds several fields to `ExternalTextureDescriptor`, specifying
how to handle color space conversion for an external texture. These
fields consist of transfer functions for the source and destination
color spaces, and a matrix for converting between gamuts. This allows
`ImageSample` and `ImageLoad` operations on external textures to
return values in a desired destination color space rather than the
source color space of the underlying planes.

These fields are plumbed through to the `ExternalTextureParams`
uniform buffer from which they are exposed to the shader. Following
conversion from YUV to RGB after sampling/loading from the external
texture planes, the shader uses them to gamma decode to linear RGB in
the source color space, convert from source to destination gamut, then
finally gamma encode to non-linear RGB in the destination color space.
2025-08-06 11:18:42 +01:00
Jamie Nicol
e1ccb6632c [naga hlsl-out] Implement external texture support
This adds HLSL backend support for `ImageClass::External` (ie WGSL's
`external_texture` texture type).

For each external texture global variable in the IR, we declare 3
`Texture2D` globals as well as a `cbuffer` for the params. The
additional bindings required by these are found in the newly added
`external_texture_binding_map`. Unique names for each can be obtained
using `NameKey::ExternalTextureGlobalVariable`.

For functions that contain ImageQuery::Size, ImageLoad, or ImageSample
expressions for external textures, ensure we have generated wrapper
functions for those expressions. When emitting code for the
expressions themselves, simply insert a call to the wrapper function.

For size queries, we return the value provided in the params
struct. If that value is [0, 0] then we query the size of the plane 0
texture and return that.

For load and sample, we sample the textures based on the number of
planes specified in the params struct. If there is more than one plane
we additionally perform YUV to RGB conversion using the provided
matrix.

Unfortunately HLSL does not allow structs to contain textures, meaning
we are unable to wrap the 3 textures and params struct variables in a
single variable that can be passed around.

For our wrapper functions we therefore ensure they take the three
textures and the params as consecutive arguments. Likewise, when
declaring user-defined functions with external texture arguments, we
expand the single external texture argument into 4 consecutive
arguments. (Using NameKey::ExternalTextureFunctionArgument to ensure
unique names for each.)

Thankfully external textures can only be used as either global
variables or function arguments. This means we only have to handle the
`Expression::GlobalVariable` and `Expression::FunctionArgument` cases
of `write_expr()`. Since in both cases we know the external texture
can only be an argument to either a user-defined function or one of
our wrapper functions, we can simply emit the names of the variables
for each three textures and the params struct in a comma-separated
list.
2025-07-30 14:33:00 -07:00
Jamie Nicol
9f654c6235 [naga] Generate special type for external texture params buffer
During wgsl lowering, if we encounter an external texture type then
generate the `ExternalTextureParams` struct. This will be required by
most Naga backends to implement external textures.

This type is not actually used by wgsl-in or the IR. However,
generating it in Naga IR ensures tricky details such as member
alignment are handled for us.

wgsl-out must ensure it does *not* generate code for this type, as it
handles external textures natively.
2025-07-30 14:33:00 -07:00
Jamie Nicol
43a4d53107
[naga wgsl-in wgsl-out] WGSL support for texture_external texture type (#7822)
* [naga wgsl-in wgsl-out] WGSL support for texture_external texture type

Make wgsl-in correctly parse `texture_external` texture declarations,
and allow such textures to be used in `textureDimensions()`,
`textureSampleBaseClampToEdge()`, and `textureLoad()` function
calls. In IR these are represented by the `ImageClass::External` image
class, which is a 2D, non-multisampled, non-mipmapped, float-sampled
image.

Adds a new Capability `TEXTURE_EXTERNAL` and ensure validation rejects
shaders containing external textures if this capability flag is not
set. This capability is enabled for validation by wgpu devices which
support the `TEXTURE_EXTERNAL` feature (currently only when using the
noop backend), and by the Naga CLI when validating-only or when
outputting WGSL.

The WGSL backend can of course emit `ImageClass::External` images
directly as `texture_external` textures. Other backends are, for now,
unimplemented.

Lastly, we add a snapshot test covering all the valid uses of a
texture_external texture. These are:
  - As a global variable declaration
  - As an argument to the built-in functions `textureDimensions()`,
    `textureSampleBaseClampToEdge()`, and `textureLoad()`
  - As an argument to user-defined function declarations and calls.

We keep these in their own test so that we can control which targets
to run them against (currently WGSL and IR). When external textures
are supported by all Naga backends we can, if so inclined, integrate
these with existing texture tests.

* fixup! [naga wgsl-in wgsl-out] WGSL support for texture_external texture type

* fixup! [naga wgsl-in wgsl-out] WGSL support for texture_external texture type

---------

Co-authored-by: Jim Blandy <jimb@red-bean.com>
2025-07-22 14:38:32 -07:00
SupaMaggie70Incorporated
dd50e56c59
Update rspirv version (#7945) 2025-07-15 00:51:31 -04:00
Andy Leiserson
bfa7ee8de5 [naga hlsl-out] Handle additional cases of Cx2 matrices
Fixes #4423
2025-07-11 16:55:46 -07:00
Jamie Nicol
55a2c3095d [naga] Support textureSampleBaseClampToEdge() for texture2d
Adds a new flag to the IR indicating when image sample coordinates are
to be clamped. Adds wgsl-in support for parsing and lowering to
IR. Validation ensures this flag is only used when sampling a 2D
non-arrayed sampled texture, without offset, gather, or depth
comparison. This matches the WGSL requirements, with the exception of
supporting `texture_external` textures, which will follow in a later
patch.

SPIRV, HLSL, and Metal backends are supported so far, with GLSL left
for a follow up. (In GLSL the texture will simply be sampled without
the coordinates being clamped.)

It may seem unfortunate to have to handle this separately for each
backend, and indeed it would have been possible to implement this simply
in the WGSL frontend. However, future patches will add support for using
textureSampleBaseClampToEdge() with external textures, which will
actually have to be handled by each backend. This patch is laying the
groundwork for that.
2025-06-17 14:27:18 -07:00
Jamie Nicol
d811258424 [naga msl-out] Add padding to end of structs if required 2025-06-17 20:20:25 +01:00
Jim Blandy
48eae68156 [naga spv-in] Lay out entry point output structs correctly.
In the SPIR-V front end, when generating Naga IR `Struct` types to
represent a SPIR-V entry point's `Output` variables, instead of saying
"0xFFFF, // shouldn't matter", follow the usual rules in assigning
struct member offsets and computing an overall
size (`TypeInner::Struct::span`) for the resulting struct type.
2025-06-17 09:56:57 -07:00
Vecvec
03775c54fe
Prevent naga crashing on an aliased ray query. (#7759) 2025-06-16 08:45:39 +00:00
Dmitry Zamkov
bbb7cc79ef
Implement clip-distances extension for GL and Vulkan backends (#7730)
* Basic implementation of `clip_distances` for Vulkan and GL backends

* Added GPU test for `clip-distances`

* Update feature array size

* Add changelog entry

* Validate `clip_distances` array size

* Check for `clip_distances` enable directive

* Consolidate code for generating `enable` directives in WGSL backend and add `clip_distances`.
2025-06-16 10:33:31 +02:00
Phena Ildanach
486a77d682 [naga glsl-out] Split writes for memory/control barriers 2025-06-16 10:22:46 +02:00
Phena Ildanach
dd273fd7e2 [naga spv] Split workgroup and subgroup memory semantics in Control Barriers 2025-06-16 10:22:46 +02:00
Phena Ildanach
1e031e7a02 [naga spv-in] Add support for Memory Barriers 2025-06-16 10:22:46 +02:00
Andy Leiserson
82fa8e2a94 [naga] Remove non-essential override references via compaction
Adds a mode to compaction that removes unused functions, global
variables, and named types and overrides. This mode is used
everywhere except the compaction at the end of lowering, where
it is important to preserve unused items for type checking and
other validation of the module.

Pruning all but the active entry point and then compacting makes
`process_overrides` tolerant of missing values for overrides that are
not used by the active entry point.

Fixes #5885
2025-06-12 14:22:18 +09:00
Erich Gubler
db3c35db90 fix(naga): properly impl. auto. type conv. for select 2025-06-11 21:55:02 +09:00
Teodor Tanasoaia
23b81da5cc
[hlsl-out] polyfill float remainder operator (#7750) 2025-06-05 15:14:03 +02:00
Thierry Berger
28af245d51
[wgsl-in,ir] Add support for parsing rust-style doc comments (#6364)
* [wgsl-in,ir] add support for parsing rust-style doc comments

* rename relevant items to `doc_comments` (or variations of it)

* address comments

* remove `next_until`

* rename `save_doc_comments` to `ignore_doc_comments`

* expand snapshot test and ignore blankspace when accumulating doc comments

* make tokenizer more straightforward

---------

Co-authored-by: teoxoy <28601907+teoxoy@users.noreply.github.com>
2025-06-05 15:13:11 +02:00
cryvosh
bb46a7f046
[naga hlsl-out, glsl-out] Support atomicCompareExchangeWeak (#7658) 2025-06-02 13:36:44 +02:00
Dmitry Zamkov
9c023e5e29
Implement subgroup quad ops (#7683)
* Rudimentary impl of quad ops, impl quad ops for spirv

* Impl quad swap for hlsl, msl and wgsl, finish spv front

* Cargo clippy & cargo fmt, impl valid for quad ops

* Enable quad feature

* Add missing feature to glsl

* Simplifying code by making `SubgroupQuadSwap` an instance of `SubgroupGather`

* Add `GroupNonUniformQuad` spv capability to Vulkan

* Adding GPU tests for quad operations

* Validate that broadcast operations use const invocation ids

* Added changelog entry

---------

Co-authored-by: valaphee <32491319+valaphee@users.noreply.github.com>
2025-05-26 09:32:01 +02:00
Dmitry Zamkov
44957709ff
Vulkan support for SHADER_EARLY_DEPTH_TEST and fix to conservative depth optimizations (#7676)
Co-authored-by: Andreas Reich <r_andreas2@web.de>
2025-05-24 09:52:39 +00:00
Robert Bamler
8969965978 [naga] Vectorize [un]pack4x{I, U}8[Clamp] on msl
Implements more direct conversions between 32-bit integers and 4x8-bit
integer vectors using bit casting to/from `packed_[u]char4` when on
MSL 2.1+ (older versions of MSL don't seem to support these bit casts).

- `unpack4x{I, U}8(x)` becomes `[u]int4(as_type<packed_[u]char4>(x))`;
- `pack4x{I, U}8(x)` becomes `as_type<uint>(packed_[u]char4(x))`; and
- `pack4x{I, U}8Clamp(x)` becomes
  `as_type<uint>(packed_uchar4(metal::clamp(x, 0, 255)))`.

These bit casts match the WGSL spec for these functions because Metal
runs on little-endian machines.
2025-05-23 16:08:26 +02:00
Robert Bamler
b32eb4a120 [naga] Vectorize [un]pack4x{I, U}8[Clamp] on spv
Emits vectorized SPIR-V code for the WGSL functions `unpack4xI8`,
`unpack4xU8`, `pack4xI8`, `pack4xU8`, `pack4xI8Clamp`, and
`pack4xU8Clamp` if `Capability::Int8` is available.

Exploits the following facts about SPIR-V ops:
- `SClamp`, `UClamp`, and `OpUConvert` accept vector arguments, in which
  case results are computed per component; and
- `OpBitcast` can cast between vectors and scalars, with a well-defined
  bit order that matches that required by the WGSL spec, see below.

WGSL spec for `pack4xI8` [1]:

> Component e[i] of the input is mapped to bits 8 x i through 8 x i + 7
> of the result.

SPIR-V spec for `OpBitcast` [2]:

> Within this mapping, any single component of `S` [remark: the type
> with fewer but wider components] (mapping to multiple components of
> `L` [remark: the type with more but narrower components]) maps its
> lower-ordered bits to the lower-numbered components of `L`.

[1] https://www.w3.org/TR/WGSL/#pack4xI8-builtin
[2] https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpBitcast
2025-05-23 16:08:26 +02:00
Andy Leiserson
0997b99429 [naga] Make additional test code reachable from entrypoints 2025-05-22 13:01:15 -07:00
Andy Leiserson
25636e274b [naga] Ensure globals in wgsl snapshot tests are reachable from an entry point
Convert tabs to spaces in access.wgsl
2025-05-22 13:01:15 -07:00
Robert Bamler
d7e6a0e1fa
Potentially optimize dot4{I,U}8Packed on Metal (#7653)
* Potentially optimize `dot4{I,U}8Packed` on Metal

This might allow the Metal compiler to emit faster code (but that's not
confirmed). See
<https://github.com/gpuweb/gpuweb/issues/2677#issuecomment-1713292226>
for the optimization. The limitation to Metal 2.1+ is discussed here:
<https://github.com/gfx-rs/wgpu/pull/7574#issuecomment-2835464472>.

* [naga] Factor out new part of `put_block` on msl

CI on test failed because the latest changes to `put_block` made its
stack too big. Factoring out the new code into a separate method fixes
this issue.
2025-05-21 18:47:59 +02:00
Andy Leiserson
bc0a023cd1
[naga] Ensure wgsl snapshot code is reachable from an entry point (#7674) 2025-05-21 11:32:10 -04:00
Andy Leiserson
2a924a330a
[naga] Ensure test functions in glsl snapshots are reachable from the entry point (#7672) 2025-05-07 15:39:10 -04:00
Robert Bamler
bb83976ddb Optimize dot4{I, U}8Packed for all spv versions
Emit optimized code for `dot4{I, U}8Packed` regardless of SPIR-V version
as long as the required capabilities are available. On SPIR-V < 1.6,
require the extension "SPV_KHR_integer_dot_product" for this. On
SPIR-V >= 1.6, don't require the extension because the corresponding
capabilities are part of SPIR-V >= 1.6 proper.
2025-04-28 16:37:45 +02:00
Robert Bamler
065d6546c4 Check for spv language version
When checking for capabilities in SPIR-V,
`capabilities_available == None` indicates that all capabilities are
available. However, some capabilities are not even defined for all
language versions, so we still need to check if the requested
capabilities even exist in the language version we're using.
2025-04-28 16:37:45 +02:00
Robert Bamler
5b20979e9b Use intrinsics for dot4{I, U}8Packed on spv 2025-04-28 16:37:45 +02:00
Robert Bamler
fe05765602 Use intrinsics for dot4{I, U}8Packed in HLSL 2025-04-28 16:37:45 +02:00
Wouter de Bruijn
30b247a8d1
[naga glsl-out] Differentiate between support for std140 and std430 (#7579)
* [naga glsl-out] Differentiate between support for `std140` and `std430` layout, and emit `std140` in Uniforms when possible

* [naga glsl-out] Remove storage buffer std140 layout fallback, and error when we are unable to assign an explicit memory layout for uniform and storage globals

Co-authored-by: teoxoy <28601907+teoxoy@users.noreply.github.com>

---------

Co-authored-by: teoxoy <28601907+teoxoy@users.noreply.github.com>
2025-04-26 13:55:02 +02:00
Jim Blandy
7c5f705580 [naga] Allow textureLoad's sample index arg to be unsigned.
Permit the `sample_index` argument of `textureLoad` overloads to be
either `i32` or `u32`.
2025-04-24 13:45:12 -07:00
Jim Blandy
5573c57393
[naga wgsl-in] Properly convert arguments to atomic operations. (#7573) 2025-04-21 12:27:02 -04:00
Jim Blandy
a9a3ea3a41 [naga wgsl-in] Convert textureStore values correctly.
Apply necessary automatic conversions to the `value` argument of
`textureStore`.
2025-04-18 12:56:51 -07:00
Jim Blandy
5304c3ca4a [naga wgsl-in] Apply automatic conversions to sampling arguments.
Properly apply WGSL's automatic conversions to the arguments
to texture sampling functions.

Introduce helper function `Lowerer::expression_with_leaf_scalar`.

Although this can't affect behavior, use
`Lowerer::expression_for_abstract` for the `image` and `sampler`
arguments, simply because we want to move away from
`Lower::expression`'s automatic concretization, and move towards
having callers say explicitly what sort of conversions they need.

Although this can't affect behavior, use
`Lowerer::expression_with_leaf_scalar` for the `offset` argument, so
that the code spells out that this requires an `i32` value, rather
than depending on blind concretization giving it that.

Continue to use `Lowerer::expression` for `gather` and `array_index`,
since those happen to behave correctly with blind concretization, and
can be cleaned up later.

Fixes #7427.
2025-04-18 11:56:34 -07:00