Commit Graph

420 Commits

Author SHA1 Message Date
Hans-Kristian Arntzen
4056d0b74e Don't use scalar dot(). 2019-07-03 14:32:06 +02:00
Hans-Kristian Arntzen
041f103d44 MSL/HLSL: Support scalar reflect and refract. 2019-07-03 12:31:52 +02:00
Chip Davis
31b6c93516 MSL: Support SubgroupLocalInvocationId and SubgroupSize in all stages.
MSL prior to 2.2 doesn't support these natively in any stage but
compute. But, we can (assuming no threads were terminated prematurely)
get their values with some creative uses of the
`simd_prefix_exclusive_sum()` and `simd_sum()` functions.

Also, fix a missing `to_expression()` with `BuiltInSubgroupEqMask`.

For KhronosGroup/MoltenVK#629.
2019-07-02 11:48:59 -05:00
Hans-Kristian Arntzen
f8b084de61 MSL/HLSL: Support OpOuterProduct. 2019-07-01 10:57:27 +02:00
Chip Davis
7eecf5a46b MSL: Support SPV_KHR_multiview.
This is needed to support `VK_KHR_multiview`, which is in turn needed
for Vulkan 1.1 support. Unfortunately, Metal provides no native support
for this, and Apple is once again less than forthcoming, so we have to
implement it all ourselves.

Tessellation and geometry shaders are deliberately unsupported for now.
The problem is that the current implementation encodes the `ViewIndex`
as part of the `InstanceIndex`, which in the SPIR-V environment at least
only exists in the vertex shader. So we need to work out a way to pass
the view index along to the later stages.

This implementation runs vertex shaders for all views up to the highest
bit set in the view mask, even those whose bits are clear. The fragments
for the inactive views are then discarded. Avoiding this is difficult:
calculating the view indices becomes far more complicated if we can only
run for those views which are set in the mask.
2019-06-29 09:43:55 -05:00
Hans-Kristian Arntzen
ff87419607 Deal with scalar input values for distance/length/normalize.
HLSL and MSL don't support it, so fall back to simpler intrinsics.
2019-06-28 11:20:14 +02:00
Hans-Kristian Arntzen
c76b99b711 Handle more cases with FP16 and texture sampling. 2019-06-27 15:04:22 +02:00
Hans-Kristian Arntzen
ab3798fd91 MSL: Add support for SubgroupSize / SubgroupInvocationID in fragment. 2019-06-24 12:31:54 +02: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
a1f7c8dc8e
Merge pull request #1031 from KhronosGroup/fix-1009
MSL: Support 64-bit integers.
2019-06-19 15:29:27 +02:00
Hans-Kristian Arntzen
7fdb418f18
Merge pull request #1028 from KhronosGroup/fix-1010
MSL: Support barycentrics and PrimitiveID in fragment shaders
2019-06-19 15:29:14 +02:00
Hans-Kristian Arntzen
4c20c941f0
Merge pull request #1025 from KhronosGroup/fix-1013
MSL: Support OpImageQueryLod.
2019-06-19 14:07:39 +02:00
Hans-Kristian Arntzen
a6798d06a2 MSL: Error out on int64_t/uint64_t buffer members.
Not supported for whatever reason.
2019-06-19 10:14:46 +02:00
Hans-Kristian Arntzen
a6b71ae999 MSL: Support 64-bit integers. 2019-06-19 09:55:00 +02:00
Hans-Kristian Arntzen
2e1cee5e1e MSL: Support PrimitiveID in fragment and barycentrics. 2019-06-19 09:52:35 +02:00
Hans-Kristian Arntzen
0671b3c35b MSL: Support OpImageQueryLod.
Correctness is a bit unclear at the moment. The spec document for 2.2 is
not updated for query-lod, but this is the best we can do anyways.
2019-06-19 09:51:56 +02:00
Hans-Kristian Arntzen
f171d82590 MSL: Support MinLod operand. 2019-06-19 09:43:03 +02:00
Hans-Kristian Arntzen
026a167549 MSL: New SDK errors out on cull distance.
Not supported, so just ignore this test for now, it should not have
compiled in the first place.
2019-06-14 12:12:40 +02:00
Hans-Kristian Arntzen
d81bfc5b58 MSL: Fix regression with Private parameter declaration.
If we compile multiple times due to forced_recompile, we had
deferred_declaration = true while emitting function prototypes which
broke an assumption. Fix this by clearing out stale state before leaving
a function.
2019-06-13 10:36:21 +02:00
Hans-Kristian Arntzen
95053ea4bc
Merge pull request #1024 from KhronosGroup/fix-1016
GLSL/MSL: Support stencil export
2019-06-12 12:48:10 +02:00
Hans-Kristian Arntzen
14d0a1eb0c MSL: Support stencil export. 2019-06-12 10:21:20 +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
314efdcc42 MSL: Fix declaration of unused input variables.
In multiple-entry-point modules, we declared builtin inputs which were
not supposed to be used for that entry point.

