Commit Graph

100 Commits

Author SHA1 Message Date
Chip Davis
688c5fcbda MSL: Add support for processing more than one patch per workgroup.
This should hopefully reduce underutilization of the GPU, especially on
GPUs where the thread execution width is greater than the number of
control points.

This also simplifies initialization by reading the buffer directly
instead of using Metal's vertex-attribute-in-compute support. It turns
out the only way in which shader stages are allowed to differ in their
interfaces is in the number of components per vector; the base type must
be the same. Since we are using the raw buffer instead of attributes, we
can now also emit arrays and matrices directly into the buffer, instead
of flattening them and then unpacking them. Structs are still flattened,
however; this is due to the need to handle vectors with fewer components
than were output, and I think handling this while also directly emitting
structs could get ugly.

Another advantage of this scheme is that the extra invocations needed to
read the attributes when there were more input than output points are
now no more. The number of threads per workgroup is now lcm(SIMD-size,
output control points). This should ensure we always process a whole
number of patches per workgroup.

To avoid complexity handling indices in the tessellation control shader,
I've also changed the way vertex shaders for tessellation are handled.
They are now compute kernels using Metal's support for vertex-style
stage input. This lets us always emit vertices into the buffer in order
of vertex shader execution. Now we no longer have to deal with indexing
in the tessellation control shader. This also fixes a long-standing
issue where if an index were greater than the number of vertices to
draw, the vertex shader would wind up writing outside the buffer, and
the vertex would be lost.

This is a breaking change, and I know SPIRV-Cross has other clients, so
I've hidden this behind an option for now. In the future, I want to
remove this option and make it the default.
2020-07-23 17:59:54 -05:00
dan sinclair
c4f3d4ae29 Roll GLSLang, SPIRV-Headers and SPIRV-Tools.
This Cl updates the various dependencies and the test file outputs.
2020-07-22 23:03:11 -04:00
dan sinclair
63fbdaca93 Roll deps.
This CL updates the GLSLang and SPIRV-Tools depedencies and updates test
files as needed.
2020-07-06 11:24:30 -04:00
Hans-Kristian Arntzen
02db4c1f16 MSL: Add tests for array copies in and out of buffers. 2020-06-18 11:59:02 +02:00
Chip Davis
5281d9997e MSL: Fix up input variables' vector lengths in all stages.
Metal is picky about interface matching. If the types don't match
exactly, down to the number of vector components, Metal fails pipline
compilation. To support pipelines where the number of components
consumed by the fragment shader is less than that produced by the vertex
shader, we have to fix up the fragment shader to accept all the
components produced.
2020-06-16 14:50:30 -05:00
Hans-Kristian Arntzen
107ab7c2b7 MSL: Avoid packed arrays in more cases.
Extend the array stride relaxation to non-packed arrays as well, as
long as the array in question contains a single array element.
2020-05-06 10:27:12 +02:00
Le Hoang Quyen
9ddfe6db6d Fix #1359: MSL: If the packed type is scalar, don't emit "pack_" prefix.
Scalar type is already packed in metal.
2020-05-06 00:43:34 +08:00
Hans-Kristian Arntzen
ebf463674d MSL: Allow removing clip distance user varyings.
Only safe if user knows that subsequent shader stage will not read clip
distance.
2020-04-20 09:58:40 +02:00
Chip Davis
495e48de44 MSL: Only disable output variables in fragment shaders.
Forgot to do this in #1319.

Fixes #1322.
2020-04-15 12:14:57 -05:00
Hans-Kristian Arntzen
20b28f72fa MSL: Reinstate workaround for returning arrays. 2020-02-24 13:04:10 +01:00
Hans-Kristian Arntzen
a3fe9756d2 MSL: Support ClipDistance as an input stage variable.
MSL does not support this, so we have to emulate it by passing it around
as a varying between stages. We use a special "user(clipN)" attribute
for this rather than locN which is used for user varyings.
2019-12-02 13:19:42 +01:00
Hans-Kristian Arntzen
b56c2f4271 Merge branch 'deps' of git://github.com/dj2/SPIRV-Cross 2019-11-06 10:43:17 +01:00
Dan Sinclair
d409210ee5 Move all .invalid shaders into no-opt folders. 2019-11-05 13:19:19 -05:00
Dan Sinclair
9da21c24a4 Roll GLSLang and SPIRV-Tools
This CL rolls the GLSLang and SPIRV-Tools dependencies to tip-of-tree
and updates the tests as required.
2019-11-05 10:07:15 -05:00
Hans-Kristian Arntzen
2767257adc MSL: Do not declare array of UBO/SSBO as spvUnsafeArray<T>.
There is no need for these to be copied, and cuts down on template
stamping bloat.
2019-10-26 16:10:08 +02:00
Hans-Kristian Arntzen
a82ecbeba9 MSL: Enable proper value types for return and value-passing of arrays.
Now that we have spvUnsafeArray<T> there is no need to deal with these
special purpose cases.
2019-10-24 13:03:38 +02:00
Hans-Kristian Arntzen
d1479f871a MSL: Do not generate UnsafeArray<> for any array inside buffer objects.
This avoids a lot of huge code changes.
Arrays generally cannot be copied in and out of buffers, at least no
compiler frontend seems to do it.

