mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 05:01:24 +00:00
[qfcc] Support vector value expressions for spir-v
It seems constant initializers are different from constants in an expression.
This commit is contained in:
parent
27afd608f1
commit
22794caf11
3 changed files with 46 additions and 1 deletions
|
@ -217,7 +217,7 @@ typedef struct ex_value_s {
|
|||
unsigned id;
|
||||
bool is_constexpr;
|
||||
union {
|
||||
uint8_t raw_value; ///< for memcpy
|
||||
pr_type_t raw_value; ///< for memcpy
|
||||
const char *string_val; ///< string constant
|
||||
double double_val; ///< double constant
|
||||
int64_t long_val; ///< signed 64-bit constant
|
||||
|
|
|
@ -77,6 +77,10 @@ math_constructor (const type_t *type, const expr_t *params, const expr_t *e)
|
|||
if (!ptype) {
|
||||
continue;
|
||||
}
|
||||
if (is_reference (ptype)) {
|
||||
pexpr = pointer_deref (pexpr);
|
||||
ptype = dereference_type (ptype);
|
||||
}
|
||||
if (!is_math (ptype)) {
|
||||
components[c++] = error (pexpr, "invalid type for conversion");
|
||||
continue;
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "tools/qfcc/include/symtab.h"
|
||||
#include "tools/qfcc/include/target.h"
|
||||
#include "tools/qfcc/include/type.h"
|
||||
#include "tools/qfcc/include/value.h"
|
||||
|
||||
#define INSN(i,o) D_var_o(int,(i),o)
|
||||
#define ADD_DATA(d,s) defspace_add_data((d), (s)->data, (s)->size)
|
||||
|
@ -946,11 +947,51 @@ spirv_temp (const expr_t *e, spirvctx_t *ctx)
|
|||
return 0;//FIXME don't want
|
||||
}
|
||||
|
||||
static unsigned spirv_value (const expr_t *e, spirvctx_t *ctx);
|
||||
|
||||
static unsigned
|
||||
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 {
|
||||
internal_error (nullptr, "invalid vector component size");
|
||||
}
|
||||
unsigned comp_ids[width];
|
||||
for (int i = 0; i < width; i++) {
|
||||
auto e = new_value_expr (comp_vals[i], false);
|
||||
comp_ids[i] = spirv_value (e, 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 + width, space);
|
||||
INSN (insn, 1) = tid;
|
||||
INSN (insn, 2) = id;
|
||||
for (int i = 0; i < width; i++) {
|
||||
INSN (insn, 3 + i) = comp_ids[i];
|
||||
}
|
||||
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) {
|
||||
return spirv_vector_value (value, ctx);
|
||||
}
|
||||
unsigned tid = type_id (value->type, ctx);
|
||||
unsigned op = SpvOpConstant;
|
||||
int val_size = 1;
|
||||
|
|
Loading…
Reference in a new issue