Fix this, by being more strict when checking which builtins to emit.
2019-05-31 13:23:34 +02:00
Hans-Kristian Arntzen
65af09d2d1 Support emitting OpLine directive.
Facilitates easier mapping from source language to cross-compiled output
in tooling.
2019-05-28 13:44:24 +02:00
Hans-Kristian Arntzen
fd0feb1ec1 MSL: Use correct address space when passing array-of-buffers.
Need to check if the descriptor set is actually an argument buffer.
2019-05-27 16:53:30 +02:00
Hans-Kristian Arntzen
42e64597a7 OpArrayLength must trigger active variables. 2019-05-27 16:44:02 +02:00
Hans-Kristian Arntzen
7b9e0fb428 MSL: Implement OpArrayLength.
This gets rather complicated because MSL does not support OpArrayLength
natively. We need to pass down a buffer which contains buffer sizes, and
we compute the array length on-demand.

Support both discrete descriptors as well as argument buffers.
2019-05-27 16:13:09 +02:00
Hans-Kristian Arntzen
55ff233526 MSL: Add test case for complex type alias. 2019-05-23 15:05:30 +02:00
Hans-Kristian Arntzen
96492648d4 MSL: Fix struct declaration order with complex type aliases.
MSL generally emits the aliases, which means we cannot always place the
master type first, unlike GLSL and HLSL. The logic fix is just to
reorder after we have tagged types with packing information, rather than
doing it in the parser fixup.
2019-05-23 14:54:04 +02:00
Hans-Kristian Arntzen
eaf7afed97 MSL: Support argument buffers and image swizzling.
Change aux buffer to swizzle buffer.
There is no good reason to expand the aux buffer, so name it
appropriately.

Make the code cleaner by emitting a straight pointer to uint rather than
a dummy struct which only contains a single unsized array member anyways.

This will also end up being very similar to how we implement swizzle
buffers for argument buffers.

Do not use implied binding if it overflows int32_t.
2019-05-18 10:30:06 +02:00
Chip Davis
8983920edf Remove fallback for OpGroupNonUniformElect.
It's not safe to enable subgroup support without this actually working
correctly.
2019-05-16 13:42:09 -05:00
Chip Davis
9d9415754b MSL: Add support for subgroup operations.
Some support for subgroups is present starting in Metal 2.0 on both iOS
and macOS. macOS gains more complete support in 10.14 (Metal 2.1).

Some restrictions are present. On iOS and on macOS 10.13, the
implementation of `OpGroupNonUniformElect` is incorrect: if thread 0 has
already terminated or is not executing a conditional branch, the first
thread that *is* will falsely believe itself not to be. Unfortunately,
this operation is part of the "basic" feature set; without it, subgroups
cannot be supported at all.

The `SubgroupSize` and `SubgroupLocalInvocationId` builtins are only
available in compute shaders (and, by extension, tessellation control
shaders), despite SPIR-V making them available in all stages. This
limits the usefulness of some of the subgroup operations in fragment
shaders.

