Mesa (master): nir: Add a size_align helper function for aligning elements to 16 bytes.
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Mon Nov 16 22:33:02 UTC 2020
Module: Mesa
Branch: master
Commit: 51f2b11b043da05e12f26d8466e68e55f0d17c3b
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=51f2b11b043da05e12f26d8466e68e55f0d17c3b
Author: Eric Anholt <eric at anholt.net>
Date: Tue Aug 4 16:09:25 2020 -0700
nir: Add a size_align helper function for aligning elements to 16 bytes.
This is useful for freedreno's intrinsic opt_large_constant lowering,
where we want arrays and struct elements aligned to 16 to avoid generating
lots of extra instructions to extract from the right component.
Reviewed-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5810>
---
src/compiler/nir_types.cpp | 100 +++++++++++++++++++++++++++++++++++++--------
src/compiler/nir_types.h | 2 +
2 files changed, 84 insertions(+), 18 deletions(-)
diff --git a/src/compiler/nir_types.cpp b/src/compiler/nir_types.cpp
index 54814ccdd8e..448e962b399 100644
--- a/src/compiler/nir_types.cpp
+++ b/src/compiler/nir_types.cpp
@@ -701,6 +701,31 @@ glsl_uint16_type(const struct glsl_type *type)
return type->get_uint16_type();
}
+static void
+glsl_size_align_handle_array_and_structs(const struct glsl_type *type,
+ glsl_type_size_align_func size_align,
+ unsigned *size, unsigned *align)
+{
+ if (type->base_type == GLSL_TYPE_ARRAY) {
+ unsigned elem_size = 0, elem_align = 0;
+ size_align(type->fields.array, &elem_size, &elem_align);
+ *align = elem_align;
+ *size = type->length * ALIGN_POT(elem_size, elem_align);
+ } else {
+ assert(type->base_type == GLSL_TYPE_STRUCT ||
+ type->base_type == GLSL_TYPE_INTERFACE);
+
+ *size = 0;
+ *align = 0;
+ for (unsigned i = 0; i < type->length; i++) {
+ unsigned elem_size = 0, elem_align = 0;
+ size_align(type->fields.structure[i].type, &elem_size, &elem_align);
+ *align = MAX2(*align, elem_align);
+ *size = ALIGN_POT(*size, elem_align) + elem_size;
+ }
+ }
+}
+
void
glsl_get_natural_size_align_bytes(const struct glsl_type *type,
unsigned *size, unsigned *align)
@@ -731,26 +756,12 @@ glsl_get_natural_size_align_bytes(const struct glsl_type *type,
break;
}
- case GLSL_TYPE_ARRAY: {
- unsigned elem_size = 0, elem_align = 0;
- glsl_get_natural_size_align_bytes(type->fields.array,
- &elem_size, &elem_align);
- *align = elem_align;
- *size = type->length * ALIGN_POT(elem_size, elem_align);
- break;
- }
-
+ case GLSL_TYPE_ARRAY:
case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_STRUCT:
- *size = 0;
- *align = 0;
- for (unsigned i = 0; i < type->length; i++) {
- unsigned elem_size = 0, elem_align = 0;
- glsl_get_natural_size_align_bytes(type->fields.structure[i].type,
- &elem_size, &elem_align);
- *align = MAX2(*align, elem_align);
- *size = ALIGN_POT(*size, elem_align) + elem_size;
- }
+ glsl_size_align_handle_array_and_structs(type,
+ glsl_get_natural_size_align_bytes,
+ size, align);
break;
case GLSL_TYPE_SAMPLER:
@@ -769,6 +780,59 @@ glsl_get_natural_size_align_bytes(const struct glsl_type *type,
}
}
+/**
+ * Returns a byte size/alignment for a type where each array element or struct
+ * field is aligned to 16 bytes.
+ */
+void
+glsl_get_vec4_size_align_bytes(const struct glsl_type *type,
+ unsigned *size, unsigned *align)
+{
+ switch (type->base_type) {
+ case GLSL_TYPE_BOOL:
+ /* We special-case Booleans to 32 bits to not cause heartburn for
+ * drivers that suddenly get an 8-bit load.
+ */
+ *size = 4 * type->components();
+ *align = 16;
+ break;
+
+ case GLSL_TYPE_UINT8:
+ case GLSL_TYPE_INT8:
+ case GLSL_TYPE_UINT16:
+ case GLSL_TYPE_INT16:
+ case GLSL_TYPE_FLOAT16:
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_DOUBLE:
+ case GLSL_TYPE_UINT64:
+ case GLSL_TYPE_INT64: {
+ unsigned N = glsl_get_bit_size(type) / 8;
+ *size = 16 * (type->matrix_columns - 1) + N * type->vector_elements;
+ *align = 16;
+ break;
+ }
+
+ case GLSL_TYPE_ARRAY:
+ case GLSL_TYPE_INTERFACE:
+ case GLSL_TYPE_STRUCT:
+ glsl_size_align_handle_array_and_structs(type,
+ glsl_get_vec4_size_align_bytes,
+ size, align);
+ break;
+
+ case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_IMAGE:
+ case GLSL_TYPE_ATOMIC_UINT:
+ case GLSL_TYPE_SUBROUTINE:
+ case GLSL_TYPE_VOID:
+ case GLSL_TYPE_ERROR:
+ case GLSL_TYPE_FUNCTION:
+ unreachable("type does not make sense for glsl_get_vec4_size_align_bytes()");
+ }
+}
+
const glsl_type *
glsl_atomic_uint_type(void)
{
diff --git a/src/compiler/nir_types.h b/src/compiler/nir_types.h
index b4bd9bcc7c9..82c268b98bc 100644
--- a/src/compiler/nir_types.h
+++ b/src/compiler/nir_types.h
@@ -228,6 +228,8 @@ const struct glsl_type *glsl_uint16_type(const struct glsl_type *type);
void glsl_get_natural_size_align_bytes(const struct glsl_type *type,
unsigned *size, unsigned *align);
+void glsl_get_vec4_size_align_bytes(const struct glsl_type *type,
+ unsigned *size, unsigned *align);
const struct glsl_type *glsl_atomic_uint_type(void);
More information about the mesa-commit
mailing list