mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-11 20:03:11 +00:00
[qfcc] Emit spir-v global variables
This required adding a `var` symbol type. For now, it holds just the storage class, but it might be good for the initializer, too. Also, clean up some pointer/reference inconsistencies.
This commit is contained in:
parent
ae4d87b969
commit
698430630d
5 changed files with 49 additions and 8 deletions
|
@ -35,6 +35,7 @@
|
|||
#endif
|
||||
|
||||
SY_TYPE(name) ///< just a name (referent tbd)
|
||||
SY_TYPE(var) ///< symbol refers to a variable
|
||||
SY_TYPE(offset) ///< symbol refers to a variable (struct member)
|
||||
SY_TYPE(def) ///< symbol refers to a variable
|
||||
SY_TYPE(const) ///< symbol refers to a constant
|
||||
|
|
|
@ -59,6 +59,10 @@ typedef struct symconv_s {
|
|||
void *data;
|
||||
} symconv_t;
|
||||
|
||||
typedef struct var_s {
|
||||
enum storage_class_e storage;
|
||||
} var_t;
|
||||
|
||||
typedef struct symbol_s {
|
||||
struct symbol_s *next; ///< chain of symbols in symbol table
|
||||
struct symtab_s *table; ///< symbol table that owns this symbol
|
||||
|
@ -73,6 +77,7 @@ typedef struct symbol_s {
|
|||
bool is_constexpr:1;
|
||||
struct attribute_s *attributes;
|
||||
union {
|
||||
var_t var; ///< sy_var
|
||||
int offset; ///< sy_offset
|
||||
struct def_s *def; ///< sy_def
|
||||
struct ex_value_s *value; ///< sy_const
|
||||
|
|
|
@ -99,6 +99,9 @@ convert_name (const expr_t *e)
|
|||
&& current_func) {
|
||||
return new_string_expr (GETSTR (e->loc.file));
|
||||
}
|
||||
if (sym->sy_type == sy_var) {
|
||||
return e;
|
||||
}
|
||||
if (!sym->table) {
|
||||
e = error (e, "%s undefined", sym->name);
|
||||
sym->type = type_default;
|
||||
|
|
|
@ -241,6 +241,9 @@ build_args (const expr_t *(*arg_exprs)[2], int *arg_expr_count,
|
|||
if (param_qual & pq_out) {
|
||||
auto inout = new_expr ();
|
||||
inout->type = ex_inout;
|
||||
if (is_reference(get_type (e))) {
|
||||
e = pointer_deref (e);
|
||||
}
|
||||
if (param_qual == pq_inout) {
|
||||
inout->inout.in = cast_expr (arg_types[i], e);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "tools/qfcc/include/defspace.h"
|
||||
#include "tools/qfcc/include/diagnostic.h"
|
||||
#include "tools/qfcc/include/function.h"
|
||||
#include "tools/qfcc/include/glsl-lang.h"
|
||||
#include "tools/qfcc/include/qfcc.h"
|
||||
#include "tools/qfcc/include/spirv.h"
|
||||
#include "tools/qfcc/include/statements.h"
|
||||
|
@ -323,7 +324,7 @@ spirv_TypeFunction (symbol_t *fsym, spirvctx_t *ctx)
|
|||
for (auto p = fsym->params; p; p = p->next) {
|
||||
auto ptype = p->type;
|
||||
if (p->qual != pq_const) {
|
||||
ptype = pointer_type (ptype);
|
||||
ptype = reference_type (ptype);
|
||||
}
|
||||
param_types[num_params++] = type_id (ptype, ctx);
|
||||
}
|
||||
|
@ -434,14 +435,38 @@ spirv_FunctionParameter (const char *name, const type_t *type, spirvctx_t *ctx)
|
|||
}
|
||||
|
||||
static unsigned
|
||||
spirv_variable (symbol_t *sym, SpvStorageClass storage_class, spirvctx_t *ctx)
|
||||
spirv_variable (symbol_t *sym, spirvctx_t *ctx)
|
||||
{
|
||||
if (sym->sy_type != sy_var) {
|
||||
internal_error (0, "unexpected variable symbol type");
|
||||
}
|
||||
auto interface = glsl_iftype_from_sc (sym->var.storage);
|
||||
SpvStorageClass storage;
|
||||
if (interface < glsl_num_interfaces) {
|
||||
static SpvStorageClass iface_storage[glsl_num_interfaces] = {
|
||||
[glsl_in] = SpvStorageClassInput,
|
||||
[glsl_out] = SpvStorageClassOutput,
|
||||
[glsl_uniform] = SpvStorageClassUniform,
|
||||
[glsl_buffer] = SpvStorageClassStorageBuffer,
|
||||
};
|
||||
storage = iface_storage[interface];
|
||||
} else if (sym->var.storage < sc_count) {
|
||||
static SpvStorageClass sc_storage[sc_count] = {
|
||||
[sc_static] = SpvStorageClassPrivate,
|
||||
[sc_local] = SpvStorageClassFunction,
|
||||
};
|
||||
storage = sc_storage[sym->var.storage];
|
||||
}
|
||||
auto space = ctx->module->globals;
|
||||
if (storage == SpvStorageClassFunction) {
|
||||
space = ctx->decl_space;
|
||||
}
|
||||
unsigned id = spirv_id (ctx);
|
||||
//FIXME init value
|
||||
auto insn = spirv_new_insn (SpvOpVariable, 4, ctx->decl_space);
|
||||
INSN (insn, 1) = type_id (sym->type, ctx);
|
||||
auto insn = spirv_new_insn (SpvOpVariable, 4, space);
|
||||
INSN (insn, 1) = type_id (reference_type (sym->type), ctx);
|
||||
INSN (insn, 2) = id;
|
||||
INSN (insn, 3) = storage_class;
|
||||
INSN (insn, 3) = storage;
|
||||
spirv_Name (id, sym->name, ctx);
|
||||
return id;
|
||||
}
|
||||
|
@ -479,7 +504,7 @@ spirv_function (function_t *func, spirvctx_t *ctx)
|
|||
for (auto p = func->sym->params; p; p = p->next) {
|
||||
auto ptype = p->type;
|
||||
if (p->qual != pq_const) {
|
||||
ptype = pointer_type (ptype);
|
||||
ptype = reference_type (ptype);
|
||||
}
|
||||
unsigned pid = spirv_FunctionParameter (p->name, ptype, ctx);
|
||||
if (func->parameters) {
|
||||
|
@ -496,7 +521,7 @@ spirv_function (function_t *func, spirvctx_t *ctx)
|
|||
if (func->locals) {
|
||||
spirv_DeclLabel (ctx);
|
||||
for (auto sym = func->locals->symbols; sym; sym = sym->next) {
|
||||
sym->id = spirv_variable (sym, SpvStorageClassFunction, ctx);
|
||||
sym->id = spirv_variable (sym, ctx);
|
||||
}
|
||||
} else {
|
||||
spirv_Label (ctx);
|
||||
|
@ -780,6 +805,8 @@ spirv_symbol (const expr_t *e, spirvctx_t *ctx)
|
|||
} else if (sym->sy_type == sy_func) {
|
||||
auto func = sym->metafunc->func;
|
||||
sym->id = spirv_function_ref (func, ctx);
|
||||
} else if (sym->sy_type == sy_var) {
|
||||
sym->id = spirv_variable (sym, ctx);
|
||||
} else {
|
||||
internal_error (e, "unexpected symbol type: %s for %s",
|
||||
symtype_str (sym->sy_type), sym->name);
|
||||
|
@ -1002,7 +1029,7 @@ spirv_field (const expr_t *e, spirvctx_t *ctx)
|
|||
auto acc_type = res_type;
|
||||
bool literal_ind = true;
|
||||
if (is_pointer (base_type) || is_reference (base_type)) {
|
||||
acc_type = pointer_type (res_type);
|
||||
acc_type = reference_type (res_type);
|
||||
op = SpvOpAccessChain;
|
||||
literal_ind = false;
|
||||
}
|
||||
|
@ -1251,6 +1278,8 @@ spirv_declare_sym (specifier_t spec, const expr_t *init, symtab_t *symtab,
|
|||
sym->type = reference_type (sym->type);
|
||||
}
|
||||
sym->lvalue = !spec.is_const;
|
||||
sym->sy_type = sy_var;
|
||||
sym->var.storage = spec.storage;
|
||||
symtab_addsymbol (symtab, sym);
|
||||
if (symtab->type == stab_local) {
|
||||
if (init) {
|
||||
|
|
Loading…
Reference in a new issue