glsl: Mark a set of array elements as accessed using a list of array_deref_range
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
@@ -60,6 +60,14 @@ ir_array_refcount_entry::ir_array_refcount_entry(ir_variable *var)
|
||||
num_bits = MAX2(1, var->type->arrays_of_arrays_size());
|
||||
bits = new BITSET_WORD[BITSET_WORDS(num_bits)];
|
||||
memset(bits, 0, BITSET_WORDS(num_bits) * sizeof(bits[0]));
|
||||
|
||||
/* Count the "depth" of the arrays-of-arrays. */
|
||||
array_depth = 0;
|
||||
for (const glsl_type *type = var->type;
|
||||
type->is_array();
|
||||
type = type->fields.array) {
|
||||
array_depth++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +77,53 @@ ir_array_refcount_entry::~ir_array_refcount_entry()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ir_array_refcount_entry::mark_array_elements_referenced(const array_deref_range *dr,
|
||||
unsigned count)
|
||||
{
|
||||
if (count != array_depth)
|
||||
return;
|
||||
|
||||
mark_array_elements_referenced(dr, count, 1, 0);
|
||||
}
|
||||
|
||||
void
|
||||
ir_array_refcount_entry::mark_array_elements_referenced(const array_deref_range *dr,
|
||||
unsigned count,
|
||||
unsigned scale,
|
||||
unsigned linearized_index)
|
||||
{
|
||||
/* Walk through the list of array dereferences in least- to
|
||||
* most-significant order. Along the way, accumulate the current
|
||||
* linearized offset and the scale factor for each array-of-.
|
||||
*/
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
if (dr[i].index < dr[i].size) {
|
||||
linearized_index += dr[i].index * scale;
|
||||
scale *= dr[i].size;
|
||||
} else {
|
||||
/* For each element in the current array, update the count and
|
||||
* offset, then recurse to process the remaining arrays.
|
||||
*
|
||||
* There is some inefficency here if the last element in the
|
||||
* array_deref_range list specifies the entire array. In that case,
|
||||
* the loop will make recursive calls with count == 0. In the call,
|
||||
* all that will happen is the bit will be set.
|
||||
*/
|
||||
for (unsigned j = 0; j < dr[i].size; j++) {
|
||||
mark_array_elements_referenced(&dr[i + 1],
|
||||
count - (i + 1),
|
||||
scale * dr[i].size,
|
||||
linearized_index + (j * scale));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BITSET_SET(bits, linearized_index);
|
||||
}
|
||||
|
||||
ir_array_refcount_entry *
|
||||
ir_array_refcount_visitor::get_variable_entry(ir_variable *var)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user