summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir/nir_deref.c
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2018-11-28 12:26:52 -0600
committerJason Ekstrand <[email protected]>2019-01-08 00:38:30 +0000
commite94a027af8953ba22f4daa3009ab71479b35c78f (patch)
tree03a9b69081808ff3bd79f9bfcb257ac7023719ad /src/compiler/nir/nir_deref.c
parentfc9c4f89b85c0116c0dc22a3eaf25f5df88ad657 (diff)
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 <[email protected]> Reviewed-by: Caio Marcelo de Oliveira Filho <[email protected]>
Diffstat (limited to 'src/compiler/nir/nir_deref.c')
-rw-r--r--src/compiler/nir/nir_deref.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c
index 1dffa285037..76bad2dd9db 100644
--- a/src/compiler/nir/nir_deref.c
+++ b/src/compiler/nir/nir_deref.c
@@ -111,7 +111,8 @@ nir_deref_instr_has_indirect(nir_deref_instr *instr)
if (instr->deref_type == nir_deref_type_cast)
return true;
- if (instr->deref_type == nir_deref_type_array &&
+ if ((instr->deref_type == nir_deref_type_array ||
+ instr->deref_type == nir_deref_type_ptr_as_array) &&
!nir_src_is_const(instr->arr.index))
return true;
@@ -121,6 +122,23 @@ nir_deref_instr_has_indirect(nir_deref_instr *instr)
return false;
}
+unsigned
+nir_deref_instr_ptr_as_array_stride(nir_deref_instr *deref)
+{
+ assert(deref->deref_type == nir_deref_type_ptr_as_array);
+ nir_deref_instr *parent = nir_deref_instr_parent(deref);
+ switch (parent->deref_type) {
+ case nir_deref_type_array:
+ return glsl_get_explicit_stride(nir_deref_instr_parent(parent)->type);
+ case nir_deref_type_ptr_as_array:
+ return nir_deref_instr_ptr_as_array_stride(parent);
+ case nir_deref_type_cast:
+ return parent->cast.ptr_stride;
+ default:
+ unreachable("Invalid parent for ptr_as_array deref");
+ }
+}
+
static unsigned
type_get_array_stride(const struct glsl_type *elem_type,
glsl_type_size_align_func size_align)