mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-22 17:45:37 +00:00
[qfcc] Support matrices in spirv output
With a few more fixes, iqm.vert builds nicely.
This commit is contained in:
parent
5e053fe270
commit
c185d2463b
6 changed files with 66 additions and 19 deletions
tools/qfcc
|
@ -171,6 +171,7 @@ 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 *column_type (const type_t *mat_type) __attribute__((pure));
|
||||
const type_t *base_type (const type_t *vec_type) __attribute__((pure));
|
||||
|
||||
/** Return an integral type of same size as the provided type.
|
||||
|
|
|
@ -2372,7 +2372,7 @@ array_expr (const expr_t *array, const expr_t *index)
|
|||
return index;
|
||||
|
||||
if (!is_pointer (array_type) && !is_array (array_type)
|
||||
&& !is_nonscalar (array_type))
|
||||
&& !is_nonscalar (array_type) && !is_matrix (array_type))
|
||||
return error (array, "not an array");
|
||||
if (!is_integral (index_type))
|
||||
return error (index, "invalid array index type");
|
||||
|
|
|
@ -47,7 +47,9 @@ get_value (const expr_t *e, int i, int j)
|
|||
}
|
||||
if (type_cols (t) > 1) {
|
||||
auto ind = new_int_expr (i, false);
|
||||
e = array_expr (e, ind);
|
||||
auto a = new_array_expr (e, ind);
|
||||
a->array.type = column_type (t);
|
||||
e = a;
|
||||
}
|
||||
if (type_rows (t) > 1) {
|
||||
auto ind = new_int_expr (j, false);
|
||||
|
@ -127,7 +129,7 @@ construct_by_components (const type_t *type, const expr_t *params,
|
|||
|
||||
auto vec = new_expr ();
|
||||
vec->type = ex_vector;
|
||||
vec->vector.type = vector_type (base, num_comp);
|
||||
vec->vector.type = type;
|
||||
list_gather (&vec->vector.list, components, num_comp);
|
||||
return vec;
|
||||
}
|
||||
|
|
|
@ -170,7 +170,19 @@ proc_array (const expr_t *expr)
|
|||
}
|
||||
scoped_src_loc (expr);
|
||||
auto e = new_array_expr (base, index);
|
||||
e->array.type = dereference_type (get_type (base));
|
||||
auto bt = get_type (base);
|
||||
if (is_reference (bt)) {
|
||||
bt = dereference_type (bt);
|
||||
}
|
||||
const type_t *type;
|
||||
if (is_matrix (bt)) {
|
||||
type = column_type (bt);
|
||||
} else if (is_nonscalar (bt)) {
|
||||
type = base_type (bt);
|
||||
} else {
|
||||
type = dereference_type (bt);
|
||||
}
|
||||
e->array.type = type;
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -230,7 +242,7 @@ static bool
|
|||
proc_do_list (ex_list_t *out, const ex_list_t *in)
|
||||
{
|
||||
int count = list_count (in);
|
||||
const expr_t *exprs[count + 1];
|
||||
const expr_t *exprs[count + 1] = {};
|
||||
list_scatter (in, exprs);
|
||||
bool ok = true;
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
|
|
@ -482,8 +482,8 @@ type_id (const type_t *type, spirvctx_t *ctx)
|
|||
// quaternion as vec4
|
||||
auto qtype = vector_type (&type_float, 4);
|
||||
id = type_id (qtype, ctx);
|
||||
} else if (type_cols (type) > 1) {
|
||||
auto ctype = vector_type (base_type (type), type_rows (type));
|
||||
} else if (is_matrix (type)) {
|
||||
auto ctype = column_type (type);
|
||||
unsigned cid = type_id (ctype, ctx);
|
||||
id = spirv_TypeMatrix (cid, type_cols (type), ctx);
|
||||
} else if (type_width (type) > 1) {
|
||||
|
@ -1109,17 +1109,14 @@ spirv_vector_value (const ex_value_t *value, spirvctx_t *ctx)
|
|||
auto base = base_type (value->type);
|
||||
int width = type_width (value->type);
|
||||
ex_value_t *comp_vals[width];
|
||||
if (type_size (base) == 1) {
|
||||
for (int i = 0; i < width; i++) {
|
||||
comp_vals[i] = new_type_value (base, &value->raw_value + i);
|
||||
}
|
||||
} else if (type_size (base) == 2) {
|
||||
for (int i = 0; i < width; i++) {
|
||||
comp_vals[i] = new_type_value (base, &value->raw_value + i * 2);
|
||||
}
|
||||
} else {
|
||||
auto val = &value->raw_value;
|
||||
if (type_size (base) < 1 || type_size (base) > 2) {
|
||||
internal_error (nullptr, "invalid vector component size");
|
||||
}
|
||||
for (int i = 0; i < width; i++) {
|
||||
comp_vals[i] = new_type_value (base, val);
|
||||
val += type_size (base);
|
||||
}
|
||||
unsigned comp_ids[width];
|
||||
for (int i = 0; i < width; i++) {
|
||||
auto e = new_value_expr (comp_vals[i], false);
|
||||
|
@ -1138,12 +1135,40 @@ spirv_vector_value (const ex_value_t *value, spirvctx_t *ctx)
|
|||
return id;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
spirv_matrix_value (const ex_value_t *value, spirvctx_t *ctx)
|
||||
{
|
||||
auto ctype = column_type (value->type);
|
||||
int count = type_cols (value->type);
|
||||
ex_value_t *columns[count];
|
||||
auto val = &value->raw_value;
|
||||
for (int i = 0; i < count; i++) {
|
||||
columns[i] = new_type_value (ctype, val);
|
||||
val += type_size (ctype);
|
||||
columns[i]->id = spirv_vector_value (columns[i], ctx);
|
||||
}
|
||||
|
||||
auto space = ctx->module->globals;
|
||||
int tid = type_id (value->type, ctx);
|
||||
int id = spirv_id (ctx);
|
||||
auto insn = spirv_new_insn (SpvOpConstantComposite, 3 + count, space);
|
||||
INSN (insn, 1) = tid;
|
||||
INSN (insn, 2) = id;
|
||||
for (int i = 0; i < count; i++) {
|
||||
INSN (insn, 3 + i) = columns[i]->id;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
spirv_value (const expr_t *e, spirvctx_t *ctx)
|
||||
{
|
||||
auto value = e->value;
|
||||
if (!value->id) {
|
||||
if (is_nonscalar (value->type) && type_cols (value->type) == 1) {
|
||||
if (is_matrix (value->type)) {
|
||||
return spirv_matrix_value (value, ctx);
|
||||
}
|
||||
if (is_nonscalar (value->type)) {
|
||||
return spirv_vector_value (value, ctx);
|
||||
}
|
||||
unsigned tid = type_id (value->type, ctx);
|
||||
|
@ -1887,7 +1912,7 @@ spirv_build_element_chain (element_chain_t *element_chain, const type_t *type,
|
|||
state.offset = state.field->id;
|
||||
}
|
||||
} else if (is_matrix (type)) {
|
||||
state.type = vector_type (base_type (type), type_rows (type));
|
||||
state.type = column_type (type);
|
||||
} else if (is_nonscalar (type)) {
|
||||
state.type = base_type (type);
|
||||
} else if (is_array (type)) {
|
||||
|
|
|
@ -855,6 +855,12 @@ matrix_type (const type_t *ele_type, int cols, int rows)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const type_t *
|
||||
column_type (const type_t *mat_type)
|
||||
{
|
||||
return vector_type (base_type (mat_type), type_rows (mat_type));
|
||||
}
|
||||
|
||||
const type_t *
|
||||
vector_type (const type_t *ele_type, int width)
|
||||
{
|
||||
|
@ -1040,6 +1046,7 @@ unalias_type (const type_t *type)
|
|||
const type_t *
|
||||
dereference_type (const type_t *type)
|
||||
{
|
||||
// is_ptr is used to catch both pointer and reference
|
||||
if (!is_ptr (type) && !is_field (type) && !is_array (type)) {
|
||||
internal_error (0, "dereference non pointer/field/array type");
|
||||
}
|
||||
|
@ -1575,7 +1582,7 @@ is_math (const type_t *type)
|
|||
if (is_algebra (type)) {
|
||||
return true;
|
||||
}
|
||||
return is_scalar (type) || is_nonscalar (type);
|
||||
return is_scalar (type) || is_nonscalar (type) || is_matrix (type);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
Loading…
Reference in a new issue