Although Metal on macOS supports some clustered, inclusive, and
exclusive operations, it does not support them all. In particular,
inclusive and exclusive min, max, and, or, and xor; as well as cluster
sizes other than 4 are not supported. If this becomes a problem, they
could be emulated, but at a significant performance cost due to the need
for non-uniform operations.
2019-05-15 17:40:04 -05:00
Hans-Kristian Arntzen
03da32a124 Fix nonuniform test for MSL.
Binding index overlaps.
2019-05-13 15:14:18 +02:00
Hans-Kristian Arntzen
647ddaee42 HLSL/MSL: Deal correctly with nonuniformEXT qualifier.
MSL does not seem to have a qualifier for this, but HLSL SM 5.1 does.
glslangValidator for HLSL does not support this, so skip any validation,
but it passes in FXC.
2019-05-13 14:58:27 +02:00
Hans-Kristian Arntzen
ac5eea3326 MSL: Add test for passing single swizzled texture arg from array. 2019-05-09 14:19:40 +02:00
Hans-Kristian Arntzen
97d39dc9d5 MSL: Deal with texture swizzle on arrays of images. 2019-05-09 11:25:45 +02:00
Chip Davis
01c491648b Fix a copy-pasto. 2019-04-26 17:16:21 -05: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
Michael Barriault
105bfd368a Only use MSL constant address space for tessellation control shader. 2019-04-16 17:56:02 +01:00
Michael Barriault
d6754c5713 Fix tests for device->constant address space change in MSL tessellation control shader generation. 2019-04-10 18:37:04 +01:00
Bill Hollings
efbe7ca16f MSL: Fix infinite CAS loop on atomic_compare_exchange_weak_explicit(). 2019-04-05 21:28:57 -04:00
Hans-Kristian Arntzen
0909975655 MSL: Declare gl_WorkGroupSize constant with [[maybe_unused]].
Avoids ugly warnings on nearly every compute shader.
We could do analysis to detect whether we need to emit this constant,
but it's a bit tedious to figure out if an OpConstantComponent is
actually used by opcodes, so just make it simple.
2019-03-28 10:54:18 +01:00
Hans-Kristian Arntzen
e2aadf8995 Rename "push descriptor set" to "discrete descriptor set".
Check for case where iOS doesn't support writable argument buffer
textures.
2019-03-15 21:53:21 +01:00
Hans-Kristian Arntzen
b3380ec9dd MSL: Support VK_KHR_push_descriptor.
If we have argument buffers, we also need to support using plain
descriptor sets for certain cases where API wants it.
2019-03-15 14:08:47 +01:00
Hans-Kristian Arntzen
bc21ccb7ce MSL: Emit correct SSBO constness for argument buffers. 2019-03-15 12:05:35 +01:00
Hans-Kristian Arntzen
969566aff5 MSL: Fixup buffer array case issue on MSL 1.0. 2019-03-15 11:37:34 +01:00
Hans-Kristian Arntzen
af8a9ccdcb MSL: Need to emit two layers of address space.
When passing down arrays of buffer pointers, the array itself needs an
address space.
2019-03-15 11:29:17 +01:00
Hans-Kristian Arntzen
e47a77d596 MSL: Implement Metal 2.0 indirect argument buffers. 2019-03-15 11:01:27 +01:00
Hans-Kristian Arntzen
ee395afa83 MSL: Emit proper name for optimized UBO/SSBO arrays. 2019-02-25 11:09:00 +01:00
Hans-Kristian Arntzen
ad6134262e
Merge pull request #877 from cdavis5e/msl-tesc-early-return
MSL: Return early from helper tesc invocations.
2019-02-25 09:13:06 +01:00
Chip Davis
a43dcd7b99 MSL: Return early from helper tesc invocations.
Return after loading the input control point array if there are more
input points than output points, and this was one of the helper
invocations spun off to load the input points. I was hesitant to do this
initially, since the MSL spec has this to say about barriers:

> The `threadgroup_barrier` (or `simdgroup_barrier`) function must be
> encountered by all threads in a threadgroup (or SIMD-group) executing
> the kernel.

That is, if any thread executes the barrier, then all threads must
execute it, or the barrier'd invocations will hang. But, the key words
here seem to be "executing the kernel;" inactive invocations, those that
have already returned, need not encounter the barrier to prevent hangs.
Indeed, I've encountered no problems from doing this, at least on my
hardware. This also fixes a few CTS tests that were failing due to
execution ordering; apparently, my assumption that the later, invalid
data written by the helpers would get overwritten was wrong.
2019-02-24 12:17:47 -06:00
Chip Davis
f3c0942d10 MSL: Use vectors for the tessellation level builtins in tese shaders.
The tessellation levels in Metal are stored as a densely-packed array of
half-precision floating point values. But, stage-in attributes in Metal
have to have offsets and strides aligned to a multiple of four, so we
can't add them individually. Luckily for us, the arrays have lengths
less than 4. So, let's use vectors for them!

Triangles get a single attribute with a `float4`, where the outer levels
are in `.xyz` and the inner levels are in `.w`. The arrays are unpacked
as though we had added the elements individually. Quads get two: a
`float4` with the outer levels and a `float2` with the inner levels.
Further, since vectors can be indexed as arrays, there's no need to
unpack them in this case.

