Merge branch 'wip/nir-vtn' into vulkan
Adds composites and matrix multiplication, plus some control flow fixes.
This commit is contained in:
commit
6ee082718f
|
@ -28,6 +28,10 @@ struct exec_list;
|
|||
|
||||
typedef struct nir_builder {
|
||||
struct exec_list *cf_node_list;
|
||||
|
||||
nir_block *before_block;
|
||||
nir_block *after_block;
|
||||
|
||||
nir_instr *before_instr;
|
||||
nir_instr *after_instr;
|
||||
|
||||
|
@ -48,6 +52,30 @@ nir_builder_insert_after_cf_list(nir_builder *build,
|
|||
struct exec_list *cf_node_list)
|
||||
{
|
||||
build->cf_node_list = cf_node_list;
|
||||
build->before_block = NULL;
|
||||
build->after_block = NULL;
|
||||
build->before_instr = NULL;
|
||||
build->after_instr = NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
nir_builder_insert_before_block(nir_builder *build,
|
||||
nir_block *block)
|
||||
{
|
||||
build->cf_node_list = NULL;
|
||||
build->before_block = block;
|
||||
build->after_block = NULL;
|
||||
build->before_instr = NULL;
|
||||
build->after_instr = NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
nir_builder_insert_after_block(nir_builder *build,
|
||||
nir_block *block)
|
||||
{
|
||||
build->cf_node_list = NULL;
|
||||
build->before_block = NULL;
|
||||
build->after_block = block;
|
||||
build->before_instr = NULL;
|
||||
build->after_instr = NULL;
|
||||
}
|
||||
|
@ -56,6 +84,8 @@ static inline void
|
|||
nir_builder_insert_before_instr(nir_builder *build, nir_instr *before_instr)
|
||||
{
|
||||
build->cf_node_list = NULL;
|
||||
build->before_block = NULL;
|
||||
build->after_block = NULL;
|
||||
build->before_instr = before_instr;
|
||||
build->after_instr = NULL;
|
||||
}
|
||||
|
@ -64,6 +94,8 @@ static inline void
|
|||
nir_builder_insert_after_instr(nir_builder *build, nir_instr *after_instr)
|
||||
{
|
||||
build->cf_node_list = NULL;
|
||||
build->before_block = NULL;
|
||||
build->after_block = NULL;
|
||||
build->before_instr = NULL;
|
||||
build->after_instr = after_instr;
|
||||
}
|
||||
|
@ -73,6 +105,10 @@ nir_builder_instr_insert(nir_builder *build, nir_instr *instr)
|
|||
{
|
||||
if (build->cf_node_list) {
|
||||
nir_instr_insert_after_cf_list(build->cf_node_list, instr);
|
||||
} else if (build->before_block) {
|
||||
nir_instr_insert_before_block(build->before_block, instr);
|
||||
} else if (build->after_block) {
|
||||
nir_instr_insert_after_block(build->after_block, instr);
|
||||
} else if (build->before_instr) {
|
||||
nir_instr_insert_before(build->before_instr, instr);
|
||||
} else {
|
||||
|
@ -240,6 +276,23 @@ nir_swizzle(nir_builder *build, nir_ssa_def *src, unsigned swiz[4],
|
|||
nir_imov_alu(build, alu_src, num_components);
|
||||
}
|
||||
|
||||
/* Selects the right fdot given the number of components in each source. */
|
||||
static inline nir_ssa_def *
|
||||
nir_fdot(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1)
|
||||
{
|
||||
assert(src0->num_components == src1->num_components);
|
||||
switch (src0->num_components) {
|
||||
case 1: return nir_fmul(build, src0, src1);
|
||||
case 2: return nir_fdot2(build, src0, src1);
|
||||
case 3: return nir_fdot3(build, src0, src1);
|
||||
case 4: return nir_fdot4(build, src0, src1);
|
||||
default:
|
||||
unreachable("bad component size");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns a nir_src into a nir_ssa_def * so it can be passed to
|
||||
* nir_build_alu()-based builder calls.
|
||||
|
|
|
@ -240,7 +240,7 @@ glsl_vector_type(enum glsl_base_type base_type, unsigned components)
|
|||
const glsl_type *
|
||||
glsl_matrix_type(enum glsl_base_type base_type, unsigned rows, unsigned columns)
|
||||
{
|
||||
assert(rows > 1 && rows <= 4 && columns > 1 && columns <= 4);
|
||||
assert(rows >= 1 && rows <= 4 && columns >= 1 && columns <= 4);
|
||||
return glsl_type::get_instance(base_type, rows, columns);
|
||||
}
|
||||
|
||||
|
@ -270,3 +270,10 @@ glsl_function_type(const glsl_type *return_type,
|
|||
{
|
||||
return glsl_type::get_function_instance(return_type, params, num_params);
|
||||
}
|
||||
|
||||
const glsl_type *
|
||||
glsl_transposed_type(const struct glsl_type *type)
|
||||
{
|
||||
return glsl_type::get_instance(type->base_type, type->matrix_columns,
|
||||
type->vector_elements);
|
||||
}
|
||||
|
|
|
@ -103,6 +103,8 @@ const struct glsl_type * glsl_function_type(const struct glsl_type *return_type,
|
|||
const struct glsl_function_param *params,
|
||||
unsigned num_params);
|
||||
|
||||
const struct glsl_type *glsl_transposed_type(const struct glsl_type *type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -140,12 +140,14 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSL450Entrypoint entrypoint,
|
|||
{
|
||||
struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
|
||||
val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
|
||||
val->ssa = rzalloc(b, struct vtn_ssa_value);
|
||||
val->ssa->type = val->type;
|
||||
|
||||
/* Collect the various SSA sources */
|
||||
unsigned num_inputs = count - 5;
|
||||
nir_ssa_def *src[3];
|
||||
for (unsigned i = 0; i < num_inputs; i++)
|
||||
src[i] = vtn_ssa_value(b, w[i + 5]);
|
||||
src[i] = vtn_ssa_value(b, w[i + 5])->def;
|
||||
|
||||
nir_op op;
|
||||
switch (entrypoint) {
|
||||
|
@ -158,16 +160,16 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSL450Entrypoint entrypoint,
|
|||
case Ceil: op = nir_op_fceil; break;
|
||||
case Fract: op = nir_op_ffract; break;
|
||||
case Radians:
|
||||
val->ssa = nir_fmul(&b->nb, src[0], nir_imm_float(&b->nb, 0.01745329251));
|
||||
val->ssa->def = nir_fmul(&b->nb, src[0], nir_imm_float(&b->nb, 0.01745329251));
|
||||
return;
|
||||
case Degrees:
|
||||
val->ssa = nir_fmul(&b->nb, src[0], nir_imm_float(&b->nb, 57.2957795131));
|
||||
val->ssa->def = nir_fmul(&b->nb, src[0], nir_imm_float(&b->nb, 57.2957795131));
|
||||
return;
|
||||
case Sin: op = nir_op_fsin; break;
|
||||
case Cos: op = nir_op_fcos; break;
|
||||
case Tan:
|
||||
val->ssa = nir_fdiv(&b->nb, nir_fsin(&b->nb, src[0]),
|
||||
nir_fcos(&b->nb, src[0]));
|
||||
val->ssa->def = nir_fdiv(&b->nb, nir_fsin(&b->nb, src[0]),
|
||||
nir_fcos(&b->nb, src[0]));
|
||||
return;
|
||||
case Pow: op = nir_op_fpow; break;
|
||||
case Exp2: op = nir_op_fexp2; break;
|
||||
|
@ -180,7 +182,7 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSL450Entrypoint entrypoint,
|
|||
case Max: op = nir_op_fmax; break;
|
||||
case Mix: op = nir_op_flrp; break;
|
||||
case Step:
|
||||
val->ssa = nir_sge(&b->nb, src[1], src[0]);
|
||||
val->ssa->def = nir_sge(&b->nb, src[1], src[0]);
|
||||
return;
|
||||
|
||||
case FloatBitsToInt:
|
||||
|
@ -188,7 +190,7 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSL450Entrypoint entrypoint,
|
|||
case IntBitsToFloat:
|
||||
case UintBitsToFloat:
|
||||
/* Probably going to be removed from the final version of the spec. */
|
||||
val->ssa = src[0];
|
||||
val->ssa->def = src[0];
|
||||
return;
|
||||
|
||||
case Fma: op = nir_op_ffma; break;
|
||||
|
@ -207,13 +209,13 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSL450Entrypoint entrypoint,
|
|||
case UnpackHalf2x16: op = nir_op_unpack_half_2x16; break;
|
||||
|
||||
case Length:
|
||||
val->ssa = build_length(&b->nb, src[0]);
|
||||
val->ssa->def = build_length(&b->nb, src[0]);
|
||||
return;
|
||||
case Distance:
|
||||
val->ssa = build_length(&b->nb, nir_fsub(&b->nb, src[0], src[1]));
|
||||
val->ssa->def = build_length(&b->nb, nir_fsub(&b->nb, src[0], src[1]));
|
||||
return;
|
||||
case Normalize:
|
||||
val->ssa = nir_fdiv(&b->nb, src[0], build_length(&b->nb, src[0]));
|
||||
val->ssa->def = nir_fdiv(&b->nb, src[0], build_length(&b->nb, src[0]));
|
||||
return;
|
||||
|
||||
case UaddCarry: op = nir_op_uadd_carry; break;
|
||||
|
@ -256,7 +258,7 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSL450Entrypoint entrypoint,
|
|||
nir_alu_instr *instr = nir_alu_instr_create(b->shader, op);
|
||||
nir_ssa_dest_init(&instr->instr, &instr->dest.dest,
|
||||
glsl_get_vector_elements(val->type), val->name);
|
||||
val->ssa = &instr->dest.dest.ssa;
|
||||
val->ssa->def = &instr->dest.dest.ssa;
|
||||
|
||||
for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++)
|
||||
instr->src[i].src = nir_src_for_ssa(src[i]);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -60,11 +60,27 @@ struct vtn_function {
|
|||
|
||||
nir_function_overload *overload;
|
||||
struct vtn_block *start_block;
|
||||
|
||||
const uint32_t *end;
|
||||
};
|
||||
|
||||
typedef bool (*vtn_instruction_handler)(struct vtn_builder *, uint32_t,
|
||||
const uint32_t *, unsigned);
|
||||
|
||||
struct vtn_ssa_value {
|
||||
union {
|
||||
nir_ssa_def *def;
|
||||
struct vtn_ssa_value **elems;
|
||||
};
|
||||
|
||||
/* For matrices, a transposed version of the value, or NULL if it hasn't
|
||||
* been computed
|
||||
*/
|
||||
struct vtn_ssa_value *transposed;
|
||||
|
||||
const struct glsl_type *type;
|
||||
};
|
||||
|
||||
struct vtn_value {
|
||||
enum vtn_value_type value_type;
|
||||
const char *name;
|
||||
|
@ -77,7 +93,7 @@ struct vtn_value {
|
|||
nir_deref_var *deref;
|
||||
struct vtn_function *func;
|
||||
struct vtn_block *block;
|
||||
nir_ssa_def *ssa;
|
||||
struct vtn_ssa_value *ssa;
|
||||
vtn_instruction_handler ext_handler;
|
||||
};
|
||||
};
|
||||
|
@ -96,6 +112,20 @@ struct vtn_builder {
|
|||
nir_function_impl *impl;
|
||||
struct vtn_block *block;
|
||||
|
||||
/*
|
||||
* In SPIR-V, constants are global, whereas in NIR, the load_const
|
||||
* instruction we use is per-function. So while we parse each function, we
|
||||
* keep a hash table of constants we've resolved to nir_ssa_value's so
|
||||
* far, and we lazily resolve them when we see them used in a function.
|
||||
*/
|
||||
struct hash_table *const_table;
|
||||
|
||||
/*
|
||||
* Map from nir_block to the vtn_block which ends with it -- used for
|
||||
* handling phi nodes.
|
||||
*/
|
||||
struct hash_table *block_table;
|
||||
|
||||
unsigned value_id_bound;
|
||||
struct vtn_value *values;
|
||||
|
||||
|
@ -134,7 +164,7 @@ vtn_value(struct vtn_builder *b, uint32_t value_id,
|
|||
return val;
|
||||
}
|
||||
|
||||
nir_ssa_def *vtn_ssa_value(struct vtn_builder *b, uint32_t value_id);
|
||||
struct vtn_ssa_value *vtn_ssa_value(struct vtn_builder *b, uint32_t value_id);
|
||||
|
||||
typedef void (*vtn_decoration_foreach_cb)(struct vtn_builder *,
|
||||
struct vtn_value *,
|
||||
|
|
Loading…
Reference in New Issue