summaryrefslogtreecommitdiffstats
path: root/src/glsl/lower_ubo_reference.cpp
diff options
context:
space:
mode:
authorJordan Justen <[email protected]>2015-11-16 18:09:27 -0800
committerJordan Justen <[email protected]>2015-12-09 23:50:38 -0800
commitee005df2f90930675a1f955030014a66dfa255da (patch)
tree4c85f5d3377561dc4f018c8cffc0bdef4d5ae5e2 /src/glsl/lower_ubo_reference.cpp
parent99c8196458dc8f299d0b49c8ee801d6e9a2bc1db (diff)
glsl ubo/ssbo: Move common code into lower_buffer_access::setup_buffer_access
This code will also be usable by the pass to lower shared variables. Note, that *const_offset is adjusted by setup_buffer_access so it must be initialized before calling setup_buffer_access. v2: * Add comment for lower_buffer_access::setup_buffer_access Signed-off-by: Jordan Justen <[email protected]> Reviewed-by: Iago Toral Quiroga <[email protected]> Reviewed-by: Kristian Høgsberg <[email protected]>
Diffstat (limited to 'src/glsl/lower_ubo_reference.cpp')
-rw-r--r--src/glsl/lower_ubo_reference.cpp160
1 files changed, 3 insertions, 157 deletions
diff --git a/src/glsl/lower_ubo_reference.cpp b/src/glsl/lower_ubo_reference.cpp
index d0fb4d6f8f6..04b82d95c31 100644
--- a/src/glsl/lower_ubo_reference.cpp
+++ b/src/glsl/lower_ubo_reference.cpp
@@ -287,164 +287,10 @@ lower_ubo_reference_visitor::setup_for_load_or_store(ir_variable *var,
assert(this->uniform_block);
- *offset = new(mem_ctx) ir_constant(0u);
- *const_offset = 0;
- *row_major = is_dereferenced_thing_row_major(deref);
- *matrix_columns = 1;
-
- /* Calculate the offset to the start of the region of the UBO
- * dereferenced by *rvalue. This may be a variable offset if an
- * array dereference has a variable index.
- */
- while (deref) {
- switch (deref->ir_type) {
- case ir_type_dereference_variable: {
- *const_offset += ubo_var->Offset;
- deref = NULL;
- break;
- }
-
- case ir_type_dereference_array: {
- ir_dereference_array *deref_array = (ir_dereference_array *) deref;
- unsigned array_stride;
- if (deref_array->array->type->is_vector()) {
- /* We get this when storing or loading a component out of a vector
- * with a non-constant index. This happens for v[i] = f where v is
- * a vector (or m[i][j] = f where m is a matrix). If we don't
- * lower that here, it gets turned into v = vector_insert(v, i,
- * f), which loads the entire vector, modifies one component and
- * then write the entire thing back. That breaks if another
- * thread or SIMD channel is modifying the same vector.
- */
- array_stride = 4;
- if (deref_array->array->type->is_double())
- array_stride *= 2;
- } else if (deref_array->array->type->is_matrix() && *row_major) {
- /* When loading a vector out of a row major matrix, the
- * step between the columns (vectors) is the size of a
- * float, while the step between the rows (elements of a
- * vector) is handled below in emit_ubo_loads.
- */
- array_stride = 4;
- if (deref_array->array->type->is_double())
- array_stride *= 2;
- *matrix_columns = deref_array->array->type->matrix_columns;
- } else if (deref_array->type->without_array()->is_interface()) {
- /* We're processing an array dereference of an interface instance
- * array. The thing being dereferenced *must* be a variable
- * dereference because interfaces cannot be embedded in other
- * types. In terms of calculating the offsets for the lowering
- * pass, we don't care about the array index. All elements of an
- * interface instance array will have the same offsets relative to
- * the base of the block that backs them.
- */
- deref = deref_array->array->as_dereference();
- break;
- } else {
- /* Whether or not the field is row-major (because it might be a
- * bvec2 or something) does not affect the array itself. We need
- * to know whether an array element in its entirety is row-major.
- */
- const bool array_row_major =
- is_dereferenced_thing_row_major(deref_array);
-
- /* The array type will give the correct interface packing
- * information
- */
- if (packing == GLSL_INTERFACE_PACKING_STD430) {
- array_stride = deref_array->type->std430_array_stride(array_row_major);
- } else {
- array_stride = deref_array->type->std140_size(array_row_major);
- array_stride = glsl_align(array_stride, 16);
- }
- }
-
- ir_rvalue *array_index = deref_array->array_index;
- if (array_index->type->base_type == GLSL_TYPE_INT)
- array_index = i2u(array_index);
-
- ir_constant *const_index =
- array_index->constant_expression_value(NULL);
- if (const_index) {
- *const_offset += array_stride * const_index->value.u[0];
- } else {
- *offset = add(*offset,
- mul(array_index,
- new(mem_ctx) ir_constant(array_stride)));
- }
- deref = deref_array->array->as_dereference();
- break;
- }
-
- case ir_type_dereference_record: {
- ir_dereference_record *deref_record = (ir_dereference_record *) deref;
- const glsl_type *struct_type = deref_record->record->type;
- unsigned intra_struct_offset = 0;
-
- for (unsigned int i = 0; i < struct_type->length; i++) {
- const glsl_type *type = struct_type->fields.structure[i].type;
-
- ir_dereference_record *field_deref = new(mem_ctx)
- ir_dereference_record(deref_record->record,
- struct_type->fields.structure[i].name);
- const bool field_row_major =
- is_dereferenced_thing_row_major(field_deref);
-
- ralloc_free(field_deref);
-
- unsigned field_align = 0;
-
- if (packing == GLSL_INTERFACE_PACKING_STD430)
- field_align = type->std430_base_alignment(field_row_major);
- else
- field_align = type->std140_base_alignment(field_row_major);
-
- intra_struct_offset = glsl_align(intra_struct_offset, field_align);
-
- if (strcmp(struct_type->fields.structure[i].name,
- deref_record->field) == 0)
- break;
-
- if (packing == GLSL_INTERFACE_PACKING_STD430)
- intra_struct_offset += type->std430_size(field_row_major);
- else
- intra_struct_offset += type->std140_size(field_row_major);
-
- /* If the field just examined was itself a structure, apply rule
- * #9:
- *
- * "The structure may have padding at the end; the base offset
- * of the member following the sub-structure is rounded up to
- * the next multiple of the base alignment of the structure."
- */
- if (type->without_array()->is_record()) {
- intra_struct_offset = glsl_align(intra_struct_offset,
- field_align);
-
- }
- }
-
- *const_offset += intra_struct_offset;
- deref = deref_record->record->as_dereference();
- break;
- }
-
- case ir_type_swizzle: {
- ir_swizzle *deref_swizzle = (ir_swizzle *) deref;
+ *const_offset = ubo_var->Offset;
- assert(deref_swizzle->mask.num_components == 1);
-
- *const_offset += deref_swizzle->mask.x * sizeof(int);
- deref = deref_swizzle->val->as_dereference();
- break;
- }
-
- default:
- assert(!"not reached");
- deref = NULL;
- break;
- }
- }
+ setup_buffer_access(mem_ctx, var, deref, offset, const_offset, row_major,
+ matrix_columns, packing);
}
void