This also saves on precious vertex attributes. Before, we were using up
to 6 of them. Now we need two at most.
2019-02-22 12:18:51 -06:00
Hans-Kristian Arntzen
a4ac27546a MSL: Fix textures which are sampled and compared against.
depth2d in MSL only returns float, not float4, even for normal sampling.
We need to conditionally remap-swizzle back to float4.
2019-02-22 12:27:40 +01:00
Chip Davis
7a7e210515 MSL: Force unnamed array builtin attributes to have a name.
That way, when we refer to them, they'll have the name that we're
expecting.
2019-02-20 22:16:51 -06:00
Chip Davis
285ca4c2b1 MSL: Don't bother fixing up triangle tess coords.
Instead, I'm going to have MoltenVK reverse the winding order in the
lower-left case. This seems to be what the test suite expects to happen
anyhow.
2019-02-20 14:30:44 -06:00
Chip Davis
8095434dc4 MSL: Drop stores to nonexistent tess levels.
In SPIR-V, there are always two inner levels and four outer levels, even
if the input patch isn't a quad patch. But in MSL, due to requirements
imposed by Metal, only one inner level and three outer levels exist when
the input patch is a triangle patch. We must explicitly ignore any write
to the nonexistent second inner and fourth outer levels in this case.
2019-02-20 09:11:24 -06:00
Chip Davis
c8ee9fbe76 MSL: Expand quad gl_TessCoord to a float3.
This is the actual SPIR-V type of the builtin. We forced to a `float2`
in the declaration because that's what Metal wants.
2019-02-20 09:11:24 -06:00
Hans-Kristian Arntzen
58f264c99d
Merge pull request #865 from KhronosGroup/fix-863
Always value-cast FP16 constants instead of using literals.
2019-02-20 14:58:44 +01:00
Hans-Kristian Arntzen
4ef51331b2 Always value-cast FP16 constants instead of using literals.
GL_NV_gpu_shader5 doesn't support "hf", so to avoid lots of complicated
workarounds, just value-cast the half literals.
2019-02-20 12:30:01 +01:00
Hans-Kristian Arntzen
056a0ba27e Fix case where a struct is loaded which contains a row-major matrix. 2019-02-20 12:19:00 +01:00
Chip Davis
41d9424233 MSL: Add an option to set the tessellation domain origin.
This is intended to be used to support `VK_KHR_maintenance2`'s
tessellation domain origin feature. If `tess_domain_origin_lower_left`
is `true`, the `v` coordinate will be inverted with respect to the
domain. Additionally, in `Triangles` mode, the `v` and `w` coordinates
will be swapped. This is because the winding order is interpreted
differently in lower-left mode.
2019-02-18 14:25:42 -06:00
Chip Davis
08863c1e28 Don't set any aliases or do any flattening for arrayed per-vertex I/O.
We already handle all that specially.
2019-02-15 17:24:16 -06:00
Chip Davis
6b7988046d Handle blocks of patch I/O.
In this case, each member of the block will be decorated with
`DecorationPatch`, rather than the block variable having the decoration.
2019-02-15 17:21:38 -06:00
Chip Davis
e75add42c9 MSL: Add support for tessellation evaluation shaders.
These are mapped to Metal's post-tessellation vertex functions. The
semantic difference is much less here, so this change should be simpler
than the previous one. There are still some hairy parts, though.

In MSL, the array of control point data is represented by a special
type, `patch_control_point<T>`, where `T` is a valid stage-input type.
This object must be embedded inside the patch-level stage input. For
this reason, I've added a new type to the type system to represent this.

On Mac, the number of input control points to the function must be
specified in the `patch()` attribute. This is optional on iOS.
SPIRV-Cross takes this from the `OutputVertices` execution mode; the
intent is that if it's not set in the shader itself, MoltenVK will set
it from the tessellation control shader. If you're translating these
offline, you'll have to update the control point count manually, since
this number must match the number that is passed to the
`drawPatches:...` family of methods.

Fixes #120.
2019-02-14 10:00:08 -06:00
Chip Davis
13df78bebf Unflatten inputs when copying to outputs.
This should fix a whole host of issues related to structs in the `Input`
class in a tessellation control shader.

Also, use pointer arithmetic instead of dereferencing the `ops` array.
This is critical in case we wind up stepping beyond the bounds of the
array.
2019-02-13 12:37:24 -06:00
Chip Davis
0bb6bbda22 Never flatten outputs when capturing them.
There's no need to do so, since these are not stage-out structs being
returned, but regular structures being written to a buffer. This also
neatly avoids issues writing to composite (e.g. arrayed) per-patch
outputs from a tessellation control shader.
2019-02-11 17:18:54 -06:00
Chip Davis
1919eb1b46 Pass the original pointer type to ensure_correct_attribute_type().
This prevents us from overwriting the variable's type with a non-pointer
type.
2019-02-11 16:07:43 -06:00
Chip Davis
eb89c3a428 MSL: Add support for tessellation control shaders.
These are transpiled to kernel functions that write the output of the
shader to three buffers: one for per-vertex varyings, one for per-patch
varyings, and one for the tessellation levels. This structure is
mandated by the way Metal works, where the tessellation factors are
supplied to the draw method in their own buffer, while the per-patch and
per-vertex varyings are supplied as though they were vertex attributes;
since they have different step rates, they must be in separate buffers.