Also avoids a lot of issues surrounding packed vectors and matrices.
2019-10-24 12:22:30 +02:00
Lukas Hermanns
ffbd801853 Added '--msl-invariant-float-math' option and new test case for it. 2019-10-09 14:03:06 -04:00
Lukas Hermanns
7ad0a84778 Updates for pull request #1162 2019-09-24 14:35:25 -04:00
Lukas Hermanns
cb3ecb9e1b Updated reference Metal shaders. 2019-09-17 15:11:19 -04:00
Mark Satterthwaite
564cb3c08d Update the Metal shaders to account for changes in the shader compilation. 2019-09-11 15:06:05 -04:00
Hans-Kristian Arntzen
9b845a4788
Merge pull request #1141 from troughton/inline-everything
MSL: Inline all non-entry-point functions
2019-08-30 11:05:04 +02:00
Thomas Roughton
91b2f34a3d Update tests to account for all non-entry-point functions being inlined 2019-08-30 09:39:06 +12:00
Hans-Kristian Arntzen
07c76f66b5 MSL: Add {Base,}{Vertex,Instance}Index to bitcast_from_builtin_load.
Totally missed these, so float(index) would not work correctly for
negative numbers.
2019-08-29 13:56:37 +02:00
Hans-Kristian Arntzen
9436cd3036 MSL: Deal with array copies from and to threadgroup. 2019-08-27 13:18:01 +02:00
Hans-Kristian Arntzen
47a18b9f1b Simplify row-major matrix/vector multiplies. 2019-07-23 10:56:57 +02:00
Hans-Kristian Arntzen
19f5cd3e90 Declare correct matrix type when unpacking. 2019-07-22 13:25:45 +02:00
Hans-Kristian Arntzen
6c1f97b4a9 Fix unpacking of packed but not remapped types on load. 2019-07-19 14:50:35 +02:00
Hans-Kristian Arntzen
b66a53a979 Traverse correct types when checking scalar layout. 2019-07-19 14:43:42 +02:00
Hans-Kristian Arntzen
932ee0e328 Deal correctly with return sign of bitscan operations. 2019-07-12 10:57:56 +02:00
Chip Davis
058f1a0933 MSL: Handle coherent, volatile, and restrict.
This maps them to their MSL equivalents. I've mapped `Coherent` to
`volatile` since MSL doesn't have anything weaker than `volatile` but
stronger than nothing.

