nir: Add a ptr_as_array deref type

These correspond directly to SPIR-V's OpPtrAccessChain.  As such, they
treat whatever their parent gives them as if it's the first element in
some array and dereferences that array.  If the parent is, itself, an
array deref, then the two indices can just be added together to get the
final array deref.  However, it can also be used in cases where what you
have is a dereference to some random vec2 value somewhere.  In this
case, we require a cast before the ptr_as_array and use the ptr_stride
field in the cast to provide a stride for the ptr_as_array derefs.

Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
This commit is contained in:
Jason Ekstrand
2018-11-28 12:26:52 -06:00
committed by Jason Ekstrand
parent fc9c4f89b8
commit e94a027af8
12 changed files with 106 additions and 13 deletions

View File

@@ -811,6 +811,31 @@ nir_build_deref_array(nir_builder *build, nir_deref_instr *parent,
return deref;
}
static inline nir_deref_instr *
nir_build_deref_ptr_as_array(nir_builder *build, nir_deref_instr *parent,
nir_ssa_def *index)
{
assert(parent->deref_type == nir_deref_type_array ||
parent->deref_type == nir_deref_type_ptr_as_array ||
parent->deref_type == nir_deref_type_cast);
nir_deref_instr *deref =
nir_deref_instr_create(build->shader, nir_deref_type_ptr_as_array);
deref->mode = parent->mode;
deref->type = parent->type;
deref->parent = nir_src_for_ssa(&parent->dest.ssa);
deref->arr.index = nir_src_for_ssa(index);
nir_ssa_dest_init(&deref->instr, &deref->dest,
parent->dest.ssa.num_components,
parent->dest.ssa.bit_size, NULL);
nir_builder_instr_insert(build, &deref->instr);
return deref;
}
static inline nir_deref_instr *
nir_build_deref_array_wildcard(nir_builder *build, nir_deref_instr *parent)
{
@@ -858,7 +883,8 @@ nir_build_deref_struct(nir_builder *build, nir_deref_instr *parent,
static inline nir_deref_instr *
nir_build_deref_cast(nir_builder *build, nir_ssa_def *parent,
nir_variable_mode mode, const struct glsl_type *type)
nir_variable_mode mode, const struct glsl_type *type,
unsigned ptr_stride)
{
nir_deref_instr *deref =
nir_deref_instr_create(build->shader, nir_deref_type_cast);
@@ -866,6 +892,7 @@ nir_build_deref_cast(nir_builder *build, nir_ssa_def *parent,
deref->mode = mode;
deref->type = type;
deref->parent = nir_src_for_ssa(parent);
deref->cast.ptr_stride = ptr_stride;
nir_ssa_dest_init(&deref->instr, &deref->dest,
parent->num_components, parent->bit_size, NULL);