glsl_type::glsl_type(GLenum gl_type,
glsl_base_type base_type, unsigned vector_elements,
unsigned matrix_columns, const char *name,
- unsigned explicit_stride, bool row_major) :
+ unsigned explicit_stride, bool row_major,
+ unsigned explicit_alignment) :
gl_type(gl_type),
base_type(base_type), sampled_type(GLSL_TYPE_VOID),
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
interface_packing(0), interface_row_major(row_major), packed(0),
vector_elements(vector_elements), matrix_columns(matrix_columns),
- length(0), explicit_stride(explicit_stride)
+ length(0), explicit_stride(explicit_stride),
+ explicit_alignment(explicit_alignment)
{
/* Values of these types must fit in the two bits of
* glsl_type::sampled_type.
/* Neither dimension is zero or both dimensions are zero.
*/
assert((vector_elements == 0) == (matrix_columns == 0));
+ assert(util_is_power_of_two_or_zero(explicit_alignment));
memset(& fields, 0, sizeof(fields));
}
sampler_dimensionality(dim), sampler_shadow(shadow),
sampler_array(array), interface_packing(0),
interface_row_major(0), packed(0),
- length(0), explicit_stride(0)
+ length(0), explicit_stride(0), explicit_alignment(0)
{
this->mem_ctx = ralloc_context(NULL);
assert(this->mem_ctx != NULL);
}
glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
- const char *name, bool packed) :
+ const char *name, bool packed,
+ unsigned explicit_alignment) :
gl_type(0),
base_type(GLSL_TYPE_STRUCT), sampled_type(GLSL_TYPE_VOID),
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
interface_packing(0), interface_row_major(0), packed(packed),
vector_elements(0), matrix_columns(0),
- length(num_fields), explicit_stride(0)
+ length(num_fields), explicit_stride(0),
+ explicit_alignment(explicit_alignment)
{
unsigned int i;
+ assert(util_is_power_of_two_or_zero(explicit_alignment));
+
this->mem_ctx = ralloc_context(NULL);
assert(this->mem_ctx != NULL);
interface_packing((unsigned) packing),
interface_row_major((unsigned) row_major), packed(0),
vector_elements(0), matrix_columns(0),
- length(num_fields), explicit_stride(0)
+ length(num_fields), explicit_stride(0), explicit_alignment(0)
{
unsigned int i;
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
interface_packing(0), interface_row_major(0), packed(0),
vector_elements(0), matrix_columns(0),
- length(num_params), explicit_stride(0)
+ length(num_params), explicit_stride(0), explicit_alignment(0)
{
unsigned int i;
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
interface_packing(0), interface_row_major(0), packed(0),
vector_elements(1), matrix_columns(1),
- length(0), explicit_stride(0)
+ length(0), explicit_stride(0), explicit_alignment(0)
{
this->mem_ctx = ralloc_context(NULL);
assert(this->mem_ctx != NULL);
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
interface_packing(0), interface_row_major(0), packed(0),
vector_elements(0), matrix_columns(0),
- length(length), name(NULL), explicit_stride(explicit_stride)
+ length(length), name(NULL), explicit_stride(explicit_stride),
+ explicit_alignment(array->explicit_alignment)
{
this->fields.array = array;
/* Inherit the gl type of the base. The GL type is used for
const glsl_type *
glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns,
- unsigned explicit_stride, bool row_major)
+ unsigned explicit_stride, bool row_major,
+ unsigned explicit_alignment)
{
if (base_type == GLSL_TYPE_VOID) {
- assert(explicit_stride == 0 && !row_major);
+ assert(explicit_stride == 0 && explicit_alignment == 0 && !row_major);
return void_type;
}
- /* Matrix and vector types with explicit strides have to be looked up in a
- * table so they're handled separately.
+ /* Matrix and vector types with explicit strides or alignment have to be
+ * looked up in a table so they're handled separately.
*/
- if (explicit_stride > 0) {
+ if (explicit_stride > 0 || explicit_alignment > 0) {
+ if (explicit_alignment > 0) {
+ assert(util_is_power_of_two_nonzero(explicit_alignment));
+ assert(explicit_stride % explicit_alignment == 0);
+ }
+
const glsl_type *bare_type = get_instance(base_type, rows, columns);
- assert(columns > 1 || !row_major);
+ assert(columns > 1 || (rows > 1 && !row_major));
char name[128];
- snprintf(name, sizeof(name), "%sx%uB%s", bare_type->name,
- explicit_stride, row_major ? "RM" : "");
+ snprintf(name, sizeof(name), "%sx%ua%uB%s", bare_type->name,
+ explicit_stride, explicit_alignment, row_major ? "RM" : "");
mtx_lock(&glsl_type::hash_mutex);
assert(glsl_type_users > 0);
const glsl_type *t = new glsl_type(bare_type->gl_type,
(glsl_base_type)base_type,
rows, columns, name,
- explicit_stride, row_major);
+ explicit_stride, row_major,
+ explicit_alignment);
entry = _mesa_hash_table_insert(explicit_matrix_types,
t->name, (void *)t);
assert(((glsl_type *) entry->data)->vector_elements == rows);
assert(((glsl_type *) entry->data)->matrix_columns == columns);
assert(((glsl_type *) entry->data)->explicit_stride == explicit_stride);
+ assert(((glsl_type *) entry->data)->explicit_alignment == explicit_alignment);
const glsl_type *t = (const glsl_type *) entry->data;
if (this->interface_row_major != b->interface_row_major)
return false;
+ if (this->explicit_alignment != b->explicit_alignment)
+ return false;
+
/* From the GLSL 4.20 specification (Sec 4.2):
*
* "Structures must have the same name, sequence of type names, and
glsl_type::get_struct_instance(const glsl_struct_field *fields,
unsigned num_fields,
const char *name,
- bool packed)
+ bool packed, unsigned explicit_alignment)
{
- const glsl_type key(fields, num_fields, name, packed);
+ const glsl_type key(fields, num_fields, name, packed, explicit_alignment);
mtx_lock(&glsl_type::hash_mutex);
assert(glsl_type_users > 0);
const struct hash_entry *entry = _mesa_hash_table_search(struct_types,
&key);
if (entry == NULL) {
- const glsl_type *t = new glsl_type(fields, num_fields, name, packed);
+ const glsl_type *t = new glsl_type(fields, num_fields, name, packed,
+ explicit_alignment);
entry = _mesa_hash_table_insert(struct_types, t, (void *) t);
}
assert(((glsl_type *) entry->data)->length == num_fields);
assert(strcmp(((glsl_type *) entry->data)->name, name) == 0);
assert(((glsl_type *) entry->data)->packed == packed);
+ assert(((glsl_type *) entry->data)->explicit_alignment == explicit_alignment);
glsl_type *t = (glsl_type *) entry->data;
glsl_type::get_explicit_type_for_size_align(glsl_type_size_align_func type_info,
unsigned *size, unsigned *alignment) const
{
- if (this->is_scalar() || this->is_vector()) {
+ if (this->is_scalar()) {
type_info(this, size, alignment);
+ assert(*size == explicit_type_scalar_byte_size(this));
+ assert(*alignment == explicit_type_scalar_byte_size(this));
return this;
+ } else if (this->is_vector()) {
+ type_info(this, size, alignment);
+ assert(*alignment % explicit_type_scalar_byte_size(this) == 0);
+ return glsl_type::get_instance(this->base_type, this->vector_elements,
+ 1, 0, false, *alignment);
} else if (this->is_array()) {
unsigned elem_size, elem_align;
const struct glsl_type *explicit_element =
const glsl_type *type;
if (this->is_struct()) {
type = get_struct_instance(fields, this->length, this->name,
- this->packed);
+ this->packed, *alignment);
} else {
assert(!this->packed);
type = get_interface_instance(fields, this->length,
unsigned stride = align(col_size, col_align);
*size = this->matrix_columns * stride;
+ /* Matrix and column alignments match. See glsl_type::column_type() */
*alignment = col_align;
return glsl_type::get_instance(this->base_type, this->vector_elements,
- this->matrix_columns, stride, false);
+ this->matrix_columns, stride, false, *alignment);
} else {
unreachable("Unhandled type.");
}
unsigned interface_row_major:1;
unsigned vector_elements:3;
unsigned matrix_columns:3;
- unsigned explicit_stride:20;
+ unsigned explicit_stride:16;
+ unsigned explicit_alignment:4;
} basic;
struct {
unsigned base_type:5;
unsigned base_type:5;
unsigned interface_packing_or_packed:2;
unsigned interface_row_major:1;
- unsigned length:24;
+ unsigned length:20;
+ unsigned explicit_alignment:4;
} strct;
};
else if (type->vector_elements == 16)
encoded.basic.vector_elements = 6;
encoded.basic.matrix_columns = type->matrix_columns;
- encoded.basic.explicit_stride = MIN2(type->explicit_stride, 0xfffff);
+ encoded.basic.explicit_stride = MIN2(type->explicit_stride, 0xffff);
+ encoded.basic.explicit_alignment =
+ MIN2(ffs(type->explicit_alignment), 0xf);
blob_write_uint32(blob, encoded.u32);
/* If we don't have enough bits for explicit_stride, store it
* separately.
*/
- if (encoded.basic.explicit_stride == 0xfffff)
+ if (encoded.basic.explicit_stride == 0xffff)
blob_write_uint32(blob, type->explicit_stride);
+ if (encoded.basic.explicit_alignment == 0xf)
+ blob_write_uint32(blob, type->explicit_alignment);
return;
case GLSL_TYPE_SAMPLER:
encoded.sampler.dimensionality = type->sampler_dimensionality;
return;
case GLSL_TYPE_STRUCT:
case GLSL_TYPE_INTERFACE:
- encoded.strct.length = MIN2(type->length, 0xffffff);
+ encoded.strct.length = MIN2(type->length, 0xfffff);
+ encoded.strct.explicit_alignment =
+ MIN2(ffs(type->explicit_alignment), 0xf);
if (type->is_interface()) {
encoded.strct.interface_packing_or_packed = type->interface_packing;
encoded.strct.interface_row_major = type->interface_row_major;
blob_write_string(blob, type->name);
/* If we don't have enough bits for length, store it separately. */
- if (encoded.strct.length == 0xffffff)
+ if (encoded.strct.length == 0xfffff)
blob_write_uint32(blob, type->length);
+ if (encoded.strct.length == 0xf)
+ blob_write_uint32(blob, type->explicit_alignment);
for (unsigned i = 0; i < type->length; i++)
encode_glsl_struct_field(blob, &type->fields.structure[i]);
case GLSL_TYPE_INT64:
case GLSL_TYPE_BOOL: {
unsigned explicit_stride = encoded.basic.explicit_stride;
- if (explicit_stride == 0xfffff)
+ if (explicit_stride == 0xffff)
explicit_stride = blob_read_uint32(blob);
+ unsigned explicit_alignment = encoded.basic.explicit_alignment;
+ if (explicit_alignment == 0xf)
+ explicit_alignment = blob_read_uint32(blob);
+ else if (explicit_alignment > 0)
+ explicit_alignment = 1 << (explicit_alignment - 1);
uint32_t vector_elements = encoded.basic.vector_elements;
if (vector_elements == 5)
vector_elements = 8;
return glsl_type::get_instance(base_type, encoded.basic.vector_elements,
encoded.basic.matrix_columns,
explicit_stride,
- encoded.basic.interface_row_major);
+ encoded.basic.interface_row_major,
+ explicit_alignment);
}
case GLSL_TYPE_SAMPLER:
return glsl_type::get_sampler_instance((enum glsl_sampler_dim)encoded.sampler.dimensionality,
case GLSL_TYPE_INTERFACE: {
char *name = blob_read_string(blob);
unsigned num_fields = encoded.strct.length;
- if (num_fields == 0xffffff)
+ if (num_fields == 0xfffff)
num_fields = blob_read_uint32(blob);
+ unsigned explicit_alignment = encoded.strct.explicit_alignment;
+ if (explicit_alignment == 0xf)
+ explicit_alignment = blob_read_uint32(blob);
+ else if (explicit_alignment > 0)
+ explicit_alignment = 1 << (explicit_alignment - 1);
glsl_struct_field *fields =
(glsl_struct_field *) malloc(sizeof(glsl_struct_field) * num_fields);
const glsl_type *t;
if (base_type == GLSL_TYPE_INTERFACE) {
+ assert(explicit_alignment == 0);
enum glsl_interface_packing packing =
(glsl_interface_packing) encoded.strct.interface_packing_or_packed;
bool row_major = encoded.strct.interface_row_major;
row_major, name);
} else {
unsigned packed = encoded.strct.interface_packing_or_packed;
- t = glsl_type::get_struct_instance(fields, num_fields, name, packed);
+ t = glsl_type::get_struct_instance(fields, num_fields, name, packed,
+ explicit_alignment);
}
free(fields);