Commit Graph

543 Commits

Author SHA1 Message Date
Hans-Kristian Arntzen
1f6653ec07 MSL: Do not override variable name late.
If we have emitted block IO lowering at the end of vertex shader, we
will end up using the wrong name. Forcing a v_ prefix does not solve any
actual problems since the intentifier already has to be valid.
2023-03-30 18:30:44 +02:00
Hans-Kristian Arntzen
3550a54ae0
Merge pull request #2105 from goki/main
add support for OpAtomicFAddEXT atomic add, and also Min, Max
2023-02-21 13:05:31 +01:00
Chip Davis
41007cdc7d MSL: Deduplicate function constants.
It is possible in SPIR-V to declare multiple specialization constants
with the same constant ID. The most common cause of this in GLSL is
defining a spec constant, then declaring the workgroup size to use that
spec constant by its ID. But, MSL forbids defining multiple function
constants with the same function constant ID. So, we must only emit one
definition of the actual function constant (with the
`[[function_constant(id)]]` attribute); but we can point the other
variables at this one definition.

Fixes three tests in the Vulkan CTS under
`dEQP-VK.compute.basic.max_local_size_*`.
2023-02-17 10:43:50 -08:00
Randall C. O'Reilly
8e20860b9e added tests and added msl3 to test_shaders.py 2023-02-15 00:04:44 -08:00
Chip Davis
e8d419854f MSL: Add a workaround for broken level() arguments.
Some Metal devices have a bug with depth array textures using comparison
with explicit LoD, where the LoD given will be biased by some amount.
For these devices, we can use a gradient instead, which does not exhibit
this problem. As with the fragment demote workaround, this is only
expected to be needed until the bug is fixed in Metal.
2023-02-02 22:01:46 -08:00
Chip Davis
2a9091ce53 MSL: Use rint() instead of round() to round array coordinates.
Vulkan specifies round-to-nearest-even mode to round array coordinates.
But we were using `round()`, which is round-to-nearest-away-from-zero.
Instead, use `rint()`, which is specified to perform nearest-even
rounding in MSL.
2023-01-18 19:34:29 -08:00
Hans-Kristian Arntzen
451ed10e91
Merge pull request #2062 from cdavis5e/msl-spirv-assembly-fixes
MSL: SPIR-V assembly fixes
2022-11-21 13:53:17 +01:00
Chip Davis
061cdd2052 MSL: Don't dereference forwarded copies of OpVariable pointers.
Fixes two more CTS tests under
`dEQP-VK.spirv_assembly.instruction.compute.empty_struct.copying`.
2022-11-20 02:08:37 -08:00
Chip Davis
5547b25afe Interleave undef values with constants and types.
Undef values may be of struct type and may be used in constants.
Therefore, they must be interleaved with constants and types.

Fixes the rest of the Vulkan CTS test
`dEQP-VK.spirv_assembly.instruction.compute.opundef.undefined_spec_constant_composite`.

(Please excuse the churn in the reference output; it's an inevitable
result of this change.)
2022-11-20 02:08:37 -08:00
Chip Davis
06ef3de002 GLSL, MSL: Handle OpUndef as part of a constant composite.
Fixes the CTS test
`dEQP-VK.spirv_assembly.instruction.compute.opundef.undefined_constant_composite`
and helps with another,
`dEQP-VK.spirv_assembly.instruction.compute.opundef.undefined_spec_constant_composite`.
Unfortunately, fixing the latter requires another change.
2022-11-20 02:08:33 -08:00
Chip Davis
aa5a8c482e MSL: Prevent stores to storage resources in discarded fragments.
Some Metal devices have a bug where storage resources can still be
written to even if the fragment is discarded. This is obviously a bug in
Metal, but bothering Apple to fix it will only fix it for newer
versions; therefore, a workaround is needed for older versions. I have
made this an option so that, in case the bug is ever fixed, the
workaround can be disabled.

This workaround is simple: if a fragment shader may discard its fragment
and writes to a storage resource, a variable representing the
`HelperInvocation` built-in is created and passed to all functions. The
flag is checked on all resource writes; writes do not occur when
`HelperInvocation` is `true`. This relies on the earlier workaround to
update `HelperInvocation` when the fragment is discarded.

