mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 13:11:00 +00:00
[qfcc] Implement field access for spir-v
It turns out my field access processing works well enough for vectors. I'm not sure about pointer access as I may have done the pointer dereference prematurely.
This commit is contained in:
parent
549203d05d
commit
fb58c1aace
1 changed files with 45 additions and 0 deletions
|
@ -984,6 +984,50 @@ spirv_extend (const expr_t *e, spirvctx_t *ctx)
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
spirv_field (const expr_t *e, spirvctx_t *ctx)
|
||||||
|
{
|
||||||
|
auto res_type = get_type (e);
|
||||||
|
ex_list_t list = {};
|
||||||
|
// convert the left-branching field expression chain to a list
|
||||||
|
for (; e->type == ex_field; e = e->field.object) {
|
||||||
|
list_prepend (&list, e);
|
||||||
|
}
|
||||||
|
int num_fields = list_count (&list);
|
||||||
|
// e is now the base object of the field expression chain
|
||||||
|
auto base_type = get_type (e);
|
||||||
|
unsigned base_id = spirv_emit_expr (e, ctx);
|
||||||
|
int op = SpvOpCompositeExtract;
|
||||||
|
bool literal_ind = true;
|
||||||
|
|
||||||
|
if (is_pointer (base_type)) {
|
||||||
|
res_type = pointer_type (res_type);
|
||||||
|
op = SpvOpAccessChain;
|
||||||
|
literal_ind = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tid = type_id (res_type, ctx);
|
||||||
|
int id = spirv_id (ctx);
|
||||||
|
auto insn = spirv_new_insn (op, 4 + num_fields, ctx->code_space);
|
||||||
|
INSN (insn, 1) = tid;
|
||||||
|
INSN (insn, 2) = id;
|
||||||
|
INSN (insn, 3) = base_id;
|
||||||
|
auto field_ind = &INSN (insn, 4);
|
||||||
|
for (auto l = list.head; l; l = l->next) {
|
||||||
|
if (l->expr->field.member->type != ex_symbol) {
|
||||||
|
internal_error (l->expr->field.member, "not a symbol");
|
||||||
|
}
|
||||||
|
auto sym = l->expr->field.member->symbol;
|
||||||
|
if (literal_ind) {
|
||||||
|
*field_ind++ = sym->id;
|
||||||
|
} else {
|
||||||
|
auto ind = new_uint_expr (sym->id);
|
||||||
|
*field_ind++ = spirv_emit_expr (ind, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
spirv_emit_expr (const expr_t *e, spirvctx_t *ctx)
|
spirv_emit_expr (const expr_t *e, spirvctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
@ -998,6 +1042,7 @@ spirv_emit_expr (const expr_t *e, spirvctx_t *ctx)
|
||||||
[ex_branch] = spirv_branch,
|
[ex_branch] = spirv_branch,
|
||||||
[ex_return] = spirv_return,
|
[ex_return] = spirv_return,
|
||||||
[ex_extend] = spirv_extend,
|
[ex_extend] = spirv_extend,
|
||||||
|
[ex_field] = spirv_field,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (e->type >= ex_count) {
|
if (e->type >= ex_count) {
|
||||||
|
|
Loading…
Reference in a new issue