I guess I hadn't thought of it because GLSL doesn't have `auto`, but
since the builtin functions are implemented in Ruamoko, `auto` is
available and I use it for the atomic image functions.
And disable it for GLSL. I might need to make it target-dependent
instead as I don't know if I'll be able to implement it in SPIR-V, and
when I get to the C back-end, it will be superfluous.
Spir-v is pretty slack with the exact types of the operants to the
right-shift instructions so no need to care about the type for shift so
long as it has the correct number of components.
It's still not great (mostly on the language side, I think), but
different glsl shader types get the correct model and fragment shaders
even get the correct mode.
Access qualifiers aren't supported yet, and some of the image handling
is a bit messy (currently tied to glsl when it should be general), but
the basics are there. However, now I've got to sort out the execution
model (need Fragment or GLCompute for ImplicitLod).
It's just a jump to a label at the end of the block, but it's enough for
now as it takes care of the assumption that the return is the last
expression in the inlined function.
This gets the incoming parameters initialized, though currently rather
suboptimally (but that's due to the setup of the call). Next, just need
to handle `return` in inline functions.
The main goal was to make it possible to give generic functions
definitions (since the code would be very dependent on the actual
parameter types), but will also allow for inline functions. It also
helped move a lot of the back-end dependent code out of semantics
processing and almost completely (if not completely) out of the parser.
Possibly more importantly, it gets the dags flushing out of the parser,
which means such is now shared by all front-ends.
There's probably a lot of dead code in expr.c now, but that can be taken
care of another time.
I'm sure there are still some warts, but interface declaration now works
for spir-v and a real vertex shader can be compiled (albeit one that
doesn't use matrices).
Arrays done via the field code since they use the same opcode and logic.
For now swizzles are just swizzles and don't support zeroing or negating
(but doing one or the other (not both) should be easy).
While storing the scope in a block was the right idea, the
implementation wasn't quite right as it resulted in the current scope
getting set at the wrong times resulting in incorrect symbol access when
shadowing was in effect.
Because spir-v's bools are abstract and have no specific size, bool and
lbool need to both have the same spir-v id, as do the vector
counterparts, so when one gets emitted, the id is copied to the mirror
type.
The tags might have other uses thus the generic term, but this allows
spir-v variables to be declared with the correct pointer storage
classes. Now spirv-val is complaining about my interfaces, so progress :)
Non-const params use references and so need somewhere to store the
arguments. Local variables could be passed directly (parameters normally
require function storage class, which local variables are), but that's a
potential optimization for later.
This required adding a `var` symbol type. For now, it holds just the
storage class, but it might be good for the initializer, too.
Also, clean up some pointer/reference inconsistencies.
As I suspected, the dereference was premature, although it can act as an
optimization when multiple fields of an object are accessed, though it
won't work for writes to lvalues (which means my fixes for spir-v
code-gen currently don't work for lvalue writes). Still, progress. Need
to get field member ids set.
It turns out my field access processing works well enough for vectors.
I'm not sure about pointer access as I may have done the pointer
dereference prematurely.
The function parameter and argument types are a mess with respect to
references (and thus calls don't pass validation) but the generated code
seems to be otherwise correct.
spir-v uses SSA, so temps cannot be assigned to directly, so instead use
the temp expression as a reference for the result id of the rhs of the
assignment. This would get function calls working if the they actually
emitted any code (right now, just a place-holder id so spirv-dis doesn't
fall over).