The kernel is expected to be run in a workgroup whose size is the
greater of the number of input or output control points. It uses Metal's
support for vertex-style stage input to a compute shader to get the
input values; therefore, at least one instance must run per input point.
Meanwhile, Vulkan mandates that it run at least once per output point.
Overrunning the output array is a concern, but any values written should
either be discarded or overwritten by subsequent patches. I'm probably
going to put some slop space in the buffer when I integrate this into
MoltenVK to be on the safe side.
2019-02-07 08:51:22 -06:00
Hans-Kristian Arntzen
d9ed3dcc7a
Merge pull request #848 from cdavis5e/capture-output-buffer
MSL: Add a setting to capture vertex shader output to a buffer.
2019-02-07 15:11:41 +01: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
Hans-Kristian Arntzen
3e584f2c3f Support LUTs in single-function CFGs on Private storage class.
Fairly common pattern in unoptimized SPIR-V. Support this case as well.
2019-02-06 10:38:59 +01: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
fcbe999d99 MSL: Fix another test incompatibility. 2019-01-30 17:22:38 +01:00
Hans-Kristian Arntzen
b78ffa1cc7 Fixup MSL iOS test. 2019-01-30 16:26:41 +01:00
Hans-Kristian Arntzen
2ed171e525 GLSL/MSL: Implement 8-bit part of VK_KHR_shader_float16_int8.
Storage was in place already, so mostly just dealing with bitcasts and
constants.

Simplies some of the bitcasting logic, and this exposed some bugs in the
implementation. Refactor to use correct width integers with explicit bitcast opcodes.
2019-01-30 15:45:24 +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
3e09879131 Support initializers on StorageClassOutput. 2019-01-30 10:29:08 +01:00
Hans-Kristian Arntzen
912fde95f1 MSL: Use correct size for structs.
Need to align the size of structs to the natural alignment.
2019-01-28 15:20:30 +01:00
Hans-Kristian Arntzen
217eb5b5f9 MSL: Add a preliminary check for bad arrays of structs.
ArrayStride can be larger than the declared struct size.
We have no obvious solution for now, but warn about it in the MSL output
for the time being.
2019-01-28 15:20:30 +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
18a4accd2f HLSL/MSL: Fix texture projection with Dref.
We need to divide the Dref by q.
2019-01-28 10:25:13 +01:00
Hans-Kristian Arntzen
437fc87a89 MSL: Deal with resource name aliasing.
Apparently we didn't use those yet. MSL seems to be able to alias struct
types and variable types to a degree, so that's why it has escaped
testing until now.
2019-01-18 16:27:57 +01:00
Hans-Kristian Arntzen
1040cf6cc1
Merge pull request #831 from cdavis5e/force-recompile-hooks
MSL: Hoist fixup hooks in entry_point_args() out of the compile loop.
2019-01-17 19:42:05 +01:00
Chip Davis
f500d2f70c MSL: Hoist fixup hooks in entry_point_args() out of the compile loop.
Otherwise, in the event of a forced recompile, we could end up adding
them twice.
2019-01-17 10:18:38 -06:00
Hans-Kristian Arntzen
3aa08f764e MSL: Fix image load/store for short vectors.
Same fixes as for GLSL.
2019-01-17 14:54:29 +01:00
Hans-Kristian Arntzen
432aaed737 Need to know the original packed type when unpacking loads. 2019-01-17 11:39:46 +01:00
Hans-Kristian Arntzen
f4b74f2f4f Add basic test for std140 small vector arrays. 2019-01-17 11:29:09 +01:00
Hans-Kristian Arntzen
de7e5ccd8b Refactor out packed expressions to extended decorations.
Can't safely just cast to the original enum without lots of hacks.
2019-01-17 11:28:51 +01:00
Hans-Kristian Arntzen
f4026a5618 Refactor access_chain_internal to be more readable from callsite. 2019-01-17 10:30:13 +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
b8033d7525 MSL: Add option to pad fragment outputs.
If not enough components are provided in the shader,
the shader MSL compiler throws an error rather than make components
undefined. This hurts portability, so we need to add explicit padding
here.
2019-01-14 15:11:52 +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
Chip Davis
d6aa911156 Flush all variables after storing through a variable pointer.
Since we can't know which variable was modified, we therefore have to
conservatively assume that any variable might have been modified.
2019-01-08 15:16:33 -06:00
Chip Davis
3bfb2f94d4 MSL: Support SPV_KHR_variable_pointers.
This allows shaders to declare and use pointer-type variables. Pointers
may be loaded and stored, be the result of an `OpSelect`, be passed to
and returned from functions, and even be passed as inputs to the `OpPhi`
instruction. All types of pointers may be used as variable pointers.
Variable pointers to storage buffers and workgroup memory may even be
loaded from and stored to, as though they were ordinary variables. In
addition, this enables using an interior pointer to an array as though
it were an array pointer itself using the `OpPtrAccessChain`
instruction.