Fixes at least 3 failures in the CTS.
2022-11-20 01:29:41 -08:00
Chip Davis
51d2dfe02a MSL: Add missing casts to Op?MulExtended.
It is possible to pass unsigned integers to `OpSMulExtended`. In that
case, we want to do a signed multiply with sign extension, so make sure
the operands are forced to be interpreted as signed.

This was an oversight on my part when I added these instructions.

Fixes the CTS test
`dEQP-VK.spirv_assembly.instruction.compute.signed_op.uint_smulextended`.
2022-11-20 00:20:49 -08:00
Chip Davis
c7ce92a95b MSL: Manually update BuiltInHelperInvocation when a fragment is discarded.
Some Metal devices have a bug where `simd_is_helper_thread()` won't
return true after a fragment has been discarded. We can work around this
by manually setting `gl_HelperInvocation` upon discarding a fragment.
This is fairly unintrusive, so it is enabled by default. I've made it an
option so that, when the bug is fixed, we can disable it.
2022-11-19 23:48:26 -08:00
Chip Davis
8cf99e7d44 MSL: Implement CompositeInsert OpSpecConstantOp.
This op creates a new composite constant with one element replaced. So,
we reconstruct the `SPIRConstant` for the composite constant, but with
one of the IDs replaced. Constant initializer lists are memoized for
when the result of a `CompositeInsert` is used in another
`CompositeInsert`.

(I wanted to add a test case for GLSL as well, but for two things:
1. `glslang` in Vulkan mode chokes on the first constant array,
   insisting that its initializer needs to be a constant. [Bug in
   glslang?]
2. The declarations for the buffers used by the shader aren't emitted,
   regardless of whether Vulkan mode is enabled.)

Fixes five tests under
`dEQP-VK.spirv_assembly.instruction.*.opspecconstantop.vector_related`.
2022-11-01 18:11:39 -07:00
Hans-Kristian Arntzen
2a49f7e82d MSL: Fix restrict vs __restrict incompatibility.
restrict was supported, but it broke in MSL 3.0. __restrict works on all
versions, so opt for that instead.

Also check for RestrictPointer decoration and refactor to_restrict() to
not take optional parameter to make it more obvious when implied space
character is added.
2022-10-26 17:52:47 +02:00
Chip Davis
0b679334e4 MSL: Don't flatten arrayed per-patch output blocks in tessellation shaders.
Flattening doesn't play well with dynamic indices. In this case, it's
better to leave it as an array of structs.

(I wanted to do this for named blocks generally. Trouble is, the builtin
`gl_out` block is *also* a named block...)

Fixes six more CTS tests, under
`dEQP-VK.tessellation.user_defined_io.per_patch_block_array.*`.
2022-10-18 15:04:42 -07:00
Chip Davis
a171087180 MSL: Support "raw" buffer input in tessellation evaluation shaders.
Using vertex-style stage input is complex, and it doesn't support
nesting of structures or arrays. By using raw buffer input instead, we
get this support "for free," and everything becomes much simpler.
Arguably, this is the way I should've done this in the first place.

Eventually, I'd like to make this the default, and then remove the
option altogether. (And I still need to do that with
`multi_patch_workgroup`...)

Should help fix 66 tests in the Vulkan CTS, under the following trees:

 - `dEQP-VK.pipeline.*.interface_matching.*`
 - `dEQP-VK.tessellation.user_defined_io.*`
 - `dEQP-VK.clipping.user_defined.*`
2022-10-18 14:58:59 -07:00
Hans-Kristian Arntzen
a915e0bd4b MSL: Do not attempt to alias push constants. 2022-09-21 11:01:42 +02:00
Hans-Kristian Arntzen
24dc49e692 MSL: Handle descriptor aliasing of raw buffer descriptors.
It is allowed to redeclare descriptors with different types in Vulkan.
MSL in general does not allow this, but for raw buffers, we can cast the
reference type at the very least.

For typed resources we are kinda hosed. Without descriptor indexing's
PARTIALLY_BOUND_BIT, descriptors must be valid if they are statically
accessed, so it would not be valid to access differently typed aliases
unless that flag is used. There might be a way to reinterpret cast
descriptors, but that seems very sketchy.

