diff --git a/tools/qfcc/source/glsl-block.c b/tools/qfcc/source/glsl-block.c index da733d7ef..e1bbe980d 100644 --- a/tools/qfcc/source/glsl-block.c +++ b/tools/qfcc/source/glsl-block.c @@ -39,6 +39,7 @@ #include "tools/qfcc/include/shared.h" #include "tools/qfcc/include/strpool.h" #include "tools/qfcc/include/symtab.h" +#include "tools/qfcc/include/target.h" #include "tools/qfcc/include/type.h" ALLOC_STATE (glsl_block_t, blocks); @@ -79,12 +80,13 @@ glsl_block_clear (void) static const expr_t * block_sym_ref (symbol_t *sym, void *data) { + // data is set to the symbol in the table (saves having to find it) sym = data; glsl_block_t *block = sym->table->data; - auto interface = new_name_expr (glsl_interface_names[block->interface]); - auto blk = new_symbol_expr (block->name); - auto expr = field_expr (interface, blk); - expr = field_expr (expr, new_symbol_expr (sym)); + auto block_sym = block->instance_name; + auto expr = new_field_expr (new_symbol_expr (block_sym), + new_symbol_expr (sym)); + expr->field.type = sym->type; return expr; } @@ -120,13 +122,6 @@ glsl_create_block (specifier_t spec, symbol_t *block_sym) 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); - def->type = sym->type; - sym->sy_type = sy_def; - sym->def = def; - sym->lvalue = true; - } return block; } @@ -135,14 +130,6 @@ glsl_finish_block (glsl_block_t *block, specifier_t spec) { spec.sym = block->name; glsl_apply_attributes (block->attributes, spec); - for (auto sym = block->members->symbols; sym; sym = sym->next) { - if (sym->sy_type == sy_offset) { - //FIXME sc_extern isn't correct (problem with unsized arrays) - sym->def = new_def (sym->name, sym->type, block->space, sc_extern); - sym->sy_type = sy_def; - sym->lvalue = !sym->def->readonly; - } - } } void @@ -159,35 +146,39 @@ glsl_declare_block_instance (glsl_block_t *block, symbol_t *instance_name) } auto interface = interface_sym->namespace; - if (instance_name) { - block->instance_name = instance_name; - auto type = new_type (); - *type = (type_t) { - .type = ev_invalid, - .name = save_string (block->name->name), - .alignment = 4, - .width = 1, - .columns = 1, - .meta = ty_struct, - .symtab = block->members, - }; - instance_name->type = append_type (instance_name->type, type); - instance_name->type = find_type (instance_name->type); - auto space = current_symtab->space;// FIXME - initialize_def (instance_name, nullptr, space, - glsl_sc_from_iftype (block->interface), - current_symtab, nullptr); + if (!instance_name) { + instance_name = new_symbol (""); + } + block->instance_name = instance_name; + auto type = new_type (); + *type = (type_t) { + .type = ev_invalid, + .name = save_string (va (0, "blk %s", block->name->name)), + .alignment = 4, + .width = 1, + .columns = 1, + .meta = ty_struct, + .symtab = block->members, + }; + specifier_t spec = { + .sym = instance_name, + .storage = glsl_sc_from_iftype (block->interface), + }; + spec.sym->type = find_type (type); + auto symtab = current_symtab;// FIXME + current_target.declare_sym (spec, nullptr, symtab, nullptr); + + auto block_sym = symtab_lookup (interface, block->name->name); + if (block_sym) { + error (0, "%s block %s redeclared", interface_name, + block_sym->name); } 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); - } + block_sym = block->name; + block_sym->sy_type = sy_namespace; + block_sym->namespace = block->members; + symtab_addsymbol (interface, block->name); + } + if (!instance_name->name[0]) { 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/target_spirv.c b/tools/qfcc/source/target_spirv.c index 4a9d1edc0..4ede971fd 100644 --- a/tools/qfcc/source/target_spirv.c +++ b/tools/qfcc/source/target_spirv.c @@ -343,6 +343,34 @@ spirv_TypeStruct (const type_t *type, spirvctx_t *ctx) return id; } +static unsigned +spirv_TypeArray (const type_t *type, spirvctx_t *ctx) +{ + auto ele_type = dereference_type (type); + unsigned count = type_count (type); + unsigned tid = type_id (ele_type, ctx); + unsigned id = spirv_id (ctx); + auto globals = ctx->module->globals; + auto insn = spirv_new_insn (SpvOpTypeArray, 4, globals); + INSN (insn, 1) = id; + INSN (insn, 2) = tid; + INSN (insn, 3) = count; + return id; +} + +static unsigned +spirv_TypeRuntimeArray (const type_t *type, spirvctx_t *ctx) +{ + auto ele_type = dereference_type (type); + unsigned tid = type_id (ele_type, ctx); + unsigned id = spirv_id (ctx); + auto globals = ctx->module->globals; + auto insn = spirv_new_insn (SpvOpTypeRuntimeArray, 3, globals); + INSN (insn, 1) = id; + INSN (insn, 2) = tid; + return id; +} + static void spirv_mirror_bool (const type_t *type, unsigned id, spirvctx_t *ctx) { @@ -453,6 +481,13 @@ type_id (const type_t *type, spirvctx_t *ctx) id = spirv_TypePointer (type, ctx); } else if (is_struct (type)) { id = spirv_TypeStruct (type, ctx); + } else if (is_array (type)) { + //FIXME should size be checked against something for validity? + if (type_count (type)) { + id = spirv_TypeArray (type, ctx); + } else { + id = spirv_TypeRuntimeArray (type, ctx); + } } else if (is_boolean (type)) { id = spirv_TypeBool (type, ctx); }