mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 13:11:00 +00:00
[qfcc] Implement swizzle and arrays for spir-v
Arrays done via the field code since they use the same opcode and logic. For now swizzles are just swizzles and don't support zeroing or negating (but doing one or the other (not both) should be easy).
This commit is contained in:
parent
34277b2050
commit
39514e4f3d
6 changed files with 80 additions and 26 deletions
|
@ -383,6 +383,22 @@ print_field (dstring_t *dstr, const expr_t *e, int level, int id,
|
|||
".", e->loc.line);
|
||||
}
|
||||
|
||||
static void
|
||||
print_array (dstring_t *dstr, const expr_t *e, int level, int id,
|
||||
const expr_t *next)
|
||||
{
|
||||
int indent = level * 2 + 2;
|
||||
|
||||
_print_expr (dstr, e->array.base, level, id, next);
|
||||
_print_expr (dstr, e->array.index, level, id, next);
|
||||
dasprintf (dstr, "%*se_%p -> \"e_%p\" [label=\"b\"];\n", indent, "", e,
|
||||
e->array.base);
|
||||
dasprintf (dstr, "%*se_%p -> \"e_%p\" [label=\"i\"];\n", indent, "", e,
|
||||
e->array.index);
|
||||
dasprintf (dstr, "%*se_%p [label=\"%s\\n%d\"];\n", indent, "", e,
|
||||
"[]", e->loc.line);
|
||||
}
|
||||
|
||||
static void
|
||||
print_subexpr (dstring_t *dstr, const expr_t *e, int level, int id, const expr_t *next)
|
||||
{
|
||||
|
@ -715,9 +731,10 @@ print_swizzle (dstring_t *dstr, const expr_t *e, int level, int id, const expr_t
|
|||
static char swizzle_components[] = "xyzw";
|
||||
int indent = level * 2 + 2;
|
||||
ex_swizzle_t swiz = e->swizzle;
|
||||
int count = type_width (swiz.type);
|
||||
const char *swizzle = "";
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (swiz.zero & (1 << i)) {
|
||||
swizzle = va (0, "%s0", swizzle);
|
||||
} else {
|
||||
|
@ -835,7 +852,7 @@ _print_expr (dstring_t *dstr, const expr_t *e, int level, int id,
|
|||
[ex_incop] = nullptr,
|
||||
[ex_cond] = print_cond,
|
||||
[ex_field] = print_field,
|
||||
[ex_array] = nullptr,
|
||||
[ex_array] = print_array,
|
||||
[ex_decl] = nullptr,
|
||||
};
|
||||
int indent = level * 2 + 2;
|
||||
|
|
|
@ -666,10 +666,14 @@ const expr_t *
|
|||
new_swizzle_expr (const expr_t *src, const char *swizzle)
|
||||
{
|
||||
src = convert_name (src);
|
||||
if (src->type == ex_error) {
|
||||
if (is_error (src)) {
|
||||
return (expr_t *) src;
|
||||
}
|
||||
auto src_type = get_type (src);
|
||||
if (is_reference (src_type)) {
|
||||
src_type = dereference_type (src_type);
|
||||
src = pointer_deref (src);
|
||||
}
|
||||
int src_width = type_width (src_type);
|
||||
ex_swizzle_t swiz = {};
|
||||
|
||||
|
@ -720,7 +724,6 @@ new_swizzle_expr (const expr_t *src, const char *swizzle)
|
|||
swiz.source[comp_count++] = ind;
|
||||
}
|
||||
}
|
||||
swiz.zero |= (0xf << comp_count) & 0xf;
|
||||
swiz.src = src;
|
||||
swiz.type = vector_type (base_type (src_type), comp_count);
|
||||
|
||||
|
|
|
@ -51,7 +51,9 @@ get_value (const expr_t *e, int i, int j)
|
|||
}
|
||||
if (type_rows (t) > 1) {
|
||||
auto ind = new_int_expr (j, false);
|
||||
e = array_expr (e, ind);
|
||||
auto a = new_array_expr (e, ind);
|
||||
a->array.type = base_type (t);
|
||||
e = a;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
|
|
@ -341,6 +341,10 @@ proc_decl (const expr_t *expr)
|
|||
if (decl->assign.dst->type != ex_symbol) {
|
||||
internal_error (decl->assign.dst, "not a symbol");
|
||||
}
|
||||
init = expr_process (init);
|
||||
if (is_error (init)) {
|
||||
return init;
|
||||
}
|
||||
pr.loc = decl->assign.dst->loc;
|
||||
sym = decl->assign.dst->symbol;
|
||||
} else if (decl->type == ex_symbol) {
|
||||
|
|
|
@ -48,12 +48,6 @@ glsl_parse_declaration (specifier_t spec, symbol_t *sym, const expr_t *init,
|
|||
if (sym->type) {
|
||||
internal_error (0, "unexected typed symbol");
|
||||
}
|
||||
if (init) {
|
||||
init = expr_process (init);
|
||||
if (is_error (init)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto attributes = glsl_optimize_attributes (spec.attributes);
|
||||
if (sym && sym->sy_type == sy_expr) {
|
||||
auto id_list = sym->expr;
|
||||
|
|
|
@ -1259,6 +1259,24 @@ spirv_return (const expr_t *e, spirvctx_t *ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
spirv_swizzle (const expr_t *e, spirvctx_t *ctx)
|
||||
{
|
||||
int count = type_width (e->swizzle.type);
|
||||
unsigned src_id = spirv_emit_expr (e->swizzle.src, ctx);
|
||||
unsigned tid = type_id (e->swizzle.type, ctx);
|
||||
unsigned id = spirv_id (ctx);
|
||||
auto insn = spirv_new_insn (SpvOpVectorShuffle, 4 + count, ctx->code_space);
|
||||
INSN (insn, 1) = tid;
|
||||
INSN (insn, 2) = id;
|
||||
INSN (insn, 3) = src_id;
|
||||
INSN (insn, 4) = src_id;
|
||||
for (int i = 0; i < count; i++) {
|
||||
INSN (insn, 5 + i) = e->swizzle.source[i];
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
spirv_extend (const expr_t *e, spirvctx_t *ctx)
|
||||
{
|
||||
|
@ -1341,16 +1359,21 @@ spirv_cond (const expr_t *e, spirvctx_t *ctx)
|
|||
}
|
||||
|
||||
static unsigned
|
||||
spirv_field (const expr_t *e, spirvctx_t *ctx)
|
||||
spirv_field_array (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
|
||||
// convert the left-branching field/array expression chain to a list
|
||||
while (e->type == ex_field || e->type == ex_array) {
|
||||
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
|
||||
for (; e->type == ex_array; e = e->array.base) {
|
||||
list_prepend (&list, e);
|
||||
}
|
||||
}
|
||||
int num_obj = list_count (&list);
|
||||
// e is now the base object of the field/array expression chain
|
||||
auto base_type = get_type (e);
|
||||
unsigned base_id = spirv_emit_expr (e, ctx);
|
||||
int op = SpvOpCompositeExtract;
|
||||
|
@ -1366,20 +1389,29 @@ spirv_field (const expr_t *e, spirvctx_t *ctx)
|
|||
|
||||
int acc_type_id = type_id (acc_type, ctx);
|
||||
int id = spirv_id (ctx);
|
||||
auto insn = spirv_new_insn (op, 4 + num_fields, ctx->code_space);
|
||||
auto insn = spirv_new_insn (op, 4 + num_obj, ctx->code_space);
|
||||
INSN (insn, 1) = acc_type_id;
|
||||
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 obj = l->expr;
|
||||
unsigned index;
|
||||
if (obj->type == ex_field) {
|
||||
if (obj->field.member->type != ex_symbol) {
|
||||
internal_error (obj->field.member, "not a symbol");
|
||||
}
|
||||
auto sym = l->expr->field.member->symbol;
|
||||
if (literal_ind) {
|
||||
*field_ind++ = sym->id;
|
||||
auto sym = obj->field.member->symbol;
|
||||
index = sym->id;
|
||||
} else if (obj->type == ex_array) {
|
||||
index = expr_integral (obj->array.index);
|
||||
} else {
|
||||
auto ind = new_uint_expr (sym->id);
|
||||
internal_error (obj, "what the what?!?");
|
||||
}
|
||||
if (literal_ind) {
|
||||
*field_ind++ = index;
|
||||
} else {
|
||||
auto ind = new_uint_expr (index);
|
||||
*field_ind++ = spirv_emit_expr (ind, ctx);
|
||||
}
|
||||
}
|
||||
|
@ -1471,9 +1503,11 @@ spirv_emit_expr (const expr_t *e, spirvctx_t *ctx)
|
|||
[ex_assign] = spirv_assign,
|
||||
[ex_branch] = spirv_branch,
|
||||
[ex_return] = spirv_return,
|
||||
[ex_swizzle] = spirv_swizzle,
|
||||
[ex_extend] = spirv_extend,
|
||||
[ex_cond] = spirv_cond,
|
||||
[ex_field] = spirv_field,
|
||||
[ex_field] = spirv_field_array,
|
||||
[ex_array] = spirv_field_array,
|
||||
[ex_loop] = spirv_loop,
|
||||
[ex_select] = spirv_select,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue