From 1a1bbfd03acd1a7975c6380d637bac580ce78cb8 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 16 Jan 2025 17:17:13 +0900 Subject: [PATCH] [qfcc] Detect interface blocks This gets the `offset` layout working for block members. --- tools/qfcc/include/symtab.h | 1 + tools/qfcc/source/glsl-block.c | 3 ++- tools/qfcc/source/glsl-layout.c | 40 ++++++++++++++++++++++----------- tools/qfcc/source/glsl-parse.y | 3 ++- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/tools/qfcc/include/symtab.h b/tools/qfcc/include/symtab.h index 5c7909911..612d64448 100644 --- a/tools/qfcc/include/symtab.h +++ b/tools/qfcc/include/symtab.h @@ -114,6 +114,7 @@ typedef struct symtab_s { struct symtab_s *parent; ///< points to parent table struct symtab_s *next; ///< next in global collection of symtabs stab_type_e type; ///< type of symbol table + int storage; ///< storage class for stab_block int size; ///< size of structure represented by symtab int count; ///< number of real members in structure struct hashtab_s *tab; ///< symbols defined in this table diff --git a/tools/qfcc/source/glsl-block.c b/tools/qfcc/source/glsl-block.c index 8c3cd419e..2e61be5e5 100644 --- a/tools/qfcc/source/glsl-block.c +++ b/tools/qfcc/source/glsl-block.c @@ -115,10 +115,11 @@ glsl_create_block (specifier_t spec, symbol_t *block_sym) .name = new_symbol (block_sym->name), .interface = interface, .attributes = glsl_optimize_attributes (spec.attributes), - .members = new_symtab (current_symtab, stab_struct), + .members = new_symtab (current_symtab, stab_block), .space = defspace_new (ds_backed), }; block->members->name = save_string (block_sym->name); + block->members->storage = spec.storage; block->members->data = block; block->space->alloc_aligned = glsl_block_alloc_loc; Hash_Add (block_tab, block); diff --git a/tools/qfcc/source/glsl-layout.c b/tools/qfcc/source/glsl-layout.c index 1306cf28e..45fe97ed6 100644 --- a/tools/qfcc/source/glsl-layout.c +++ b/tools/qfcc/source/glsl-layout.c @@ -116,15 +116,21 @@ glsl_layout_constant_id (specifier_t spec, const expr_t *qual_name, static void glsl_layout_binding (specifier_t spec, const expr_t *qual_name, - const expr_t *val) + const expr_t *val) { const char *name = expr_string (qual_name); set_attribute (&spec.sym->attributes, name, val); } +static void +glsl_layout_offset (specifier_t spec, const expr_t *qual_name, + const expr_t *val) +{ +} + static void glsl_layout_set (specifier_t spec, const expr_t *qual_name, - const expr_t *val) + const expr_t *val) { const char *name = expr_string (qual_name); set_attribute (&spec.sym->attributes, name, val); @@ -134,9 +140,9 @@ static void glsl_layout_set_property (specifier_t spec, const expr_t *qual_name, const expr_t *val) { - auto interface = glsl_iftype_from_sc (spec.storage); - notice (qual_name, "%s %s %s", glsl_interface_names[interface], - expr_string (qual_name), get_value_string (val->value)); + //auto interface = glsl_iftype_from_sc (spec.storage); + //notice (qual_name, "%s %s %s", glsl_interface_names[interface], + // expr_string (qual_name), get_value_string (val->value)); } static void @@ -248,7 +254,7 @@ static layout_qual_t layout_qualifiers[] = { .if_mask = I(uniform)|I(buffer), }, { .name = "offset", - .apply = E(nullptr), + .apply = E(glsl_layout_offset), .obj_mask = D(var)|D(member), .var_type = V(opaque), .if_mask = I(uniform)|I(buffer), @@ -822,17 +828,24 @@ layout_qual_cmp (const void *_a, const void *_b) return strcasecmp (a->name, b->name); } +static unsigned +get_interface_mask (int storage) +{ + unsigned if_mask = 0; + + auto interface = glsl_iftype_from_sc (storage); + if (interface < glsl_num_interfaces) { + if_mask = 1 << interface; + } + return if_mask; +} + static bool __attribute__((pure)) layout_check_qualifier (const layout_qual_t *qual, specifier_t spec) { unsigned obj_mask = 0; glsl_var_t var_type = var_any; - unsigned if_mask = 0; - - auto interface = glsl_iftype_from_sc (spec.storage); - if (interface < glsl_num_interfaces) { - if_mask = 1 << interface; - } + unsigned if_mask = get_interface_mask (spec.storage); if (spec.sym) { auto sym = spec.sym; if (sym->type) { @@ -869,8 +882,9 @@ layout_check_qualifier (const layout_qual_t *qual, specifier_t spec) var_type = var_gl_FragDepth; } obj_mask = decl_var; - if (sym->table->parent && sym->table->parent->type == stab_struct) { + if (sym->table->type == stab_block) { obj_mask = decl_member; + if_mask = get_interface_mask (sym->table->storage); } } else { obj_mask = decl_block; diff --git a/tools/qfcc/source/glsl-parse.y b/tools/qfcc/source/glsl-parse.y index 748e83902..0271db796 100644 --- a/tools/qfcc/source/glsl-parse.y +++ b/tools/qfcc/source/glsl-parse.y @@ -997,7 +997,8 @@ precision_qualifier struct_specifier : STRUCT IDENTIFIER '{' { - if (current_symtab->type == stab_struct) { + if (current_symtab->type == stab_struct + || current_symtab->type == stab_block) { error (0, "nested struct declaration"); } int op = 's';