This is a rather large and involved change, mostly because this is
somewhat complicated with a lot of moving parts. It's a wonder
SPIRV-Cross's output is largely unchanged. Indeed, many of these changes
are to accomplish exactly that! Perhaps the largest source of changes
was the violation of the assumption that, when emitting types, the
pointer type didn't matter.

One of the test cases added by the change doesn't optimize very well;
the output of `spirv-opt` here is invalid SPIR-V. I need to file a bug
with SPIRV-Tools about this.

I wanted to test that variable pointers to images worked too, but I
couldn't figure out how to propagate the access qualifier properly--in
MSL, it's part of the type, so getting this right is important. I've
punted on that for now.
2019-01-07 11:19:10 -06:00
Hans-Kristian Arntzen
cacfeef89e
Merge pull request #804 from KhronosGroup/fix-788
Forward meta information in OpCompositeExtract.
2019-01-07 11:43:43 +01:00
Hans-Kristian Arntzen
66263d4569 Forward meta information in OpCompositeExtract.
Just like OpAccessChain we need to make use of the meta information
available to use from access_chain_internal as we can extract a packed
vector or transposed vector from a composite, not just memory load.
2019-01-07 10:43:55 +01:00
Hans-Kristian Arntzen
649ce3c7bb MSL: Workaround missing gradient2d() for sampler_compare. 2019-01-07 10:01:00 +01:00
Hans-Kristian Arntzen
211abfb7ef
Merge pull request #799 from KhronosGroup/fix-780
Use correct block-name / other-name aliasing rules.
2019-01-04 16:08:10 +01:00
Hans-Kristian Arntzen
9728f9c1b7 Use correct block-name / other-name aliasing rules.
A block name cannot alias with any name in its own scope,
and it cannot alias with any other "global" name.

To solve this, we need to complicate the name cache updates a little bit
where we have a "primary" namespace and "secondary" namespace.
2019-01-04 15:02:54 +01:00
Hans-Kristian Arntzen
acae607703 Register implied expression reads in OpLoad/OpAccessChain.
This is required to avoid relying on complex sub-expression elimination
in compilers, and generates cleaner code.

The problem case is if a complex expression is used in an access chain,
like:

Composite comp = buffer[texture(...)];
vec4 a = comp.a + comp.b + comp.c;

Before, we did not have common subexpression tracking for
OpLoad/OpAccessChain, so we easily ended up with code like:

vec4 a = buffer[texture(...)].a + buffer[texture(...)].b + buffer[texture(...)].c;

A good compiler will optimize this, but we should not rely on it, and
forcing texture(...) to a temporary also looks better.

The solution is to add a vector "implied_expression_reads", which works
similarly to expression_dependencies. We also need an extra mechanism in
to_expression which lets us skip expression read checking and do it
later. E.g. for expr -> access chain -> load, we should only trigger
a read of expr when using the loaded expression.
2019-01-04 14:56:12 +01:00
Hans-Kristian Arntzen
61f1d8b2cf Support gl_HelperInvocation on GLSL and MSL.
There is no obvious builtin for this on HLSL.
2018-11-28 15:18:43 +01:00
Hans-Kristian Arntzen
04f410d35c Fix unsigned switch case selectors. 2018-11-26 10:36:50 +01:00
Hans-Kristian Arntzen
510e1475c6
Merge pull request #756 from cdavis5e/relaxed-block-layout-2
MSL: Also pack 2- and 4- element vectors when necessary.
2018-11-15 10:09:09 +01:00
Chip Davis
a5882da091 Test loading from and storing to packed vectors. 2018-11-14 10:47:20 -06:00
Chip Davis
6d675ae6a2 Correct carry/borrow bit checks.
Don't use `addsat()`/`subsat()`; that'll erroneously flag cases where
the sum is exactly the maximum integer value, or the difference is
exactly 0. Also, correct the condition for the `select()` function; it's
basically `mix()` with a boolean factor.

