glsl: Refactor matrix stride calculation into a utility function

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Thomas Helland <thomashelland90@gmail.com>
This commit is contained in:
Ian Romanick 2017-11-01 16:27:53 -07:00
parent 88f5588f77
commit 24e78d99db
2 changed files with 50 additions and 11 deletions

View File

@ -398,6 +398,48 @@ private:
} /* anonymous namespace */
unsigned
link_calculate_matrix_stride(const glsl_type *matrix, bool row_major,
enum glsl_interface_packing packing)
{
const unsigned N = matrix->is_double() ? 8 : 4;
const unsigned items =
row_major ? matrix->matrix_columns : matrix->vector_elements;
assert(items <= 4);
/* Matrix stride for std430 mat2xY matrices are not rounded up to
* vec4 size.
*
* Section 7.6.2.2 "Standard Uniform Block Layout" of the OpenGL 4.3 spec
* says:
*
* 2. If the member is a two- or four-component vector with components
* consuming N basic machine units, the base alignment is 2N or 4N,
* respectively.
* ...
* 4. If the member is an array of scalars or vectors, the base
* alignment and array stride are set to match the base alignment of
* a single array element, according to rules (1), (2), and (3), and
* rounded up to the base alignment of a vec4.
* ...
* 7. If the member is a row-major matrix with C columns and R rows, the
* matrix is stored identically to an array of R row vectors with C
* components each, according to rule (4).
* ...
*
* When using the std430 storage layout, shader storage blocks will be
* laid out in buffer storage identically to uniform and shader storage
* blocks using the std140 layout, except that the base alignment and
* stride of arrays of scalars and vectors in rule 4 and of structures
* in rule 9 are not rounded up a multiple of the base alignment of a
* vec4.
*/
return packing == GLSL_INTERFACE_PACKING_STD430
? (items < 3 ? items * N : glsl_align(items * N, 16))
: glsl_align(items * N, 16);
}
/**
* Class to help parcel out pieces of backing storage to uniforms
*
@ -856,17 +898,10 @@ private:
}
if (type->without_array()->is_matrix()) {
const glsl_type *matrix = type->without_array();
const unsigned N = matrix->is_double() ? 8 : 4;
const unsigned items =
row_major ? matrix->matrix_columns : matrix->vector_elements;
assert(items <= 4);
if (packing == GLSL_INTERFACE_PACKING_STD430)
this->uniforms[id].matrix_stride = items < 3 ? items * N :
glsl_align(items * N, 16);
else
this->uniforms[id].matrix_stride = glsl_align(items * N, 16);
this->uniforms[id].matrix_stride =
link_calculate_matrix_stride(type->without_array(),
row_major,
packing);
this->uniforms[id].row_major = row_major;
} else {
this->uniforms[id].matrix_stride = 0;

View File

@ -92,6 +92,10 @@ link_intrastage_shaders(void *mem_ctx,
unsigned num_shaders,
bool allow_missing_main);
extern unsigned
link_calculate_matrix_stride(const glsl_type *matrix, bool row_major,
enum glsl_interface_packing packing);
/**
* Class for processing all of the leaf fields of a variable that corresponds
* to a program resource.