Implements support for:

- Single discrete descriptor
- Single argument buffer descriptor
- Array of argument buffer descriptors

Other cases are unimplemented for now since they are extremely painful
to unroll.
2022-09-20 15:21:56 +02:00
Hans-Kristian Arntzen
d24f41f1d5 Update dependencies. 2022-09-02 14:58:04 +02:00
Hans-Kristian Arntzen
bc3987e59a MSL: Fix various bugs with Ptr/U bitcasts. 2022-08-09 13:49:40 +02:00
Chip Davis
fc4a12fd4f MSL: Use a wrapper type for matrices in workgroup storage.
The standard `matrix` type in MSL lacked a constructor in the
`threadgroup` AS. This means that it was impossible to declare a
`threadgroup` variable that contains a matrix. This appears to have been
an oversight that was corrected in macOS 13/Xcode 14 beta 4. This
workaround continues to be required, however, for older systems.

To avoid changing interfaces unnecessarily (which shouldn't be a problem
regardless because the old and new types take up the same amount of
storage), only do this for structs if the struct is positively
identified as being used for workgroup storage.

I'm entirely aware this is inconsistent with the way packed matrices are
handled. One of them should be changed to match the other. Not sure
which one.

Fixes 23 CTS tests under `dEQP-VK.memory_model.shared`.
2022-08-07 17:31:41 -07:00
Chip Davis
faea931de3 MSL: Also replace bool with short in structures.
Since `bool` is a logical type, it cannot be used in uniform or storage
buffers. Therefore, replacing it in structures should not change the
shader interface.

We leave it alone for builtins. (FIXME: Should we also leave it for
I/O varyings?)

Fixes 24 CTS tests under `dEQP-VK.memory_model.shared`.
2022-08-05 11:43:21 -07:00
Bill Hollings
4185acc70d MSL: Fixes from review for SPV_KHR_physical_storage_buffer extension.
- Assign ulongn physical type to buffer pointers in short arrays
  when array stride is larger than pointer size.
- Support GL_EXT_buffer_reference_uvec2 casting
  buffer reference pointers to and from uvec2 values.
- When packing structs, include structs inside physical buffers.
- Update mechanism for traversing pointer arrays when calculating type sizes.
- Added unit test shaders.
2022-07-01 16:10:41 -04:00
Bill Hollings
78eb5043f9 MSL: Fixes from review for SPV_KHR_physical_storage_buffer extension.
- For physical storage pointers, emit forward reference
  declarations in addition to definitions.
- Minor syntax corrections.
2022-06-24 17:28:17 -04:00
Bill Hollings
52c7c2dab6 MSL: Add support for SPV_KHR_physical_storage_buffer extension.
- Determine sizing and alignments of pointers to types as
  distinct from the size and alignment of the types themselves.
- Declare all buffer pointers in the MSL device address space.
- Support struct pointer recursion, where structs can
  contain pointers to themselves or to a parent struct.
- Add SPIRType::was_forward_referenced to track if a type was forward
  referenced, to help emit MSL structs in the correct dependency order.
- Handle pointers to pointers that are not just arrays of arrays.
2022-06-20 20:21:00 -04:00
Hans-Kristian Arntzen
e45d01c41f Emit KHR barycentrics if source enables the KHR extension.
For roundtrip purposes, need to match KHR or NV extension.
2022-05-27 13:28:25 +02:00
Hans-Kristian Arntzen
b3ff97d0fe
Merge pull request #1946 from KhronosGroup/fix-1943
Promote Unreachable cases into break to avoid fallthrough.
2022-05-18 19:22:45 +02:00
Hans-Kristian Arntzen
d08ce828f4 Promote Unreachable cases into break to avoid fallthrough.
HLSL is very fussy about fallthrough in switch blocks, so promote
Unreachable blocks to breaks if they are inside a switch construct.

Some false positives are possible in weird multi-break scenarios, but
this is benign.
2022-05-18 18:36:32 +02:00
Hans-Kristian Arntzen
23662668dd Attempt more optimal codegen for OpCompositeInsert.
Speculate that we can modify the SSA value in-place. As long as it is
not used after the modify, this is fine.