(What was I *thinking*?)
2018-11-14 10:13:56 -06:00
Chip Davis
cf2a890e4f MSL: Support extended arithmetic opcodes. 2018-11-13 17:33:03 -06:00
Chip Davis
bed4918cb5 MSL: Also pack 2- and 4- element vectors when necessary.
This is also needed for `VK_KHR_relaxed_block_layout` support.
2018-11-13 17:31:47 -06:00
Hans-Kristian Arntzen
d6be21543d MSL: Split out early_fragment_tests.
Was causing compilation failures, jumped the merge a bit too soon.
2018-11-12 16:20:49 +01:00
Hans-Kristian Arntzen
4e5c8d7199 Deal with depth_greater/depth_less qualifiers.
Adds support on HLSL SM 5.0, and fixes bug on GLSL.
Makes sure early fragment tests is tested on MSL as well.
2018-11-12 10:35:36 +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
Chip Davis
e50eecfeeb MSL: Also pack members at unaligned offsets.
This is necessary to support `VK_KHR_relaxed_block_layout`.
2018-11-07 09:42:54 -06:00
Chip Davis
0d949e11ff Support bitcasts of 16-bit types. 2018-11-05 14:56:36 -06:00
Chip Davis
ca4744ab72 Support constants of 16-bit integral type in GLSL and MSL.
Constants of 8-bit type aren't supported in GLSL, since there's no
extension letting you use them.
2018-11-02 14:39:55 -05:00
Chip Davis
1fb27b4cda Add support for 8- and 16-bit types to GLSL and MSL.
In GLSL, 8-bit types require GL_EXT_shader_8bit_storage. 16-bit types
can use either GL_AMD_gpu_shader_int16/GL_AMD_gpu_shader_half_float or
GL_EXT_shader_16bit_storage.
2018-11-01 10:20:57 -05:00
Hans-Kristian Arntzen
480acdad18 Deal with OpSpecConstantOp used as array size.
When trying to validate buffer sizes, we usually need to bail out when
using SpecConstantOps, but for some very specific cases where we allow
unsized arrays currently, we can safely allow "unknown" sized arrays as
well.

This is probably the best we can do, when we have even more difficult
cases than this, we throw a more sensible error message.
2018-11-01 14:58:02 +01:00
Hans-Kristian Arntzen
d4ad1e266a Add test case for local_size_x_id and some complex cases. 2018-11-01 11:23:48 +01:00
Hans-Kristian Arntzen
62db535b3f Update tests. 2018-11-01 11:23:48 +01:00
Hans-Kristian Arntzen
6157bf3cae Add Windows support in Travis CI.
- Add new Windows support
- Use CMake/CTest instead of Make + shell scripts
- Use --parallel in CTest
- Fix CTest on Windows
- Cleanups in test_shaders.py
- Force specific commit for SPIRV-Headers
- Fix Inf/NaN odd-ball case by moving to ASM
2018-10-27 00:22:30 +02:00
Chip Davis
47089a48a0 Make the test case a lot simpler. 2018-10-04 11:26:46 -05:00
Chip Davis
9919fbbe0d MSL: Handle OpImage on OpSampledImage expressions.
I have seen this happen. The included test case is one such case.
2018-10-03 11:48:46 -05: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
2506046cb4 Merge remote-tracking branch 'origin' into resource-arrays-msl 2018-09-27 10:50:16 -05:00
Hans-Kristian Arntzen
af75ef005f Update glslang and SPIRV-Tools.
A lot of changes in spirv-opt output.
Some new invalid SPIR-V was found but most of them were not significant
for SPIRV-Cross, so just marked them as invalid.
2018-09-27 11:10:22 +02: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
Chip Davis
7cb817e40e Add spvTexelBufferCoord for buffer image reads, too.
I should've caught this when I fixed this for writes.
2018-09-23 14:37:03 -05:00
Chip Davis
ec857f6778 Cast uses of Layer and ViewportIndex to the expected type. 2018-09-19 09:13:30 -05:00
Chip Davis
0e9ad14ba6 MSL: Handle the ViewportIndex builtin.
This requires MSL 2.0+.

Also, force `ViewportIndex` and `Layer` to be defined as the correct
type, which is always `uint` in MSL.

Since Metal doesn't yet have geometry shaders, the vertex shader (or
tessellation evaluation shader == "post-tessellation vertex shader" in
Metal jargon) is the only kind of shader that can set this output. This
currently requires an extension to Vulkan, which causes validation of
the SPIR-V binaries for the test cases to fail. Therefore, the test
cases are marked "invalid", even though they're actually perfectly valid
SPIR-V--they just won't work without the
`SPV_EXT_shader_viewport_index_layer` extension.
2018-09-18 09:52:30 -05:00
Chip Davis
7dcfed888a Use a hook to emit a local for the sample position.
That way, we don't have to handle it specially when constructing a call.
2018-09-17 11:51:09 -05:00
Chip Davis
72fc1cce53 Merge remote-tracking branch 'origin' into msl-sample-pos 2018-09-17 11:20:34 -05:00
Hans-Kristian Arntzen
a77880787d
Merge pull request #698 from KhronosGroup/fix-695
MSL: Support global I/O block and struct Input/Output usage.
2018-09-17 14:54:58 +02:00
Chip Davis
39bc101e82 MSL: Handle the SamplePosition builtin.
This is somewhat tricky, because in MSL this value is obtained through a
function, `get_sample_position()`. Since the call expression is an
rvalue, it can't be passed by reference, so functions get a copy
instead.

