nir: Use an integer index for specifying structure fields
authorJason Ekstrand <jason.ekstrand@intel.com>
Wed, 26 Nov 2014 05:36:25 +0000 (21:36 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Thu, 15 Jan 2015 15:19:02 +0000 (07:19 -0800)
Previously, we used a string name.  It was nice for translating out of GLSL
IR (which also does that) but cumbersome the rest of the time.

Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
src/glsl/nir/glsl_to_nir.cpp
src/glsl/nir/nir.c
src/glsl/nir/nir.h
src/glsl/nir/nir_lower_samplers.cpp
src/glsl/nir/nir_lower_variables_scalar.c
src/glsl/nir/nir_print.c
src/glsl/nir/nir_types.cpp
src/glsl/nir/nir_types.h
src/glsl/nir/nir_validate.c

index 6b90da5481c0a8bc91b6272735dd2cc942c66b2b..19bc664961c1627f7ea194672e9f9ad897268546 100644 (file)
@@ -1753,7 +1753,10 @@ nir_visitor::visit(ir_dereference_record *ir)
 {
    ir->record->accept(this);
 
-   nir_deref_struct *deref = nir_deref_struct_create(this->shader, ir->field);
+   int field_index = this->deref_tail->type->field_index(ir->field);
+   assert(field_index >= 0);
+
+   nir_deref_struct *deref = nir_deref_struct_create(this->shader, field_index);
    deref->deref.type = ir->type;
    this->deref_tail->child = &deref->deref;
    this->deref_tail = &deref->deref;
index 0514158bbdea8689f7d8d5131b79e697840aedb7..3f04de2fee69f8563d1e6d7c840f530e5a82f624 100644 (file)
@@ -529,12 +529,12 @@ nir_deref_array_create(void *mem_ctx)
 }
 
 nir_deref_struct *
-nir_deref_struct_create(void *mem_ctx, const char *field)
+nir_deref_struct_create(void *mem_ctx, unsigned field_index)
 {
    nir_deref_struct *deref = ralloc(mem_ctx, nir_deref_struct);
    deref->deref.deref_type = nir_deref_type_struct;
    deref->deref.child = NULL;
-   deref->elem = ralloc_strdup(deref, field);
+   deref->index = field_index;
    return deref;
 }
 
@@ -566,7 +566,7 @@ copy_deref_array(void *mem_ctx, nir_deref_array *deref)
 static nir_deref_struct *
 copy_deref_struct(void *mem_ctx, nir_deref_struct *deref)
 {
-   nir_deref_struct *ret = nir_deref_struct_create(mem_ctx, deref->elem);
+   nir_deref_struct *ret = nir_deref_struct_create(mem_ctx, deref->index);
    ret->deref.type = deref->deref.type;
    if (deref->deref.child)
       ret->deref.child = nir_copy_deref(mem_ctx, deref->deref.child);
index a9a77f395f3f90bec3e834fce08269260b0925b6..e977159584f7430d4869ca1273915dda1dc637f5 100644 (file)
@@ -650,7 +650,7 @@ typedef struct {
 typedef struct {
    nir_deref deref;
 
-   const char *elem;
+   unsigned index;
 } nir_deref_struct;
 
 #define nir_deref_as_var(_deref) exec_node_data(nir_deref_var, _deref, deref)
@@ -1292,7 +1292,7 @@ nir_ssa_undef_instr *nir_ssa_undef_instr_create(void *mem_ctx);
 
 nir_deref_var *nir_deref_var_create(void *mem_ctx, nir_variable *var);
 nir_deref_array *nir_deref_array_create(void *mem_ctx);
-nir_deref_struct *nir_deref_struct_create(void *mem_ctx, const char *field);
+nir_deref_struct *nir_deref_struct_create(void *mem_ctx, unsigned field_index);
 
 nir_deref *nir_copy_deref(void *mem_ctx, nir_deref *deref);
 
index be6a75525b7f6aa9ca8ce550688a318254d7d231..4fa764ca3789b72fc0b0b9c9a33cd7a1611c7147 100644 (file)
@@ -47,38 +47,41 @@ get_deref_name_offset(nir_deref_var *deref_var,
    *name = ralloc_strdup(mem_ctx, deref_var->var->name);
 
    while (deref->child != NULL) {
-      deref = deref->child;
-      switch (deref->deref_type) {
-         case nir_deref_type_array:
-            deref_array = nir_deref_as_array(deref);
-            if (deref_array->deref_array_type == nir_deref_array_type_indirect) {
-               /* GLSL 1.10 and 1.20 allowed variable sampler array indices,
-                * while GLSL 1.30 requires that the array indices be
-                * constant integer expressions.  We don't expect any driver
-                * to actually work with a really variable array index, so
-                * all that would work would be an unrolled loop counter that
-                * ends up being constant.
-                */
-               ralloc_strcat(&shader_program->InfoLog,
-                           "warning: Variable sampler array index unsupported.\n"
-                           "This feature of the language was removed in GLSL 1.20 "
-                           "and is unlikely to be supported for 1.10 in Mesa.\n");
-            }
-            if (deref->child == NULL) {
-               return deref_array->base_offset;
-            }
-            ralloc_asprintf_append(name, "[%u]", deref_array->base_offset);
-            break;
-
-         case nir_deref_type_struct:
-            deref_struct = nir_deref_as_struct(deref);
-            ralloc_asprintf_append(name, ".%s", deref_struct->elem);
-            break;
-
-         default:
-            assert(0);
-            break;
+      switch (deref->child->deref_type) {
+      case nir_deref_type_array:
+         deref_array = nir_deref_as_array(deref->child);
+         if (deref_array->deref_array_type == nir_deref_array_type_indirect) {
+            /* GLSL 1.10 and 1.20 allowed variable sampler array indices,
+             * while GLSL 1.30 requires that the array indices be
+             * constant integer expressions.  We don't expect any driver
+             * to actually work with a really variable array index, so
+             * all that would work would be an unrolled loop counter that
+             * ends up being constant.
+             */
+            ralloc_strcat(&shader_program->InfoLog,
+                        "warning: Variable sampler array index unsupported.\n"
+                        "This feature of the language was removed in GLSL 1.20 "
+                        "and is unlikely to be supported for 1.10 in Mesa.\n");
+         }
+         if (deref_array->deref.child == NULL) {
+            return deref_array->base_offset;
+         }
+         ralloc_asprintf_append(name, "[%u]", deref_array->base_offset);
+         break;
+
+      case nir_deref_type_struct: {
+         deref_struct = nir_deref_as_struct(deref->child);
+         const char *field = glsl_get_struct_elem_name(deref->type,
+                                                       deref_struct->index);
+         ralloc_asprintf_append(name, ".%s", field);
+         break;
       }
+
+      default:
+         assert(0);
+         break;
+      }
+      deref = deref->child;
    }
 
    return 0;
index 3127dbb19b4baff83e7d05f7ea143b5f15919dfd..3d79b5febf26b6d95554d4114624958795d6e0eb 100644 (file)
@@ -51,7 +51,7 @@ type_size(const struct glsl_type *type)
    case GLSL_TYPE_STRUCT:
       size = 0;
       for (i = 0; i < glsl_get_length(type); i++) {
-         size += type_size(glsl_get_struct_elem_type(type, i));
+         size += type_size(glsl_get_struct_field(type, i));
       }
       return size;
    case GLSL_TYPE_SAMPLER:
@@ -267,12 +267,8 @@ get_deref_offset(nir_deref_var *deref_var, nir_instr *instr,
       } else {
          nir_deref_struct *deref_struct = nir_deref_as_struct(deref);
 
-         unsigned i = 0;
-         while(strcmp(glsl_get_struct_elem_name(parent_type, i),
-                      deref_struct->elem) != 0) {
-            base_offset += type_size(glsl_get_struct_elem_type(parent_type, i));
-            i++;
-         }
+         for (unsigned i = 0; i < deref_struct->index; i++)
+            base_offset += type_size(glsl_get_struct_field(parent_type, i));
       }
    }
 
@@ -411,7 +407,7 @@ reg_const_load(nir_reg_dest reg, nir_constant *constant,
 
       case GLSL_TYPE_STRUCT:
          for (unsigned i = 0; i < glsl_get_length(type); i++) {
-            const struct glsl_type *field = glsl_get_struct_elem_type(type, i);
+            const struct glsl_type *field = glsl_get_struct_field(type, i);
             nir_reg_dest new_reg = reg;
             new_reg.base_offset += offset;
             reg_const_load(new_reg, constant->elements[i], field, impl,
@@ -528,14 +524,10 @@ var_reg_block_copy_impl(nir_reg_src reg, nir_deref_var *deref_head,
       case GLSL_TYPE_STRUCT:
          offset = 0;
          for (unsigned i = 0; i < glsl_get_length(type); i++) {
-            const struct glsl_type *field_type =
-               glsl_get_struct_elem_type(type, i);
-            const char *field_name = glsl_get_struct_elem_name(type, i);
+            const struct glsl_type *field_type = glsl_get_struct_field(type, i);
 
-            nir_deref_struct *deref_struct =
-               nir_deref_struct_create(mem_ctx, field_name);
+            nir_deref_struct *deref_struct = nir_deref_struct_create(mem_ctx, i);
             deref_struct->deref.type = field_type;
-            deref_struct->elem = field_name;
 
             nir_deref_var *new_deref_head =
                nir_deref_as_var(nir_copy_deref(mem_ctx, &deref_head->deref));
index ec60981b5483bc80b16c39266e3c4a67c3b85ef4..9ad2849d376e2f9b91f51d4fa51598d41291954b 100644 (file)
@@ -282,33 +282,42 @@ print_deref_array(nir_deref_array *deref, print_var_state *state, FILE *fp)
 }
 
 static void
-print_deref_struct(nir_deref_struct *deref, print_var_state *state, FILE *fp)
+print_deref_struct(nir_deref_struct *deref, const struct glsl_type *parent_type,
+                   print_var_state *state, FILE *fp)
 {
-   fprintf(fp, ".%s", deref->elem);
+   fprintf(fp, ".%s", glsl_get_struct_elem_name(parent_type, deref->index));
 }
 
 static void
-print_deref(nir_deref *deref, print_var_state *state, FILE *fp)
+print_deref(nir_deref_var *deref, print_var_state *state, FILE *fp)
 {
-   while (deref != NULL) {
-      switch (deref->deref_type) {
+   nir_deref *tail = &deref->deref;
+   nir_deref *pretail = NULL;
+   while (tail != NULL) {
+      switch (tail->deref_type) {
       case nir_deref_type_var:
-         print_deref_var(nir_deref_as_var(deref), state, fp);
+         assert(pretail == NULL);
+         assert(tail == &deref->deref);
+         print_deref_var(deref, state, fp);
          break;
 
       case nir_deref_type_array:
-         print_deref_array(nir_deref_as_array(deref), state, fp);
+         assert(pretail != NULL);
+         print_deref_array(nir_deref_as_array(tail), state, fp);
          break;
 
       case nir_deref_type_struct:
-         print_deref_struct(nir_deref_as_struct(deref), state, fp);
+         assert(pretail != NULL);
+         print_deref_struct(nir_deref_as_struct(tail),
+                            pretail->type, state, fp);
          break;
 
       default:
          unreachable("Invalid deref type");
       }
 
-      deref = deref->child;
+      pretail = tail;
+      tail = pretail->child;
    }
 }
 
@@ -350,7 +359,7 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_var_state *state,
       if (!first)
          fprintf(fp, ", ");
 
-      print_deref(&instr->variables[i]->deref, state, fp);
+      print_deref(instr->variables[i], state, fp);
 
       first = false;
    }
@@ -485,7 +494,7 @@ print_tex_instr(nir_tex_instr *instr, print_var_state *state, FILE *fp)
    }
 
    if (instr->sampler) {
-      print_deref(&instr->sampler->deref, state, fp);
+      print_deref(instr->sampler, state, fp);
    } else {
       fprintf(fp, "%u", instr->sampler_index);
    }
@@ -508,14 +517,14 @@ print_call_instr(nir_call_instr *instr, print_var_state *state, FILE *fp)
       if (i != 0)
          fprintf(fp, ", ");
 
-      print_deref(&instr->params[i]->deref, state, fp);
+      print_deref(instr->params[i], state, fp);
    }
 
    if (instr->return_deref != NULL) {
       if (instr->num_params != 0)
          fprintf(fp, ", ");
       fprintf(fp, "returning ");
-      print_deref(&instr->return_deref->deref, state, fp);
+      print_deref(instr->return_deref, state, fp);
    }
 }
 
index 7f1992b77ff9be6d3fb27c269ec520d3106ac46e..fe0001592d1a86c1bd9d74351ec5970f1cdb4a7b 100644 (file)
@@ -65,15 +65,9 @@ glsl_get_array_element(const glsl_type* type)
 }
 
 const glsl_type *
-glsl_get_struct_field(const glsl_type *type, const char *field)
+glsl_get_struct_field(const glsl_type *type, unsigned index)
 {
-   for (unsigned i = 0; i < type->length; i++) {
-      if (strcmp(type->fields.structure[i].name, field) == 0) {
-         return type->fields.structure[i].type;
-      }
-   }
-
-   return NULL;
+   return type->fields.structure[index].type;
 }
 
 const struct glsl_type *
@@ -112,12 +106,6 @@ glsl_get_length(const struct glsl_type *type)
    return type->length;
 }
 
-const struct glsl_type *
-glsl_get_struct_elem_type(const struct glsl_type *type, unsigned index)
-{
-   return type->fields.structure[index].type;
-}
-
 const char *
 glsl_get_struct_elem_name(const struct glsl_type *type, unsigned index)
 {
index 5b6d068a8cbbdf73a3ced5178a746b521896bfdb..6f91e2dce8db74fe0e7b276f25b03833b6c98789 100644 (file)
@@ -43,7 +43,7 @@ void glsl_print_type(const struct glsl_type *type, FILE *fp);
 void glsl_print_struct(const struct glsl_type *type, FILE *fp);
 
 const struct glsl_type *glsl_get_struct_field(const struct glsl_type *type,
-                                              const char *field);
+                                              unsigned index);
 
 const struct glsl_type *glsl_get_array_element(const struct glsl_type *type);
 
@@ -59,9 +59,6 @@ unsigned glsl_get_matrix_columns(const struct glsl_type *type);
 
 unsigned glsl_get_length(const struct glsl_type *type);
 
-const struct glsl_type *glsl_get_struct_elem_type(const struct glsl_type *type,
-                                                  unsigned index);
-
 const char *glsl_get_struct_elem_name(const struct glsl_type *type,
                                       unsigned index);
 
index d4a8cd588c7641377af94f0d8af015b268aaa60b..f6a55ccabd5204a1b6bc4d5b8a1b4180a262d8f2 100644 (file)
@@ -275,7 +275,7 @@ validate_deref_chain(nir_deref *deref, validate_state *state)
       case nir_deref_type_struct:
          assert(deref->type ==
                 glsl_get_struct_field(parent->type,
-                                      nir_deref_as_struct(deref)->elem));
+                                      nir_deref_as_struct(deref)->index));
          break;
 
       case nir_deref_type_var: