mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-11 11:51:50 +00:00
[qfcc] Use a separate enum for glsl interfaces
While technically storage classes, they shouldn't pollute other languages. It's a bit hacky mixing enums in one value, but having some macros helps.
This commit is contained in:
parent
c4c4b9f5b4
commit
7a2027276b
6 changed files with 57 additions and 64 deletions
|
@ -45,6 +45,18 @@ extern language_t lang_glsl_tese;
|
|||
extern language_t lang_glsl_geom;
|
||||
extern language_t lang_glsl_frag;
|
||||
|
||||
typedef enum glsl_interface_e : unsigned {
|
||||
glsl_in,
|
||||
glsl_out,
|
||||
glsl_uniform,
|
||||
glsl_buffer,
|
||||
glsl_shared,
|
||||
|
||||
glsl_num_interfaces
|
||||
} glsl_interface_t;
|
||||
#define glsl_iftype_from_sc(sc) ((glsl_interface_t)((sc) - sc_in))
|
||||
#define glsl_sc_from_iftype(it) (((storage_class_t)(it)) + sc_in)
|
||||
|
||||
typedef struct glsl_block_s {
|
||||
struct glsl_block_s *next;
|
||||
const char *name;
|
||||
|
|
|
@ -38,7 +38,7 @@ typedef struct symtab_s symtab_t;
|
|||
|
||||
/** Specify the storage class of a def.
|
||||
*/
|
||||
typedef enum storage_class_e {
|
||||
typedef enum storage_class_e : unsigned {
|
||||
sc_global, ///< def is globally visible across units
|
||||
sc_system, ///< def may be redefined once
|
||||
sc_extern, ///< def is externally allocated
|
||||
|
@ -47,14 +47,15 @@ typedef enum storage_class_e {
|
|||
sc_local, ///< def is local to the current function
|
||||
sc_argument, ///< def is a function argument
|
||||
|
||||
sc_inout,
|
||||
sc_in,
|
||||
sc_out,
|
||||
sc_inout,
|
||||
sc_uniform,
|
||||
sc_buffer,
|
||||
sc_shared,
|
||||
|
||||
sc_count
|
||||
} storage_class_t;
|
||||
|
||||
extern const char *storage_class_names[sc_count];
|
||||
|
||||
typedef struct specifier_s {
|
||||
const type_t *type;
|
||||
const expr_t *type_expr;
|
||||
|
|
|
@ -70,22 +70,12 @@ set_storage_bits (def_t *def, storage_class_t storage)
|
|||
{
|
||||
def->storage_bits = 0;
|
||||
switch (storage) {
|
||||
case sc_out:
|
||||
case sc_buffer:
|
||||
case sc_shared:
|
||||
def->global = true;
|
||||
break;
|
||||
case sc_system:
|
||||
def->system = true;
|
||||
// fall through
|
||||
case sc_global:
|
||||
def->global = true;
|
||||
break;
|
||||
case sc_in:
|
||||
case sc_uniform:
|
||||
def->global = true;
|
||||
def->readonly = true;
|
||||
break;
|
||||
case sc_extern:
|
||||
def->global = true;
|
||||
def->external = true;
|
||||
|
@ -96,6 +86,8 @@ set_storage_bits (def_t *def, storage_class_t storage)
|
|||
def->local = true;
|
||||
break;
|
||||
case sc_inout:
|
||||
case sc_in:
|
||||
case sc_out:
|
||||
case sc_param:
|
||||
def->local = true;
|
||||
def->param = true;
|
||||
|
@ -104,13 +96,15 @@ set_storage_bits (def_t *def, storage_class_t storage)
|
|||
def->local = true;
|
||||
def->argument = true;
|
||||
break;
|
||||
case sc_count:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
deferred_size (storage_class_t storage)
|
||||
{
|
||||
if (storage == sc_in || storage == sc_uniform || storage == sc_buffer) {
|
||||
if (storage >= sc_in) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -42,11 +42,7 @@
|
|||
|
||||
ALLOC_STATE (glsl_block_t, blocks);
|
||||
|
||||
static hashtab_t *input_blocks;
|
||||
static hashtab_t *output_blocks;
|
||||
static hashtab_t *uniform_blocks;
|
||||
static hashtab_t *buffer_blocks;
|
||||
static hashtab_t *shared_blocks;
|
||||
static hashtab_t *interfaces[glsl_num_interfaces];
|
||||
|
||||
static const char *
|
||||
block_get_key (const void *_b, void *)
|
||||
|
@ -58,18 +54,14 @@ block_get_key (const void *_b, void *)
|
|||
void
|
||||
glsl_block_clear (void)
|
||||
{
|
||||
if (input_blocks) {
|
||||
Hash_FlushTable (input_blocks);
|
||||
Hash_FlushTable (output_blocks);
|
||||
Hash_FlushTable (uniform_blocks);
|
||||
Hash_FlushTable (buffer_blocks);
|
||||
Hash_FlushTable (shared_blocks);
|
||||
if (interfaces[glsl_in]) {
|
||||
for (auto i = glsl_in; i < glsl_num_interfaces; i++) {
|
||||
Hash_FlushTable (interfaces[i]);
|
||||
}
|
||||
} else {
|
||||
input_blocks = Hash_NewTable (127, block_get_key, 0, 0, 0);
|
||||
output_blocks = Hash_NewTable (127, block_get_key, 0, 0, 0);
|
||||
uniform_blocks = Hash_NewTable (127, block_get_key, 0, 0, 0);
|
||||
buffer_blocks = Hash_NewTable (127, block_get_key, 0, 0, 0);
|
||||
shared_blocks = Hash_NewTable (127, block_get_key, 0, 0, 0);
|
||||
for (auto i = glsl_in; i < glsl_num_interfaces; i++) {
|
||||
interfaces[i] = Hash_NewTable (127, block_get_key, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,32 +75,10 @@ void
|
|||
glsl_declare_block (specifier_t spec, symbol_t *block_sym,
|
||||
symbol_t *instance_name)
|
||||
{
|
||||
auto interface = glsl_iftype_from_sc(spec.storage);
|
||||
hashtab_t *block_tab = nullptr;
|
||||
switch (spec.storage) {
|
||||
case sc_in:
|
||||
block_tab = input_blocks;
|
||||
break;
|
||||
case sc_out:
|
||||
block_tab = output_blocks;
|
||||
break;
|
||||
case sc_uniform:
|
||||
block_tab = uniform_blocks;
|
||||
break;
|
||||
case sc_buffer:
|
||||
block_tab = buffer_blocks;
|
||||
break;
|
||||
case sc_shared:
|
||||
block_tab = shared_blocks;
|
||||
break;
|
||||
case sc_global:
|
||||
case sc_system:
|
||||
case sc_extern:
|
||||
case sc_static:
|
||||
case sc_param:
|
||||
case sc_local:
|
||||
case sc_argument:
|
||||
case sc_inout:
|
||||
break;
|
||||
if (interface < glsl_num_interfaces) {
|
||||
block_tab = interfaces[interface];
|
||||
}
|
||||
if (!block_tab) {
|
||||
error (0, "invalid storage for block: %d", spec.storage);
|
||||
|
|
|
@ -1133,12 +1133,18 @@ jump_statement
|
|||
|
||||
%%
|
||||
|
||||
|
||||
#define GLSL_INTERFACE(bt) .spec = { .storage = glsl_sc_from_iftype (bt) }
|
||||
static keyword_t glsl_keywords[] = {
|
||||
{"const", GLSL_CONST, .spec = { .is_const = true }},
|
||||
{"uniform", GLSL_UNIFORM, .spec = { .storage = sc_uniform }},
|
||||
{"buffer", GLSL_BUFFER, .spec = { .storage = sc_buffer }},
|
||||
{"shared", GLSL_SHARED, .spec = { .storage = sc_shared }},
|
||||
{"uniform", GLSL_UNIFORM, GLSL_INTERFACE (glsl_uniform)},
|
||||
{"buffer", GLSL_BUFFER, GLSL_INTERFACE (glsl_buffer)},
|
||||
{"shared", GLSL_SHARED, GLSL_INTERFACE (glsl_shared)},
|
||||
// in and out are both parameter qualifiers (sc_in and sc_out) and
|
||||
// glsl interface types (glsl_in and glsl_out). Assume interface type
|
||||
// here.
|
||||
{"in", GLSL_IN, GLSL_INTERFACE (glsl_in )},
|
||||
{"out", GLSL_OUT, GLSL_INTERFACE (glsl_out )},
|
||||
{"inout", GLSL_INOUT, .spec = { .storage = sc_inout }},
|
||||
{"attribute", GLSL_RESERVED},
|
||||
{"varying", GLSL_RESERVED},
|
||||
{"coherent", GLSL_COHERENT},
|
||||
|
@ -1167,9 +1173,6 @@ static keyword_t glsl_keywords[] = {
|
|||
{"if", GLSL_IF},
|
||||
{"else", GLSL_ELSE},
|
||||
{"subroutine", GLSL_RESERVED},
|
||||
{"in", GLSL_IN, .spec = { .storage = sc_in }},
|
||||
{"out", GLSL_OUT, .spec = { .storage = sc_out }},
|
||||
{"inout", GLSL_INOUT},
|
||||
{"int", GLSL_TYPE_SPEC, .spec = {.type = &type_int}},
|
||||
{"void", GLSL_VOID, .spec = {.type = &type_void}},
|
||||
{"bool", GLSL_TYPE_SPEC, .spec = {.type = &type_bool}},
|
||||
|
|
|
@ -40,6 +40,19 @@
|
|||
#include "tools/qfcc/include/symtab.h"
|
||||
#include "tools/qfcc/include/type.h"
|
||||
|
||||
const char *storage_class_names[sc_count] = {
|
||||
"global",
|
||||
"system",
|
||||
"extern",
|
||||
"static",
|
||||
"param",
|
||||
"local",
|
||||
"argument",
|
||||
"inout",
|
||||
"in",
|
||||
"out",
|
||||
};
|
||||
|
||||
language_t current_language;
|
||||
function_t *current_func;
|
||||
class_type_t *current_class;
|
||||
|
|
Loading…
Reference in a new issue