summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Ekstrand <jason.ekstrand@intel.com>2015-04-10 16:16:02 -0700
committerJason Ekstrand <jason.ekstrand@intel.com>2015-04-22 18:10:40 -0700
commit8b900e74058dd48368511780a488ccb7a645c64f (patch)
tree44bb04335642a61cecf0824cd6e410474fa68a22
parent7e1d21edbff772f6dfc727e0e09788d87e00e0f5 (diff)
nir/types: Make glsl_get_length smarter
Previously, this function returned the number of elements for structures and arrays and 0 for everything else. In NIR, this is almost never what you want because we also treat matricies as arrays so you have to special-case constantly. This commit glsl_get_length treat matrices as an array of columns by returning the number of columns instead of 0 This also fixes a bug in locals_to_regs caused by not checking for the matrix case in one place. v2: Only special-case for matrices and return a length of 0 for vectors as we did before. This was needed to not break the TGSI-based drivers and doesn't really affect NIR at the moment. Reviewed-by: Connor Abbott <cwabbott0@gmail.com> Tested-by: Rob Clark <robclark@freedesktop.org>
-rw-r--r--src/glsl/nir/nir_lower_locals_to_regs.c11
-rw-r--r--src/glsl/nir/nir_lower_var_copies.c24
-rw-r--r--src/glsl/nir/nir_lower_vars_to_ssa.c26
-rw-r--r--src/glsl/nir/nir_types.cpp2
4 files changed, 8 insertions, 55 deletions
diff --git a/src/glsl/nir/nir_lower_locals_to_regs.c b/src/glsl/nir/nir_lower_locals_to_regs.c
index 8c5df7be67..8c1977ad4c 100644
--- a/src/glsl/nir/nir_lower_locals_to_regs.c
+++ b/src/glsl/nir/nir_lower_locals_to_regs.c
@@ -100,15 +100,8 @@ get_reg_for_deref(nir_deref_var *deref, struct locals_to_regs_state *state)
unsigned array_size = 1;
nir_deref *tail = &deref->deref;
while (tail->child) {
- if (tail->child->deref_type == nir_deref_type_array) {
- /* Multiply by the parent's type. */
- if (glsl_type_is_matrix(tail->type)) {
- array_size *= glsl_get_matrix_columns(tail->type);
- } else {
- assert(glsl_get_length(tail->type) > 0);
- array_size *= glsl_get_length(tail->type);
- }
- }
+ if (tail->child->deref_type == nir_deref_type_array)
+ array_size *= glsl_get_length(tail->type);
tail = tail->child;
}
diff --git a/src/glsl/nir/nir_lower_var_copies.c b/src/glsl/nir/nir_lower_var_copies.c
index 58389a7c76..21672901f0 100644
--- a/src/glsl/nir/nir_lower_var_copies.c
+++ b/src/glsl/nir/nir_lower_var_copies.c
@@ -64,26 +64,6 @@ get_deref_tail(nir_deref *deref)
return deref;
}
-static int
-type_get_length(const struct glsl_type *type)
-{
- switch (glsl_get_base_type(type)) {
- case GLSL_TYPE_STRUCT:
- case GLSL_TYPE_ARRAY:
- return glsl_get_length(type);
- case GLSL_TYPE_FLOAT:
- case GLSL_TYPE_INT:
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_BOOL:
- if (glsl_type_is_matrix(type))
- return glsl_get_matrix_columns(type);
- else
- return glsl_get_vector_elements(type);
- default:
- unreachable("Invalid deref base type");
- }
-}
-
/* This function recursively walks the given deref chain and replaces the
* given copy instruction with an equivalent sequence load/store
* operations.
@@ -121,9 +101,9 @@ emit_copy_load_store(nir_intrinsic_instr *copy_instr,
nir_deref_array *src_arr = nir_deref_as_array(src_arr_parent->child);
nir_deref_array *dest_arr = nir_deref_as_array(dest_arr_parent->child);
- unsigned length = type_get_length(src_arr_parent->type);
+ unsigned length = glsl_get_length(src_arr_parent->type);
/* The wildcards should represent the same number of elements */
- assert(length == type_get_length(dest_arr_parent->type));
+ assert(length == glsl_get_length(dest_arr_parent->type));
assert(length > 0);
/* Walk over all of the elements that this wildcard refers to and
diff --git a/src/glsl/nir/nir_lower_vars_to_ssa.c b/src/glsl/nir/nir_lower_vars_to_ssa.c
index 00b4fb6e52..bb60f46012 100644
--- a/src/glsl/nir/nir_lower_vars_to_ssa.c
+++ b/src/glsl/nir/nir_lower_vars_to_ssa.c
@@ -90,32 +90,12 @@ struct lower_variables_state {
struct hash_table *phi_table;
};
-static int
-type_get_length(const struct glsl_type *type)
-{
- switch (glsl_get_base_type(type)) {
- case GLSL_TYPE_STRUCT:
- case GLSL_TYPE_ARRAY:
- return glsl_get_length(type);
- case GLSL_TYPE_FLOAT:
- case GLSL_TYPE_INT:
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_BOOL:
- if (glsl_type_is_matrix(type))
- return glsl_get_matrix_columns(type);
- else
- return glsl_get_vector_elements(type);
- default:
- unreachable("Invalid deref base type");
- }
-}
-
static struct deref_node *
deref_node_create(struct deref_node *parent,
const struct glsl_type *type, nir_shader *shader)
{
size_t size = sizeof(struct deref_node) +
- type_get_length(type) * sizeof(struct deref_node *);
+ glsl_get_length(type) * sizeof(struct deref_node *);
struct deref_node *node = rzalloc_size(shader, size);
node->type = type;
@@ -165,7 +145,7 @@ get_deref_node(nir_deref_var *deref, struct lower_variables_state *state)
case nir_deref_type_struct: {
nir_deref_struct *deref_struct = nir_deref_as_struct(tail);
- assert(deref_struct->index < type_get_length(node->type));
+ assert(deref_struct->index < glsl_get_length(node->type));
if (node->children[deref_struct->index] == NULL)
node->children[deref_struct->index] =
@@ -184,7 +164,7 @@ get_deref_node(nir_deref_var *deref, struct lower_variables_state *state)
* out-of-bounds offset. We need to handle this at least
* somewhat gracefully.
*/
- if (arr->base_offset >= type_get_length(node->type))
+ if (arr->base_offset >= glsl_get_length(node->type))
return NULL;
if (node->children[arr->base_offset] == NULL)
diff --git a/src/glsl/nir/nir_types.cpp b/src/glsl/nir/nir_types.cpp
index f0d0b46d25..62176f508a 100644
--- a/src/glsl/nir/nir_types.cpp
+++ b/src/glsl/nir/nir_types.cpp
@@ -103,7 +103,7 @@ glsl_get_matrix_columns(const struct glsl_type *type)
unsigned
glsl_get_length(const struct glsl_type *type)
{
- return type->length;
+ return type->is_matrix() ? type->matrix_columns : type->length;
}
const char *