+/* Dereference the given base pointer by the access chain */
+static struct vtn_pointer *
+vtn_pointer_dereference(struct vtn_builder *b,
+ struct vtn_pointer *base,
+ struct vtn_access_chain *deref_chain)
+{
+ struct vtn_access_chain *chain =
+ vtn_access_chain_extend(b, base->chain, deref_chain->length);
+ struct vtn_type *type = base->type;
+
+ unsigned start = base->chain ? base->chain->length : 0;
+ for (unsigned i = 0; i < deref_chain->length; i++) {
+ chain->link[start + i] = deref_chain->link[i];
+
+ if (glsl_type_is_struct(type->type)) {
+ assert(deref_chain->link[i].mode == vtn_access_mode_literal);
+ type = type->members[deref_chain->link[i].id];
+ } else {
+ type = type->array_element;
+ }
+ }
+
+ struct vtn_pointer *ptr = rzalloc(b, struct vtn_pointer);
+ ptr->mode = base->mode;
+ ptr->type = type;
+ ptr->var = base->var;
+ ptr->chain = chain;
+
+ return ptr;
+}
+