summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2018-12-12 14:32:19 -0600
committerJason Ekstrand <[email protected]>2019-01-08 00:38:29 +0000
commit6cebeb4f71918aded1ddade5727f79fae83780fd (patch)
tree9de5dba8aa2944b15f516d541abe8ad7f62c54c1 /src/compiler/nir
parent7f70b3e55514f1744e9aab6d2145e855603bd1dc (diff)
glsl_type: Add support for explicitly laid out matrices and arrays
SPIR-V allows for matrix and array types to be decorated with explicit byte stride decorations and matrix types to be decorated row- or column-major. This commit adds support to glsl_type to encode this information. Because this doesn't work nicely with std430 and std140 alignments, we add asserts to ensure that we don't use any of the std430 or std140 layout functions with explicitly laid out types. In SPIR-V, the layout information for matrices is applied to the parent struct member instead of to the matrix type itself. However, this is gets rather clumsy when you're walking derefs trying to compute offsets because, the moment you hit a matrix, you have to crawl back the deref chain and find the struct. Instead, we take the same path here as we've taken in spirv_to_nir and put the decorations on the matrix type itself. This also subtly adds support for strided vector types. These don't come up in SPIR-V directly but you can get one as the result of taking a column from a row-major matrix or a row from a column-major matrix. Reviewed-by: Alejandro PiƱeiro <[email protected]>
Diffstat (limited to 'src/compiler/nir')
-rw-r--r--src/compiler/nir/nir_lower_atomics_to_ssbo.c2
-rw-r--r--src/compiler/nir/nir_lower_clip_cull_distance_arrays.c4
-rw-r--r--src/compiler/nir/nir_lower_io_arrays_to_elements.c9
-rw-r--r--src/compiler/nir/nir_split_per_member_structs.c3
-rw-r--r--src/compiler/nir/nir_split_vars.c9
5 files changed, 15 insertions, 12 deletions
diff --git a/src/compiler/nir/nir_lower_atomics_to_ssbo.c b/src/compiler/nir/nir_lower_atomics_to_ssbo.c
index d9acc5c3a79..ffa03dc27f8 100644
--- a/src/compiler/nir/nir_lower_atomics_to_ssbo.c
+++ b/src/compiler/nir/nir_lower_atomics_to_ssbo.c
@@ -219,7 +219,7 @@ nir_lower_atomics_to_ssbo(nir_shader *shader, unsigned ssbo_offset)
char name[16];
/* A length of 0 is used to denote unsized arrays */
- const struct glsl_type *type = glsl_array_type(glsl_uint_type(), 0);
+ const struct glsl_type *type = glsl_array_type(glsl_uint_type(), 0, 0);
snprintf(name, sizeof(name), "counter%d", var->data.binding);
diff --git a/src/compiler/nir/nir_lower_clip_cull_distance_arrays.c b/src/compiler/nir/nir_lower_clip_cull_distance_arrays.c
index 2afbf9285c0..6e1557ef40d 100644
--- a/src/compiler/nir/nir_lower_clip_cull_distance_arrays.c
+++ b/src/compiler/nir/nir_lower_clip_cull_distance_arrays.c
@@ -62,10 +62,10 @@ get_unwrapped_array_length(nir_shader *nir, nir_variable *var)
static void
update_type(nir_variable *var, gl_shader_stage stage, unsigned length)
{
- const struct glsl_type *type = glsl_array_type(glsl_float_type(), length);
+ const struct glsl_type *type = glsl_array_type(glsl_float_type(), length, 0);
if (nir_is_per_vertex_io(var, stage))
- type = glsl_array_type(type, glsl_get_length(var->type));
+ type = glsl_array_type(type, glsl_get_length(var->type), 0);
var->type = type;
}
diff --git a/src/compiler/nir/nir_lower_io_arrays_to_elements.c b/src/compiler/nir/nir_lower_io_arrays_to_elements.c
index 30d53f156ff..34020249199 100644
--- a/src/compiler/nir/nir_lower_io_arrays_to_elements.c
+++ b/src/compiler/nir/nir_lower_io_arrays_to_elements.c
@@ -127,13 +127,12 @@ lower_array(nir_builder *b, nir_intrinsic_instr *intr, nir_variable *var,
const struct glsl_type *type = glsl_without_array(element->type);
/* This pass also splits matrices so we need give them a new type. */
- if (glsl_type_is_matrix(type)) {
- type = glsl_vector_type(glsl_get_base_type(type),
- glsl_get_vector_elements(type));
- }
+ if (glsl_type_is_matrix(type))
+ type = glsl_get_column_type(type);
if (nir_is_per_vertex_io(var, b->shader->info.stage)) {
- type = glsl_array_type(type, glsl_get_length(element->type));
+ type = glsl_array_type(type, glsl_get_length(element->type),
+ glsl_get_explicit_stride(element->type));
}
element->type = type;
diff --git a/src/compiler/nir/nir_split_per_member_structs.c b/src/compiler/nir/nir_split_per_member_structs.c
index f649c8f474b..c1234c2e92a 100644
--- a/src/compiler/nir/nir_split_per_member_structs.c
+++ b/src/compiler/nir/nir_split_per_member_structs.c
@@ -50,7 +50,8 @@ member_type(const struct glsl_type *type, unsigned index)
if (glsl_type_is_array(type)) {
const struct glsl_type *elem =
member_type(glsl_get_array_element(type), index);
- return glsl_array_type(elem, glsl_get_length(type));
+ assert(glsl_get_explicit_stride(type) == 0);
+ return glsl_array_type(elem, glsl_get_length(type), 0);
} else {
assert(glsl_type_is_struct(type));
assert(index < glsl_get_length(type));
diff --git a/src/compiler/nir/nir_split_vars.c b/src/compiler/nir/nir_split_vars.c
index bf9205c5150..e738ee3f385 100644
--- a/src/compiler/nir/nir_split_vars.c
+++ b/src/compiler/nir/nir_split_vars.c
@@ -58,7 +58,8 @@ wrap_type_in_array(const struct glsl_type *type,
const struct glsl_type *elem_type =
wrap_type_in_array(type, glsl_get_array_element(array_type));
- return glsl_array_type(elem_type, glsl_get_length(array_type));
+ assert(glsl_get_explicit_stride(array_type) == 0);
+ return glsl_array_type(elem_type, glsl_get_length(array_type), 0);
}
static int
@@ -341,6 +342,7 @@ init_var_list_array_infos(struct exec_list *vars,
const struct glsl_type *type = var->type;
for (int i = 0; i < num_levels; i++) {
+ assert(glsl_get_explicit_stride(type) == 0);
info->levels[i].array_len = glsl_get_length(type);
type = glsl_get_array_element(type);
@@ -506,7 +508,7 @@ split_var_list_arrays(nir_shader *shader,
glsl_get_components(split_type),
info->levels[i].array_len);
} else {
- split_type = glsl_array_type(split_type, info->levels[i].array_len);
+ split_type = glsl_array_type(split_type, info->levels[i].array_len, 0);
}
}
@@ -918,6 +920,7 @@ get_vec_var_usage(nir_variable *var,
const struct glsl_type *type = var->type;
for (unsigned i = 0; i < num_levels; i++) {
usage->levels[i].array_len = glsl_get_length(type);
+ assert(glsl_get_explicit_stride(type) == 0);
type = glsl_get_array_element(type);
}
assert(glsl_type_is_vector_or_scalar(type));
@@ -1290,7 +1293,7 @@ shrink_vec_var_list(struct exec_list *vars,
new_num_comps,
usage->levels[i].array_len);
} else {
- new_type = glsl_array_type(new_type, usage->levels[i].array_len);
+ new_type = glsl_array_type(new_type, usage->levels[i].array_len, 0);
}
}
var->type = new_type;