nir/spirv: Refactor vtn_block_load
authorJason Ekstrand <jason.ekstrand@intel.com>
Sat, 14 Nov 2015 05:31:58 +0000 (21:31 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Sat, 14 Nov 2015 05:32:00 +0000 (21:32 -0800)
We pull the offset calculations out into their own function so we can
re-use it for stores.

src/glsl/nir/spirv_to_nir.c

index db5823c9da104120de08de0a4da401363f409dad..3f4b1202c8fd36bf7f7497c263b922a27e4a6398 100644 (file)
@@ -1160,51 +1160,48 @@ _vtn_block_load(struct vtn_builder *b, nir_intrinsic_op op,
    return val;
 }
 
-static struct vtn_ssa_value *
-vtn_block_load(struct vtn_builder *b, nir_deref_var *src,
-               struct vtn_type *type, nir_deref *src_tail)
+static void
+vtn_block_get_offset(struct vtn_builder *b, nir_deref_var *src,
+                     struct vtn_type **type, nir_deref *src_tail,
+                     nir_ssa_def **index,
+                     unsigned *offset, nir_ssa_def **indirect)
 {
-   unsigned set = src->var->data.descriptor_set;
-   unsigned binding = src->var->data.binding;
-   nir_variable_mode mode = src->var->data.mode;
-
    nir_deref *deref = &src->deref;
 
-   nir_ssa_def *index;
    if (deref->child->deref_type == nir_deref_type_array) {
       deref = deref->child;
-      type = type->array_element;
+      *type = (*type)->array_element;
       nir_deref_array *deref_array = nir_deref_as_array(deref);
-      index = nir_imm_int(&b->nb, deref_array->base_offset);
+      *index = nir_imm_int(&b->nb, deref_array->base_offset);
 
       if (deref_array->deref_array_type == nir_deref_array_type_indirect)
-         index = nir_iadd(&b->nb, index, deref_array->indirect.ssa);
+         *index = nir_iadd(&b->nb, *index, deref_array->indirect.ssa);
    } else {
-      index = nir_imm_int(&b->nb, 0);
+      *index = nir_imm_int(&b->nb, 0);
    }
 
-   unsigned offset = 0;
-   nir_ssa_def *indirect = NULL;
+   *offset = 0;
+   *indirect = NULL;
    while (deref != src_tail) {
       deref = deref->child;
       switch (deref->deref_type) {
       case nir_deref_type_array: {
          nir_deref_array *deref_array = nir_deref_as_array(deref);
          if (deref_array->deref_array_type == nir_deref_array_type_direct) {
-            offset += type->stride * deref_array->base_offset;
+            *offset += (*type)->stride * deref_array->base_offset;
          } else {
-            nir_ssa_def *offset = nir_imul(&b->nb, deref_array->indirect.ssa,
-                                           nir_imm_int(&b->nb, type->stride));
-            indirect = indirect ? nir_iadd(&b->nb, indirect, offset) : offset;
+            nir_ssa_def *off = nir_imul(&b->nb, deref_array->indirect.ssa,
+                                        nir_imm_int(&b->nb, (*type)->stride));
+            *indirect = *indirect ? nir_iadd(&b->nb, *indirect, off) : off;
          }
-         type = type->array_element;
+         *type = (*type)->array_element;
          break;
       }
 
       case nir_deref_type_struct: {
          nir_deref_struct *deref_struct = nir_deref_as_struct(deref);
-         offset += type->offsets[deref_struct->index];
-         type = type->members[deref_struct->index];
+         *offset += (*type)->offsets[deref_struct->index];
+         *type = (*type)->members[deref_struct->index];
          break;
       }
 
@@ -1212,6 +1209,16 @@ vtn_block_load(struct vtn_builder *b, nir_deref_var *src,
          unreachable("unknown deref type");
       }
    }
+}
+
+static struct vtn_ssa_value *
+vtn_block_load(struct vtn_builder *b, nir_deref_var *src,
+               struct vtn_type *type, nir_deref *src_tail)
+{
+   nir_ssa_def *index;
+   unsigned offset;
+   nir_ssa_def *indirect;
+   vtn_block_get_offset(b, src, &type, src_tail, &index, &offset, &indirect);
 
    nir_intrinsic_op op;
    if (src->var->data.mode == nir_var_uniform) {
@@ -1235,8 +1242,9 @@ vtn_block_load(struct vtn_builder *b, nir_deref_var *src,
                     : nir_intrinsic_load_ssbo;
    }
 
-   return _vtn_block_load(b, op, set, binding, mode, index,
-                          offset, indirect, type);
+   return _vtn_block_load(b, op, src->var->data.descriptor_set,
+                          src->var->data.binding, src->var->data.mode,
+                          index, offset, indirect, type);
 }
 
 /*