I won't say it belongs in glsl-builtins, though the glsl-specific stuff
probably does (glsl texture handling is a mess). Also adds sampler
attribute handling (which falls back to image when necessary).
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.
GLSL's texture functions are a bit of a nightmare. The return types are
wrong, but I need to decide how I want to pull the sample type from a
texture or sampler.
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).
I decided to not mess with actual casts. In retrospect, this is probably
for the best as it avoids any bit-cast conflicts, but should allow for
block initializers with a few tweaks. `@construct (type, args...)` in
Ruamoko follows the same path as `type(args...)` in glsl.
Because the symbol tables for generic functions are ephemeral (as such),
they need to be easily removed from the scope chain, it's easiest if
definitions are never added to them (instead, they get added to the
parent symbol table). This keeps handling of function declarations or
definitions and their parameter scopes simple as the function gets put
in the global scope still, and the parameter scope simply gets
reconnected to the global scope (really, the generic scope's parent)
when the parameter scope is popped within a generic scope.
Because the glsl front-end uses Ruamoko to compile its builtins, it
needs to switch languages, and the cleanest way to do so is to use a
context object that gets passed around. This removes not only the
current_language global, but also (as a bonus) any real references to
flex's scanner object (there's still a pointer in rua_ctx_t, but it's no
longer a parameter (which caused some pain in the change)).
I'm not sure what it's useful for, but GLSL has a function for it thus I
decided to add the instruction to the VM, so this is part of the
compiler side.
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.
I guess that was a mental FIXME for later, but later came sooner. The
declaration doesn't seem to be working properly, but I'll worry about
that later when I can get some automated tests going.
This gets parameter qualifiers to the parameters and thus `const`
parameters work as expected (even passes validation). However,
in/out/inout do not work yet due to incorrect setup of the function
call: spir-v wants them to be passed by reference (pointers) rather than
by value.
I've long felt build_function_call was getting a bit big, and expr.c
especially so. This should make it easier to rewrite build_function_call
for dealing with target-specific code. As a bonus, the int through ...
warning is already cleaned up.
Now declarations can be deferred too, thus things like generic/template
and inline functions should be possible. However, the most important
thing is this is a step towards a cleaner middle layer for compilation,
separating front-end language from back-end code-gen.
I plan to do this eventually for Ruamoko, but I need it to keep working
for now; it's rather nice having multiple languages. I expect this will
open up a lot of options for inlining, generic/template function
instantiation, etc. Right now, it's helping with specialization
constants in glsl.
Each interface type (in, out, uniform etc) gets its own namespace, and
non-instanced blocks get a namespace (their block name) within the
interface namespace.
The defs for the block members are currently "allocated" to be at offset
-1, but the idea is to allow layout qualifiers to know if the member has
already been located.
Attributes seem appropriate as GLSL's qualifiers affect variables rather
than types (since there's no typedef).
Not much is done with the attributes yet other than some basic error
checking (duplicates of non-layout attributes) and debug output, but
most (if not all) declarations get to the declaration code with
attributes intact.
The version directive really does only some error checking, and
only GL_EXT_multiview and GL_GOOGLE_include_directive are supported for
extensions, but enable/disable work (but not yet warn for multiview).
There's no direct support for namespaces in Ruamoko yet, nor even in
qfcc, but glsl's blocks bring in a bit of foundation for them, even the
concept of "using" (for blocks with no instance name).
The members don't get locations allocated to them yet, but
fstrianglest.vert compiles and links correctly otherwise.
Also, there's no error checking yet.
Other than contructors (and problems with the `out` block) qfcc can
compile fstrianglest.vert to what looks like working ruamoko code.
There's still a lot of work to do, though.
Using a struct with function pointers instead of switching on an enum
makes it much easier to add languages and, more importantly,
sub-languages like glsl's shader stage variants.