Also need to make sure we don't attempt to RMW something that is
impossible to modify.
2022-05-18 16:37:33 +02:00
Hans-Kristian Arntzen
05206005ca MSL: Potentially cast loaded Input variables.
If the sign is rewritten for an input, we might have to fixup the sign
in OpLoad, similar to builtins.
2022-05-13 13:02:45 +02:00
Bill Hollings
3bca246ad2 MSL: Emit interface block members of array length 1 as arrays instead of scalars.
Test for array presence using is_array() instead of element count.
Add shaders-msl/vert/interface-block-single-element-array.vert regression test.

Fixes a regression error introduced in 3d4daab.
2022-04-26 20:39:18 -04:00
Hans-Kristian Arntzen
5b18fb1bcd MSL: Pass down global RayQuery object to leaf functions. 2022-04-19 11:49:22 +02:00
Hans-Kristian Arntzen
17c52990d5 MSL: Fix goofy bugs in ray query. 2022-03-24 18:14:46 +01:00
Bill Hollings
0c0fd98322 MSL: Use var name instead of var-type name for flattened interface members.
This allows two variables of the same struct type to be flattened
into the same interface struct without a member name conflict.

Add shaders-msl/frag/in_block_with_multiple_structs_of_same_type.frag
unit test shader to demonstrate this.
2022-03-04 11:38:53 -05:00
Hans-Kristian Arntzen
b192b8887a MSL: Consider that gl_IsHelperInvocation can be Volatile.
Just emit simd_is_helper_thread() directly.
2022-03-04 11:46:35 +01:00
Hans-Kristian Arntzen
31be74a853 Add relax_nan_checks options.
Makes codegen from typical D3D emulation SPIR-V more readable.
Also makes cross compilation with NotEqual more sensible.
It's very rare to actually need the strict NaN-checks in practice.

Also, glslang now emits UnordNotEqual by default it seems, so give up
trying to assume OrdNotEqual. Harmonize for UnordNotEqual as the sane
default.
2022-03-03 14:50:56 +01:00
Bill Hollings
02d588b7e4 MSL: Fix var names in test shaders to avoid reserved identifiers. 2022-03-03 10:19:04 +01:00
Bill Hollings
3d4daab29d MSL: Support input/output blocks containing nested struct arrays
Fixes numerous CTS tests of types
dEQP-VK.pipeline.interface_matching.vector_length.member_of_*,
passing complex nested structs between stages as stage I/O.

- Make add_composite_member_variable_to_interface_block() recursive to allow
  struct members to contain nested structs, building up member names and access
  chains recursively, and only add the resulting flattened leaf members to the
  synthetic input and output interface blocks.
- Recursively generate individual location numbers for the flattened members
  of the input/output block.
- Replace to_qualified_member_name() with append_member_name().
- Update add_variable_to_interface_block() to support arrays as struct members,
  adding a member to input and output interface blocks for each element of the array.
- Pass name qualifiers to add_plain_member_variable_to_interface_block() to allow
  struct members to be arrays of structs, building up member names and access chains,
  and adding multiple distinct flattened leaf members to the synthetic input and
  output interface blocks.
- Generate individual location numbers for the individual array members
  of the input/output block.
- SPIRVCrossDecorationInterfaceMemberIndex references the index of a member
  of a variable that is a struct type. The value is relative to the variable,
  and for structs nested within that top-level struct, the index value needs
  to take into consideration the members within those nested structs.
- Pass var_mbr_idx to add_plain_member_variable_to_interface_block() and
  add_composite_member_variable_to_interface_block(), start at zero for each
  variable, and increment for each member or nested member within that variable.
- Add unit test shaders-msl/vert/out-block-with-nested-struct-array.vert
- Add unit test shaders-msl/vert/out-block-with-struct-array.vert
- Add unit test shaders-msl/tese/in-block-with-nested-struct.tese
2022-03-03 10:18:40 +01:00
Hans-Kristian Arntzen
5b952d2cbf MSL: Rethink how opaque descriptors are passed to leaf functions.
We were passing arrays by value which the compiler fails to optimize,
causing abyssal performance. To fix this, we need to consider that
descriptors can be in constant or const device address spaces.