This was the last piece preventing us from turning on sample-rate
shading support in MoltenVK.
2018-09-13 09:34:28 -05:00
Hans-Kristian Arntzen
1bbb4032c8
Merge pull request #693 from cdavis5e/msl-atomic-inc-dec
MSL: Fix OpAtomicIIncrement and OpAtomicIDecrement.
2018-09-13 16:19:27 +02:00
Hans-Kristian Arntzen
d310060f92 MSL: Support global I/O block and struct Input/Output usage.
Implement this by flattening outputs and unflattening inputs explicitly.
This allows us to pass down a single struct instead of dealing with the
insanity that would be passing down each flattened member separately.

Remove stage_uniforms_var_id.
Seems to be dead code. Naked uniforms do not exist in SPIR-V for Vulkan,
which this seems to have been intended for. It was also unused elsewhere.
2018-09-13 16:04:24 +02:00
Chip Davis
986345c754 Fix tests for changes to my last patch. 2018-09-12 09:43:12 -05:00
Hans-Kristian Arntzen
2f65a1583e MSL: Support array-of-arrays composite construction. 2018-09-12 10:25:51 +02:00
Hans-Kristian Arntzen
38d19821d4 MSL: Support copying array of arrays. 2018-09-12 09:54:55 +02:00
Chip Davis
41eb5c43b5 MSL: Fix OpAtomicIIncrement and OpAtomicIDecrement.
We were passing a constant '1' to `emit_atomic_func_op()`--which caused
us to refer to SPIR-V value `%1`, which is almost certainly not what we
want! What we really want is to add/subtract the literal constant '1'
to/from the memory location.
2018-09-11 17:29:54 -05:00
Hans-Kristian Arntzen
403011e973
Merge pull request #684 from cdavis5e/msl-builtin-vector-cast
MSL: Cast uses of builtin vectors to their declared SPIR-V type.
2018-09-11 19:59:58 +02:00
Chip Davis
6757ef8512 Use bitcast_to_builtin_load() instead of hacking to_expression().
This only affects the builtin when it is used, and not when it's passed
to a function. It's a lot cleaner than the way I was doing it before.

Remove the `to_expression()` hack.
2018-09-11 11:15:17 -05:00
Chip Davis
acb3fac747 Opt for a simple value cast in lieu of a bitcast. 2018-09-10 14:05:36 -05:00
Hans-Kristian Arntzen
aa17a02efb Add test shader for composite array initialization. 2018-09-10 10:05:00 +02:00
Hans-Kristian Arntzen
b114889102 Only declare typed initializer list for non-array types.
Also, cleanup now redundant constant_expression virtualization for MSL.
2018-09-10 10:04:17 +02:00
Chip Davis
f7dad9da66 MSL: Cast uses of builtin vectors to their declared SPIR-V type.
In SPIR-V, builtin integral vectors can be either signed or unsigned,
but in MSL they're always unsigned. Unfortunately, the MSL spec forbids
implicit conversions between vector types--even if the corresponding
scalar types would implicitly convert. If you try, the result is a
cryptic error message such as:

```
program_source:37:60: error: cannot convert between vector values of different size ('int4' (aka 'vector_int4') and 'vector_uint4' (vector of 4 'unsigned int' values))
            float4 r3 = as_type<float4>((as_type<int4>(r0) * gl_LocalInvocationID.xyyy) + as_type<int4>(r2));
                                         ~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~
```

Therefore, uses of these builtins must be explicitly cast, since the
rest of the binary likely assumes that the builtin is of its declared
type.
2018-09-08 21:17:54 -05:00
Hans-Kristian Arntzen
9ffd4172b4
Merge pull request #680 from cdavis5e/msl-varying-components
MSL: Account for components when assigning locations to varyings.
2018-09-07 16:01:53 +02:00
Hans-Kristian Arntzen
652d8263e5 Use correct spirv-cross version when testing MSL 1.1 shaders. 2018-09-07 09:45:25 +02:00
Hans-Kristian Arntzen
32823b0838 MSL: Do not emit function constants for version < 1.2. 2018-09-07 09:33:34 +02:00