From 829aa98320fcd529407d16991b476b71af017479 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Tue, 25 Nov 2014 21:36:25 -0800 Subject: [PATCH] nir: Use an integer index for specifying structure fields 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 --- src/glsl/nir/glsl_to_nir.cpp | 5 +- src/glsl/nir/nir.c | 6 +-- src/glsl/nir/nir.h | 4 +- src/glsl/nir/nir_lower_samplers.cpp | 65 ++++++++++++----------- src/glsl/nir/nir_lower_variables_scalar.c | 20 +++---- src/glsl/nir/nir_print.c | 35 +++++++----- src/glsl/nir/nir_types.cpp | 16 +----- src/glsl/nir/nir_types.h | 5 +- src/glsl/nir/nir_validate.c | 2 +- 9 files changed, 75 insertions(+), 83 deletions(-) diff --git a/src/glsl/nir/glsl_to_nir.cpp b/src/glsl/nir/glsl_to_nir.cpp index 6b90da5481c..19bc664961c 100644 --- a/src/glsl/nir/glsl_to_nir.cpp +++ b/src/glsl/nir/glsl_to_nir.cpp @@ -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; diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c index 0514158bbde..3f04de2fee6 100644 --- a/src/glsl/nir/nir.c +++ b/src/glsl/nir/nir.c @@ -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); diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h index a9a77f395f3..e977159584f 100644 --- a/src/glsl/nir/nir.h +++ b/src/glsl/nir/nir.h @@ -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); diff --git a/src/glsl/nir/nir_lower_samplers.cpp b/src/glsl/nir/nir_lower_samplers.cpp index be6a75525b7..4fa764ca378 100644 --- a/src/glsl/nir/nir_lower_samplers.cpp +++ b/src/glsl/nir/nir_lower_samplers.cpp @@ -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; diff --git a/src/glsl/nir/nir_lower_variables_scalar.c b/src/glsl/nir/nir_lower_variables_scalar.c index 3127dbb19b4..3d79b5febf2 100644 --- a/src/glsl/nir/nir_lower_variables_scalar.c +++ b/src/glsl/nir/nir_lower_variables_scalar.c @@ -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)); diff --git a/src/glsl/nir/nir_print.c b/src/glsl/nir/nir_print.c index ec60981b548..9ad2849d376 100644 --- a/src/glsl/nir/nir_print.c +++ b/src/glsl/nir/nir_print.c @@ -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); } } diff --git a/src/glsl/nir/nir_types.cpp b/src/glsl/nir/nir_types.cpp index 7f1992b77ff..fe0001592d1 100644 --- a/src/glsl/nir/nir_types.cpp +++ b/src/glsl/nir/nir_types.cpp @@ -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) { diff --git a/src/glsl/nir/nir_types.h b/src/glsl/nir/nir_types.h index 5b6d068a8cb..6f91e2dce8d 100644 --- a/src/glsl/nir/nir_types.h +++ b/src/glsl/nir/nir_types.h @@ -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); diff --git a/src/glsl/nir/nir_validate.c b/src/glsl/nir/nir_validate.c index d4a8cd588c7..f6a55ccabd5 100644 --- a/src/glsl/nir/nir_validate.c +++ b/src/glsl/nir/nir_validate.c @@ -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: -- 2.30.2