mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 17:30:12 +01:00
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@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5810>
This commit is contained in:
parent
433841d9eb
commit
51f2b11b04
2 changed files with 84 additions and 18 deletions
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue