diff options
author | Jason Ekstrand <[email protected]> | 2018-06-29 14:14:52 -0700 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2018-07-02 12:09:39 -0700 |
commit | 2bf8be99b0f3dedd8fb23eeba998f6e1c540edf7 (patch) | |
tree | 7f5cad6f18d88b73d2d7ebd2b7b745859799dba4 | |
parent | 893fc2d07d382c0b9563c0b48215a0e260f17d4b (diff) |
nir/types: Add a natural size and alignment helper
The size and alignment are "natural" in the sense that everything is
aligned to a scalar. This is a bit tighter than std430 where vec3s are
required to be aligned to a vec4.
Reviewed-by: Timothy Arceri <[email protected]>
Reviewed-by: Iago Toral Quiroga <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r-- | src/compiler/nir_types.cpp | 56 | ||||
-rw-r--r-- | src/compiler/nir_types.h | 6 |
2 files changed, 62 insertions, 0 deletions
diff --git a/src/compiler/nir_types.cpp b/src/compiler/nir_types.cpp index d2b2a93b207..2b932b1967e 100644 --- a/src/compiler/nir_types.cpp +++ b/src/compiler/nir_types.cpp @@ -477,3 +477,59 @@ glsl_channel_type(const glsl_type *t) unreachable("Unhandled base type glsl_channel_type()"); } } + +void +glsl_get_natural_size_align_bytes(const struct glsl_type *type, + unsigned *size, unsigned *align) +{ + switch (type->base_type) { + 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_BOOL: + case GLSL_TYPE_DOUBLE: + case GLSL_TYPE_UINT64: + case GLSL_TYPE_INT64: { + unsigned N = glsl_get_bit_size(type) / 8; + *size = N * type->components(); + *align = N; + break; + } + + case GLSL_TYPE_ARRAY: { + unsigned elem_size, elem_align; + 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_STRUCT: + *size = 0; + *align = 0; + for (unsigned i = 0; i < type->length; i++) { + unsigned elem_size, elem_align; + 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; + } + break; + + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_ATOMIC_UINT: + case GLSL_TYPE_SUBROUTINE: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_VOID: + case GLSL_TYPE_ERROR: + case GLSL_TYPE_INTERFACE: + case GLSL_TYPE_FUNCTION: + unreachable("type does not have a natural size"); + } +} diff --git a/src/compiler/nir_types.h b/src/compiler/nir_types.h index 1107cfd73f2..67c4d7b5097 100644 --- a/src/compiler/nir_types.h +++ b/src/compiler/nir_types.h @@ -184,6 +184,12 @@ const struct glsl_type *glsl_transposed_type(const struct glsl_type *type); const struct glsl_type *glsl_channel_type(const struct glsl_type *type); +typedef void (*glsl_type_size_align_func)(const struct glsl_type *type, + unsigned *size, unsigned *align); + +void glsl_get_natural_size_align_bytes(const struct glsl_type *type, + unsigned *size, unsigned *align); + #ifdef __cplusplus } #endif |