{
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;
}
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;
}
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);
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)
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);
*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;
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:
} 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));
}
}
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,
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));
}
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;
}
}
if (!first)
fprintf(fp, ", ");
- print_deref(&instr->variables[i]->deref, state, fp);
+ print_deref(instr->variables[i], state, fp);
first = false;
}
}
if (instr->sampler) {
- print_deref(&instr->sampler->deref, state, fp);
+ print_deref(instr->sampler, state, fp);
} else {
fprintf(fp, "%u", instr->sampler_index);
}
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);
}
}
}
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 *
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)
{
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);
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);
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: