It turns out it didn't need to expand the arguments itself. Now my
@image tests get past the pre-processor. ie, the following works (until
spir-v segs):
#define __image(t,...) @image(t __VA_OPT__(,) __VA_ARGS__)
#define _image(d,...) __image(float, d __VA_OPT__(,) __VA_ARGS__)
@generic(foo=[_image(1D,Array)]) { void bar(foo baz); }
It seems I hadn't understood the C spec very well when I implemented
__VA_ARGS__ as reading it again now was (after a bit of extra thought)
helpful in realizing that __VA_ARGS__ is simply a proper name for the
... "parameter". Fixes __VA_ARGS__ not expanding in the arguments to
another macro.
I think the __VA_ARGS__ magic macro is no longer needed, but I need to
test it properly before deleting it outright.
I'll probably tweak the syntax a little (make placement of the type more
flexible and not generate an error if either type or other arguments are
missing), but I think I like it result:
typedef @image(int, 2D, Array, R8) bimage;
typedef @image(float, 3D, Rgba8) fimage;
typedef @image(float, Cube, Rgba8) cube;
typedef @image(float, Array, Cube) cube_array;
Or mostly silent, since the core and enumeration symbols are expected to
be value, but the enumerant itself does not cause a diagnostic if not
found (needed for checking image dimension and format).
It has come time to get image handle type creation into Ruamoko. This
commit only gets the functions and types independent of glsl, @image (my
plan for dealing with the handles) isn't implemented yet.
It doesn't really work yet for multiple reasons (eg, not an exact match
with the spir-v names, and the type system itself being a little
inadequate), but gotta start somewhere.
It turns out it was completely tangled up when I first wrote it. The
previous correction got things mostly right, but the overall sign was
wrong (ie, it gave -1..0 instead of 1..0)
I had forgotten the parameters needed to be in reverse order (since
constructor_expr was written as the implementation of a function call),
and I had also forgotten I need to do the assignment. No more broken
lights :)
This is a hack until I rethink the entire glsl implementation, but it
gets my vertex shaders such that Vulkan no longer rejects them. However,
there are a couple struct related bugs (next).
Things aren't quite working yet (currently due to buffer blocks not
getting marked NonWritable (or maybe they should be BufferBlock)), but
this gets shader compilation via qfcc working at all, including
automatic dependencies.
This allows struct block members to be copied out of a block for spir-v.
The code may not be optimal (the full struct is copied rather than only
used members), but it gets my vertex shaders compiling again and thus
passing that part of validation.
SPIR-V buffer block members need to be fully decorated with offsets
(recursively), which means that any members with struct or array types
need their own types in order to support having different offset and
stride (arrays) decorations. This breaks struct assignment at the
language level, but that is intentional as I want to deal with the
member copying needed to implement struct assignment before emitting
code. It also removes the need for some of the complication in
target_spirv.c, but I'll deal with that later.
The recursively built tag for nested structs might be a bit too
aggressive, but that too can wait until I have a better idea of what's
needed.
Any matrix, array or struct member in a uniform/buffer block requires
offset and stride annotations. These seem to be calculated correctly
(tricky due to qfcc's internal size system, which I should probably
adjust based on target (I think type_size() and type_align() should help
here). Now I've got fun with incompatible structs that are the same type
in the source (thus pass type checks), but different in the target (due
to concrete vs abstract addressing).
Fixes an ICE when compiling simplex.r (thus its addition to qfcc's
tests). It still fails due to having lost the points parameter, but yet
another automated test :)
It both seems to be a bit of a hack (since it probably doesn't conform
with the GLSL spec, but I've given up on worrying too much about that),
and the most sensible thing to do.
Shadow swizzling can return a single component but OpVectorShuffle
doesn't support returning a scalar. This is essentially duplicating the
vector logic in proc_field.
The whole point of prototypes is to ensure arguments are of the correct
type. Fixes some ints getting into places where floats were expected
(eg, mix, smoothstep, etc).
The function queue needs to be cleared before figuring out the interface
symbols otherwise the variables referenced only by called functions will
not get into the list of interface symbols.
This fixes the constant type reference ICE for subpassLoad. The problem
was stale symbols recorded in the expressions thus gsubpassInput
referred to the allowed types for the generic function rather than the
type specific to the call.
`address_expr()` wasn't enough because it returns pointers instead of
references (quite correct) which messes with checks for references
elsewhere (also quite correct). It seems I've finally got reference
parameters working.