mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 05:01:24 +00:00
[qfcc] Use tagged references for spir-v storage
The tags might have other uses thus the generic term, but this allows spir-v variables to be declared with the correct pointer storage classes. Now spirv-val is complaining about my interfaces, so progress :)
This commit is contained in:
parent
fa42478af6
commit
c5613ba1e4
3 changed files with 74 additions and 38 deletions
|
@ -53,6 +53,7 @@ typedef struct ty_func_s {
|
|||
|
||||
typedef struct ty_fldptr_s {
|
||||
const struct type_s *type;
|
||||
unsigned tag;
|
||||
bool deref; ///< automatic dereference for pointers (C++ &)
|
||||
} ty_fldptr_t;
|
||||
|
||||
|
@ -159,7 +160,9 @@ const type_t *find_type (const type_t *new);
|
|||
void new_typedef (const char *name, type_t *type);
|
||||
const type_t *field_type (const type_t *aux);
|
||||
const type_t *pointer_type (const type_t *aux);
|
||||
const type_t *tagged_pointer_type (unsigned tag, const type_t *aux);
|
||||
const type_t *reference_type (const type_t *aux);
|
||||
const type_t *tagged_reference_type (unsigned tag, const type_t *aux);
|
||||
const type_t *vector_type (const type_t *ele_type, int width) __attribute__((pure));
|
||||
const type_t *matrix_type (const type_t *ele_type, int cols, int rows) __attribute__((pure));
|
||||
const type_t *base_type (const type_t *vec_type) __attribute__((pure));
|
||||
|
|
|
@ -269,7 +269,7 @@ spirv_TypePointer (const type_t *type, spirvctx_t *ctx)
|
|||
auto globals = ctx->module->globals;
|
||||
auto insn = spirv_new_insn (SpvOpTypePointer, 4, globals);
|
||||
INSN (insn, 1) = spirv_id (ctx);
|
||||
INSN (insn, 2) = SpvStorageClassFunction;//FIXME
|
||||
INSN (insn, 2) = type->fldptr.tag;
|
||||
INSN (insn, 3) = rid;
|
||||
return INSN (insn, 1);
|
||||
}
|
||||
|
@ -322,7 +322,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 = reference_type (ptype);
|
||||
ptype = tagged_reference_type (SpvStorageClassFunction, ptype);
|
||||
}
|
||||
param_types[num_params++] = type_id (ptype, ctx);
|
||||
}
|
||||
|
@ -432,14 +432,11 @@ spirv_FunctionParameter (const char *name, const type_t *type, spirvctx_t *ctx)
|
|||
return id;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
spirv_variable (symbol_t *sym, spirvctx_t *ctx)
|
||||
static SpvStorageClass
|
||||
spirv_storage_class (unsigned storage)
|
||||
{
|
||||
if (sym->sy_type != sy_var) {
|
||||
internal_error (0, "unexpected variable symbol type");
|
||||
}
|
||||
auto interface = glsl_iftype_from_sc (sym->var.storage);
|
||||
SpvStorageClass storage;
|
||||
auto interface = glsl_iftype_from_sc (storage);
|
||||
SpvStorageClass sc = 0;
|
||||
if (interface < glsl_num_interfaces) {
|
||||
static SpvStorageClass iface_storage[glsl_num_interfaces] = {
|
||||
[glsl_in] = SpvStorageClassInput,
|
||||
|
@ -447,22 +444,39 @@ spirv_variable (symbol_t *sym, spirvctx_t *ctx)
|
|||
[glsl_uniform] = SpvStorageClassUniform,
|
||||
[glsl_buffer] = SpvStorageClassStorageBuffer,
|
||||
};
|
||||
storage = iface_storage[interface];
|
||||
} else if (sym->var.storage < sc_count) {
|
||||
sc = iface_storage[interface];
|
||||
} else if (storage < sc_count) {
|
||||
static SpvStorageClass sc_storage[sc_count] = {
|
||||
[sc_global] = SpvStorageClassPrivate,
|
||||
[sc_static] = SpvStorageClassPrivate,
|
||||
[sc_local] = SpvStorageClassFunction,
|
||||
[sc_inout] = SpvStorageClassFunction,
|
||||
};
|
||||
storage = sc_storage[sym->var.storage];
|
||||
sc = sc_storage[storage];
|
||||
}
|
||||
if (!sc) {
|
||||
internal_error (0, "invalid storage class: %d", storage);
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
spirv_variable (symbol_t *sym, spirvctx_t *ctx)
|
||||
{
|
||||
if (sym->sy_type != sy_var) {
|
||||
internal_error (0, "unexpected variable symbol type");
|
||||
}
|
||||
auto space = ctx->module->globals;
|
||||
auto storage = spirv_storage_class (sym->var.storage);
|
||||
if (storage == SpvStorageClassFunction) {
|
||||
space = ctx->decl_space;
|
||||
}
|
||||
auto type = sym->type;
|
||||
unsigned tid = type_id (type, ctx);
|
||||
unsigned id = spirv_id (ctx);
|
||||
//FIXME init value
|
||||
auto insn = spirv_new_insn (SpvOpVariable, 4, space);
|
||||
INSN (insn, 1) = type_id (reference_type (sym->type), ctx);
|
||||
INSN (insn, 1) = tid;
|
||||
INSN (insn, 2) = id;
|
||||
INSN (insn, 3) = storage;
|
||||
spirv_Name (id, sym->name, ctx);
|
||||
|
@ -514,7 +528,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 = reference_type (ptype);
|
||||
ptype = tagged_reference_type (SpvStorageClassFunction, ptype);
|
||||
}
|
||||
unsigned pid = spirv_FunctionParameter (p->name, ptype, ctx);
|
||||
if (func->parameters) {
|
||||
|
@ -939,7 +953,7 @@ spirv_call (const expr_t *call, spirvctx_t *ctx)
|
|||
arg_ids[i] = spirv_emit_expr (a, ctx);
|
||||
} else {
|
||||
auto psym = new_symbol ("param");
|
||||
psym->type = reference_type (get_type (a));
|
||||
psym->type = tagged_reference_type (SpvStorageClassFunction, get_type (a));
|
||||
psym->sy_type = sy_var;
|
||||
psym->var.storage = SpvStorageClassFunction;
|
||||
psym->id = spirv_variable (psym, ctx);
|
||||
|
@ -1071,7 +1085,8 @@ 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 = reference_type (res_type);
|
||||
unsigned storage = base_type->fldptr.tag;
|
||||
acc_type = tagged_reference_type (storage, res_type);
|
||||
op = SpvOpAccessChain;
|
||||
literal_ind = false;
|
||||
}
|
||||
|
@ -1273,7 +1288,7 @@ spirv_create_param (symtab_t *parameters, symbol_t *param, param_qual_t qual)
|
|||
auto type = param->type;
|
||||
if (qual != pq_const) {
|
||||
param->lvalue = true;
|
||||
type = reference_type (type);
|
||||
type = tagged_reference_type (SpvStorageClassFunction, type);
|
||||
}
|
||||
param->type = type;
|
||||
}
|
||||
|
@ -1315,10 +1330,8 @@ spirv_declare_sym (specifier_t spec, const expr_t *init, symtab_t *symtab,
|
|||
if (check && check->table == symtab) {
|
||||
error (0, "%s redefined", sym->name);
|
||||
}
|
||||
if (symtab->type == stab_local) {
|
||||
// spir-v locals are references
|
||||
sym->type = reference_type (sym->type);
|
||||
}
|
||||
auto storage = spirv_storage_class (spec.storage);
|
||||
sym->type = tagged_reference_type (storage, sym->type);
|
||||
sym->lvalue = !spec.is_const;
|
||||
sym->sy_type = sy_var;
|
||||
sym->var.storage = spec.storage;
|
||||
|
|
|
@ -688,7 +688,7 @@ field_type (const type_t *aux)
|
|||
}
|
||||
|
||||
const type_t *
|
||||
pointer_type (const type_t *aux)
|
||||
tagged_pointer_type (unsigned tag, const type_t *aux)
|
||||
{
|
||||
type_t _new;
|
||||
type_t *new = &_new;
|
||||
|
@ -701,6 +701,7 @@ pointer_type (const type_t *aux)
|
|||
new->alignment = 1;
|
||||
new->width = 1;
|
||||
new->columns = 1;
|
||||
new->fldptr.tag = tag;
|
||||
new->fldptr.deref = false;
|
||||
if (aux) {
|
||||
return find_type (append_type (new, aux));
|
||||
|
@ -708,25 +709,38 @@ pointer_type (const type_t *aux)
|
|||
return new;
|
||||
}
|
||||
|
||||
const type_t *
|
||||
pointer_type (const type_t *aux)
|
||||
{
|
||||
return tagged_pointer_type (0, aux);
|
||||
}
|
||||
|
||||
const type_t *
|
||||
tagged_reference_type (unsigned tag, const type_t *aux)
|
||||
{
|
||||
type_t _new;
|
||||
type_t *new = &_new;
|
||||
|
||||
if (aux)
|
||||
memset (&_new, 0, sizeof (_new));
|
||||
else
|
||||
new = new_type ();
|
||||
new->type = ev_ptr;
|
||||
new->alignment = 1;
|
||||
new->width = 1;
|
||||
new->columns = 1;
|
||||
new->fldptr.tag = tag;
|
||||
new->fldptr.deref = true;
|
||||
if (aux) {
|
||||
return find_type (append_type (new, aux));
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
const type_t *
|
||||
reference_type (const type_t *aux)
|
||||
{
|
||||
type_t _new;
|
||||
type_t *new = &_new;
|
||||
|
||||
if (aux)
|
||||
memset (&_new, 0, sizeof (_new));
|
||||
else
|
||||
new = new_type ();
|
||||
new->type = ev_ptr;
|
||||
new->alignment = 1;
|
||||
new->width = 1;
|
||||
new->columns = 1;
|
||||
new->fldptr.deref = true;
|
||||
if (aux) {
|
||||
return find_type (append_type (new, aux));
|
||||
}
|
||||
return new;
|
||||
return tagged_reference_type (0, aux);
|
||||
}
|
||||
|
||||
const type_t *
|
||||
|
@ -1040,6 +1054,9 @@ print_type_str (dstring_t *str, const type_t *type)
|
|||
}
|
||||
}
|
||||
dasprintf (str, "(%c", type->fldptr.deref ? '&' : '*');
|
||||
if (type->fldptr.tag) {
|
||||
dasprintf (str, "%d", type->fldptr.tag);
|
||||
}
|
||||
print_type_str (str, type->fldptr.type);
|
||||
dasprintf (str, ")");
|
||||
return;
|
||||
|
@ -1266,6 +1283,9 @@ encode_type (dstring_t *encoding, const type_t *type)
|
|||
return;
|
||||
}
|
||||
dasprintf (encoding, type->fldptr.deref ? "&" : "^");
|
||||
if (type->fldptr.tag) {
|
||||
dasprintf (encoding, "%d", type->fldptr.tag);
|
||||
}
|
||||
type = type->fldptr.type;
|
||||
encode_type (encoding, type);
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue