From 99be6f6e41ec6a4faa79c1c0ed85edbb3b11dbd6 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 12 Sep 2024 13:33:42 +0900 Subject: [PATCH] [qfcc] Build namespaces for non-instanced blocks 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. --- tools/qfcc/include/glsl-lang.h | 2 ++ tools/qfcc/include/symtab.h | 1 + tools/qfcc/source/glsl-block.c | 43 ++++++++++++++++++++++++++++++++++ tools/qfcc/source/glsl-parse.y | 7 ++---- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/tools/qfcc/include/glsl-lang.h b/tools/qfcc/include/glsl-lang.h index f724977e5..cc063e037 100644 --- a/tools/qfcc/include/glsl-lang.h +++ b/tools/qfcc/include/glsl-lang.h @@ -36,6 +36,7 @@ typedef struct type_s type_t; typedef struct symbol_s symbol_t; typedef struct symtab_s symtab_t; typedef struct language_s language_t; +typedef struct defspace_s defspace_t; void glsl_init_comp (void); void glsl_init_vert (void); @@ -73,6 +74,7 @@ typedef struct glsl_block_s { glsl_interface_t interface; symtab_t *attributes; symtab_t *members; + defspace_t *space; symbol_t *instance_name; } glsl_block_t; diff --git a/tools/qfcc/include/symtab.h b/tools/qfcc/include/symtab.h index eac92b589..9677d5110 100644 --- a/tools/qfcc/include/symtab.h +++ b/tools/qfcc/include/symtab.h @@ -90,6 +90,7 @@ typedef enum { stab_union, stab_enum, stab_label, + stab_block, } stab_type_e; typedef struct symtab_s { diff --git a/tools/qfcc/source/glsl-block.c b/tools/qfcc/source/glsl-block.c index 8dbb20d6b..9a495e62e 100644 --- a/tools/qfcc/source/glsl-block.c +++ b/tools/qfcc/source/glsl-block.c @@ -33,6 +33,7 @@ #include "QF/va.h" #include "tools/qfcc/include/def.h" +#include "tools/qfcc/include/defspace.h" #include "tools/qfcc/include/diagnostic.h" #include "tools/qfcc/include/glsl-lang.h" #include "tools/qfcc/include/shared.h" @@ -63,6 +64,16 @@ glsl_block_clear (void) interfaces[i] = Hash_NewTable (127, block_get_key, 0, 0, 0); } } + for (auto i = glsl_in; i < glsl_num_interfaces; i++) { + auto name = glsl_interface_names[i]; + if (symtab_lookup (current_symtab, name)) { + internal_error (0, "%s already declared", name); + } + auto sym = new_symbol (name); + sym->sy_type = sy_namespace; + sym->namespace = new_symtab (nullptr, stab_block); + symtab_addsymbol (current_symtab, sym); + } } static const expr_t * @@ -77,6 +88,13 @@ block_sym_ref (symbol_t *sym, void *data) return expr; } +static int +glsl_block_alloc_loc (defspace_t *space, int size, int alignment) +{ + // XXX + return -1; +} + glsl_block_t * glsl_create_block (specifier_t spec, symbol_t *block_sym) { @@ -96,8 +114,10 @@ glsl_create_block (specifier_t spec, symbol_t *block_sym) .interface = interface, .attributes = glsl_optimize_attributes (spec.attributes), .members = new_symtab (current_symtab, stab_struct), + .space = defspace_new (ds_backed), }; block->members->data = block; + block->space->alloc_aligned = glsl_block_alloc_loc; Hash_Add (block_tab, block); for (auto sym = block->members->symbols; sym; sym = sym->next) { auto def = new_def (sym->name, nullptr, nullptr, spec.storage); @@ -111,6 +131,12 @@ glsl_create_block (specifier_t spec, symbol_t *block_sym) void glsl_finish_block (glsl_block_t *block) { + for (auto sym = block->members->symbols; sym; sym = sym->next) { + if (sym->sy_type == sy_var) { + //FIXME sc_extern isn't correct (problem with unsized arrays) + sym->def = new_def (sym->name, sym->type, block->space, sc_extern); + } + } } void @@ -120,6 +146,13 @@ glsl_declare_block_instance (glsl_block_t *block, symbol_t *instance_name) // error recovery return; } + auto interface_name = glsl_interface_names[block->interface]; + auto interface_sym = symtab_lookup (current_symtab, interface_name); + if (!interface_sym) { + internal_error (0, "%s interface not defined", interface_name); + } + auto interface = interface_sym->namespace; + if (instance_name) { block->instance_name = instance_name; auto type = new_type (); @@ -139,6 +172,16 @@ glsl_declare_block_instance (glsl_block_t *block, symbol_t *instance_name) glsl_sc_from_iftype (block->interface), current_symtab); } else { + auto block_sym = symtab_lookup (interface, block->name->name); + if (block_sym) { + error (0, "%s block %s redeclared", interface_name, + block_sym->name); + } else { + block_sym = block->name; + block_sym->sy_type = sy_namespace; + block_sym->namespace = block->members; + symtab_addsymbol (interface, block->name); + } for (auto sym = block->members->symbols; sym; sym = sym->next) { auto new = new_symbol (sym->name); new->sy_type = sy_convert; diff --git a/tools/qfcc/source/glsl-parse.y b/tools/qfcc/source/glsl-parse.y index 6d78caefb..1e38fe55d 100644 --- a/tools/qfcc/source/glsl-parse.y +++ b/tools/qfcc/source/glsl-parse.y @@ -619,8 +619,8 @@ block_declaration : IDENTIFIER '{' { auto spec = $0; - auto block_sym = $IDENTIFIER; - auto block = glsl_create_block (spec, block_sym); + auto sym = $IDENTIFIER; + auto block = glsl_create_block (spec, sym); if (block) { current_symtab = block->members; } @@ -631,10 +631,7 @@ block_declaration auto block = $3; if (block) { current_symtab = block->members->parent; - auto sym = $IDENTIFIER; glsl_finish_block (block); - sym->sy_type = sy_namespace; - sym->namespace = current_symtab; } $$ = block; }