As part of this, I had to remove the implicit `volatile` added for
atomic operation casts. If the buffer is already `coherent` or
`volatile`, then we would add a second `volatile`, which would be
redundant. I think this is OK even when the buffer *doesn't* have
`coherent`: `T *` is implicitly convertible to `volatile T *`, but not
vice-versa. It seems to compile OK at any rate. (Note that the
non-`volatile` overloads of the atomic functions documented in the spec
aren't present in the MSL 2.2 stdlib headers.)

`restrict` is tricky, because in MSL, as in C++, it needs to go *after*
the asterisk or ampersand for the pointer type it's modifying.

Another issue is that, in the `Simple`, `GLSL450`, and `Vulkan` memory
models, `Restrict` is the default (i.e. does not need to be specified);
but MSL likely follows the `OpenCL` model where `Aliased` is the
default. We probably need to implicitly set either `Restrict` or
`Aliased` depending on the module's declared memory model.
2019-07-11 10:22:30 -05:00
Chip Davis
28454facbb MSL: Handle packed matrices.
The old method of using a different unpacked matrix type doesn't work
for scalar alignment. It certainly wouldn't have any effect for a square
matrix, since the number of columns and rows are the same. So now we'll
store them as arrays of packed vectors.
2019-07-10 18:37:31 -05:00
Hans-Kristian Arntzen
e2c95bdcbc MSL: Rewrite how resource indices are fallback-assigned.
We used to use the Binding decoration for this, but this method is
hopelessly broken. If no explicit MSL resource remapping exists, we
remap automatically in a manner which should always "just work".
2019-06-21 12:54:08 +02:00
Hans-Kristian Arntzen
a7b2ba28a0 MSL: Support Invariant qualifier on position. 2019-06-12 09:39:12 +02:00
Hans-Kristian Arntzen
03d93abc1a Deal with case where a variable is dominated by inner part of a loop.
There is a risk that we try to preserve a loop variable through multiple
iterations, even though the dominating block is inside a loop.

Fix this by analyzing if a block starts off by writing to a variable. In
that case, there cannot be any preservation going on. If we don't, pretend the
loop header is reading the variable, which moves the variable to an
appropriate scope.
2019-06-06 11:11:44 +02:00
Hans-Kristian Arntzen
c2715c3908 MSL: Cast texture_buffer index to uint. 2019-04-23 12:46:48 +02:00
Hans-Kristian Arntzen
fc4f39b11f MSL: Support native texture_buffer type, throw error on atomics.
Atomics are not supported on images or texture_buffers in MSL.
Properly throw an error if OpImageTexelPointer is used (since it can
only be used for atomic operations anyways).
2019-04-23 12:21:43 +02:00
Chip Davis
056c0e207d Take the vertex count from any indirect parameters passed.
This is necessary to deal with indirect draws, where the draw parameters
are given in a buffer instead of passed by the CPU. For normal draws,
the draw parameters are set with Metal's `setVertexBytes:` method.

This undoes the change to add the vertex count to the aux buffer,
rendering that entire discussion largely moot. Oh well. It was a
discussion that needed to happen anyway.
2019-02-06 15:17:14 -06:00
Chip Davis
546f1ccbb5 Test that out variables still work in leaf functions with capture on. 2019-02-06 10:49:25 -06:00
Chip Davis
c51e5b7911 MSL: Add a setting to capture vertex shader output to a buffer.
This will be necessary to support transform feedback, as well as
tessellation shaders.
2019-02-05 20:00:10 -06:00
Hans-Kristian Arntzen
b78ffa1cc7 Fixup MSL iOS test. 2019-01-30 16:26:41 +01:00
Hans-Kristian Arntzen
4e7777c443 Update to latest glslang/SPIRV-Tools.
Fix various bugs along the way.
2019-01-30 13:41:57 +01:00
Hans-Kristian Arntzen
8c632da461 MSL: Use correct alignment rule for whole structs.
Structs are aligned as you would expect in MSL (maximum member
alignment), and it is not minimum 16 bytes like in std140.

Also rename the dummy "pad" members to a reserved naming scheme.
2019-01-28 15:20:30 +01:00
Hans-Kristian Arntzen
15b52bee48 Deal with packing/unpacking on store.
Still a bit buggy, since we cannot deduce between float2[] and
packed_float2. Need a deeper refactor to plumb this through ...
2019-01-17 10:06:23 +01:00
Hans-Kristian Arntzen
d92de00cc1 Rewrite how IDs are iterated over.
This is a fairly fundamental change on how IDs are handled.
It serves many purposes:

- Improve performance. We only need to iterate over IDs which are
  relevant at any one time.
- Makes sure we iterate through IDs in SPIR-V module declaration order
  rather than ID space. IDs don't have to be monotonically increasing,
  which was an assumption SPIRV-Cross used to have. It has apparently
  never been a problem until now.
- Support LUTs of structs. We do this by interleaving declaration of
  constants and struct types in SPIR-V module order.

To support this, the ParsedIR interface needed to change slightly.
Before setting any ID with variant_set<T> we let ParsedIR know
that an ID with a specific type has been added. The surface for change
should be minimal.

ParsedIR will maintain a per-type list of IDs which the cross-compiler
will need to consider for later.

Instead of looping over ir.ids[] (which can be extremely large), we loop
over types now, using:

ir.for_each_typed_id<SPIRVariable>([&](uint32_t id, SPIRVariable &var) {
	handle_variable(var);
});

Now we make sure that we're never looking at irrelevant types.
2019-01-10 12:52:56 +01:00
Hans-Kristian Arntzen
5345756cab MSL: Support composites inside I/O blocks
I had to refactor the existing add_interface_block as it was
getting extremely large. Now it's all split up into different readable
functions.
2019-01-09 09:33:10 +01:00
Connor McLaughlin
1dd676c1de MSL: Emit wrapper for SSign (sign() for int types)
Metal does not define the sign() function for integer types, only
floating-point types.
2018-11-08 13:08:34 +10:00
Hans-Kristian Arntzen
62db535b3f Update tests. 2018-11-01 11:23:48 +01:00
Chip Davis
b7433c01ee Minor cleanups.
Throw an error for cases we don't support. Add a blank line after each
local array declaration.
2018-09-27 11:01:46 -05:00
Chip Davis
3a9af9681c MSL: Expand arrays of buffers passed as input.
Even as of Metal 2.1, MSL still doesn't support arrays of buffers
directly. Therefore, we must manually expand them. In the prologue, we
define arrays holding the argument pointers; these arrays are what the
transpiled code ends up referencing. We might be able to do similar
things for textures and samplers prior to MSL 2.0.

Speaking of which, also enable texture arrays on iOS MSL 1.2.
2018-09-26 20:48:09 -05:00