Also, lone descriptors are passed by value, so we explicitly remove address
space qualifiers.

One failure case is when shader passes a texture/sampler array as an
argument. It's all UniformConstant in SPIR-V, but in MSL it might be
thread, const device or constant, so that won't work ...
Global variable use works fine though, and that should cover 99.9999999%
of use cases.
2022-01-18 14:40:52 +01:00
Hans-Kristian Arntzen
fe8848a6f2 Roll dependencies. 2022-01-05 14:56:01 +01:00
Hans-Kristian Arntzen
be333e0cab MSL: Move float2->3 TessCoord fixup to a better location. 2022-01-05 13:32:17 +01:00
Nikita Fediuchin
2acf0e73dd Fix gl_TessCoord arguments presence. Update reference shaders.
* Added check for "gl_TessCoord" presence in the entry point arguments.
* Updated reference tessellation evaluation shaders.
2021-12-20 22:58:21 +02:00
Sebastián Aedo
6d8302ef14 MSL: Add 64 bit switch support
Add 64 bit switch support for MSL version 2.2.

* Also fixes a wrong endianness conversion.

Signed-off-by: Sebastián Aedo <saedo@codeweavers.com>
2021-11-26 15:54:56 -03:00
Bill Hollings
248e9ae9ed MSL: Don't output depth and stencil values with explicit early fragment tests.
Fragment shaders that require explicit early fragment tests are incompatible
with specifying depth and stencil values within the shader. If explicit early
fragment tests is specified, remove the depth and stencil outputs from the
output structure, and replace them with dummy local variables.

Add CompilerMSL:uses_explicit_early_fragment_test() function to consolidate
testing for whether early fragment tests are required.

Add two unit tests for depth-out with, and without, early fragment tests.
2021-11-12 14:17:00 -05:00
Bill Hollings
fd252b21ff Separate (partially) the tracking of depth images from depth compare ops.
SPIR-V allows an image to be marked as a depth image, but with a non-depth
format. Such images should be read or sampled as vectors instead of scalars,
except when they are subject to compare operations.

Don't mark an OpSampledImage as using a compare operation just because the
image contains a depth marker. Instead, require that a compare operation
is actually used on that image.

Compiler::image_is_comparison() was really testing whether an image is a
depth image, since it incorporates the depth marker. Rename that function
to is_depth_image(), to clarify what it is really testing.

In Compiler::is_depth_image(), do not treat an image  as a depth image
if it has been explicitly marked with a color format, unless the image
is subject to compare operations.

In CompilerMSL::to_function_name(), test for compare operations
specifically, rather than assuming them from the depth-image marker.

CompilerGLSL and CompilerMSL still contain a number of internal tests that
use is_depth_image() both for testing for a depth image, and for testing
whether compare operations are being used. I've left these as they are
for now, but these should be cleaned up at some point.

Add unit tests for fetch/sample depth images with color formats and no compare ops.
2021-11-08 15:59:45 -05:00
Hans-Kristian Arntzen
4561ecddbd Handle Modf/Frexp in more cases.
Consider it a write to a variable, similar to OpStore.
2021-11-07 11:36:44 +01:00
Bill Hollings
be812c45e5 MSL: Remove over-zealous check for struct packing compatibility.
Previous test for SPIRVCrossDecorationPhysicalTypePacked on parent struct
when unpacking member struct was too restrictive, and not needed as long
as padding compensates.
2021-10-28 19:36:32 -04:00
Bill Hollings
76cb807c19 MSL: Fix type redirection when struct members are reordered to align with offsets.
Populate member_type_index_redirection as reverse lookup, not forward lookup.
Move use of member_type_index_redirection from CompilerMSL::to_member_reference()
to CompilerGLSL::access_chain_internal() to access all redirected type info,
not just name.
2021-10-28 10:16:34 -04:00
Hans-Kristian Arntzen
edf247fb1c MSL: Workaround compiler crashes when using threadgroup bool.
Promote to short instead and do simple casts on load/store instead.

Not 100% complete fix since structs can contain booleans, but this is
getting into pretty ridiculously complicated territory.
2021-10-25 10:55:11 +02:00