It's intended to be used with MoltenVK to support arbitrary
`VkComponentMapping` settings. The idea is that MoltenVK will pass a
buffer (which it set to some buffer index that isn't being used)
containing packed versions of the `VkComponentMapping` struct, one for
each sampled image.
Yes, this is horribly ugly. It is unfortunately necessary. Much of the
ugliness is to support swizzling gather operations, where we need to
alter the component that the gather operates on--something complicated
by the `gather()` method requiring the passed-in component to be a
constant expression. It doesn't even support swizzling gathers on depth
textures, though I could add that if it turns out we need it.
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.
Need some pretty hideous ladder variable system, but high level
languages do not support breaking out of a loop. break in switch blocks
and break in loops alias each other.
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.
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.
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.
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.