nir/spirv: Rework access chains

Previously, we were creating nir_deref's immediately.  Now, instead, we
have an intermediate vtn_access_chain structure.  While a little more
awkward initially, this will allow us to more easily do structure splitting
on-the-fly.
This commit is contained in:
Jason Ekstrand 2016-01-20 17:11:55 -08:00
parent 824f776355
commit 1112bf633f
4 changed files with 448 additions and 366 deletions

File diff suppressed because it is too large Load diff

View file

@ -88,7 +88,8 @@ vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode,
break;
case SpvOpFunctionParameter: {
struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
struct vtn_value *val =
vtn_push_value(b, w[2], vtn_value_type_access_chain);
assert(b->func_param_idx < b->func->impl->num_params);
unsigned idx = b->func_param_idx++;
@ -97,10 +98,13 @@ vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode,
nir_local_variable_create(b->func->impl,
b->func->impl->function->params[idx].type,
val->name);
b->func->impl->params[idx] = param;
val->deref = nir_deref_var_create(b, param);
val->deref_type = vtn_value(b, w[1], vtn_value_type_type)->type;
val->access_chain = ralloc(b, struct vtn_access_chain);
val->access_chain->var = param;
val->access_chain->length = 0;
val->access_chain->var_type =
vtn_value(b, w[1], vtn_value_type_type)->type;
break;
}
@ -480,7 +484,7 @@ vtn_handle_phis_first_pass(struct vtn_builder *b, SpvOp opcode,
nir_local_variable_create(b->nb.impl, type->type, "phi");
_mesa_hash_table_insert(b->phi_table, w, phi_var);
val->ssa = vtn_variable_load(b, nir_deref_var_create(b, phi_var), type);
val->ssa = vtn_local_load(b, nir_deref_var_create(b, phi_var));
return true;
}
@ -496,8 +500,6 @@ vtn_handle_phi_second_pass(struct vtn_builder *b, SpvOp opcode,
assert(phi_entry);
nir_variable *phi_var = phi_entry->data;
struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
for (unsigned i = 3; i < count; i += 2) {
struct vtn_ssa_value *src = vtn_ssa_value(b, w[i]);
struct vtn_block *pred =
@ -505,7 +507,7 @@ vtn_handle_phi_second_pass(struct vtn_builder *b, SpvOp opcode,
b->nb.cursor = nir_after_block_before_jump(pred->end_block);
vtn_variable_store(b, src, nir_deref_var_create(b, phi_var), type);
vtn_local_store(b, src, nir_deref_var_create(b, phi_var));
}
return true;
@ -565,9 +567,8 @@ vtn_emit_cf_list(struct vtn_builder *b, struct list_head *cf_list,
if ((*block->branch & SpvOpCodeMask) == SpvOpReturnValue) {
struct vtn_ssa_value *src = vtn_ssa_value(b, block->branch[1]);
vtn_variable_store(b, src,
nir_deref_var_create(b, b->impl->return_var),
NULL);
vtn_local_store(b, src,
nir_deref_var_create(b, b->impl->return_var));
}
if (block->branch_type != vtn_branch_type_none) {

View file

@ -419,8 +419,8 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
case GLSLstd450Modf: {
val->ssa->def = nir_ffract(nb, src[0]);
nir_deref_var *out = vtn_value(b, w[6], vtn_value_type_deref)->deref;
nir_store_deref_var(nb, out, nir_ffloor(nb, src[0]), 0xf);
nir_store_deref_var(nb, vtn_nir_deref(b, w[6]),
nir_ffloor(nb, src[0]), 0xf);
return;
}
@ -613,8 +613,7 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
case GLSLstd450Frexp: {
nir_ssa_def *exponent;
val->ssa->def = build_frexp(nb, src[0], &exponent);
nir_deref_var *out = vtn_value(b, w[6], vtn_value_type_deref)->deref;
nir_store_deref_var(nb, out, exponent, 0xf);
nir_store_deref_var(nb, vtn_nir_deref(b, w[6]), exponent, 0xf);
return;
}

View file

@ -41,7 +41,7 @@ enum vtn_value_type {
vtn_value_type_decoration_group,
vtn_value_type_type,
vtn_value_type_constant,
vtn_value_type_deref,
vtn_value_type_access_chain,
vtn_value_type_function,
vtn_value_type_block,
vtn_value_type_ssa,
@ -234,15 +234,25 @@ struct vtn_type {
SpvBuiltIn builtin;
};
struct vtn_access_chain {
nir_variable *var;
struct vtn_type *var_type;
uint32_t length;
/* Struct elements and array offsets */
uint32_t ids[0];
};
struct vtn_image_pointer {
nir_deref_var *deref;
struct vtn_access_chain *image;
nir_ssa_def *coord;
nir_ssa_def *sample;
};
struct vtn_sampled_image {
nir_deref_var *image; /* Image or array of images */
nir_deref_var *sampler; /* Sampler */
struct vtn_access_chain *image; /* Image or array of images */
struct vtn_access_chain *sampler; /* Sampler */
};
struct vtn_value {
@ -257,10 +267,7 @@ struct vtn_value {
nir_constant *constant;
const struct glsl_type *const_type;
};
struct {
nir_deref_var *deref;
struct vtn_type *deref_type;
};
struct vtn_access_chain *access_chain;
struct vtn_image_pointer *image;
struct vtn_sampled_image *sampled_image;
struct vtn_function *func;
@ -383,12 +390,18 @@ struct vtn_ssa_value *vtn_create_ssa_value(struct vtn_builder *b,
struct vtn_ssa_value *vtn_ssa_transpose(struct vtn_builder *b,
struct vtn_ssa_value *src);
nir_deref_var *vtn_nir_deref(struct vtn_builder *b, uint32_t id);
struct vtn_ssa_value *vtn_local_load(struct vtn_builder *b, nir_deref_var *src);
void vtn_local_store(struct vtn_builder *b, struct vtn_ssa_value *src,
nir_deref_var *dest);
struct vtn_ssa_value *
vtn_variable_load(struct vtn_builder *b, nir_deref_var *src,
struct vtn_type *src_type);
vtn_variable_load(struct vtn_builder *b, struct vtn_access_chain *src);
void vtn_variable_store(struct vtn_builder *b, struct vtn_ssa_value *src,
nir_deref_var *dest, struct vtn_type *dest_type);
struct vtn_access_chain *dest);
typedef void (*vtn_decoration_foreach_cb)(struct vtn_builder *,