vk/image: Check extent does not exceed surface type limits
[mesa.git] / src / glsl / loop_unroll.cpp
index ce795f6cd245c31324bbc087b6960144fe697460..635e1dd99cd5058be97d1023047b5e009611da7d 100644 (file)
@@ -64,6 +64,7 @@ class loop_unroll_count : public ir_hierarchical_visitor {
 public:
    int nodes;
    bool unsupported_variable_indexing;
+   bool array_indexed_by_induction_var_with_exact_iterations;
    /* If there are nested loops, the node count will be inaccurate. */
    bool nested_loop;
 
@@ -74,6 +75,7 @@ public:
       nodes = 0;
       nested_loop = false;
       unsupported_variable_indexing = false;
+      array_indexed_by_induction_var_with_exact_iterations = false;
 
       run(list);
    }
@@ -112,6 +114,14 @@ public:
          ir_variable *array = ir->array->variable_referenced();
          loop_variable *lv = ls->get(ir->array_index->variable_referenced());
          if (array && lv && lv->is_induction_var()) {
+            /* If an array is indexed by a loop induction variable, and the
+             * array size is exactly the number of loop iterations, this is
+             * probably a simple for-loop trying to access each element in
+             * turn; the application may expect it to be unrolled.
+             */
+            if (int(array->type->length) == ls->limiting_terminator->iterations)
+               array_indexed_by_induction_var_with_exact_iterations = true;
+
             switch (array->data.mode) {
             case ir_var_auto:
             case ir_var_temporary:
@@ -314,7 +324,8 @@ loop_unroll_visitor::visit_leave(ir_loop *ir)
    bool loop_too_large =
       count.nested_loop || count.nodes * iterations > max_iterations * 5;
 
-   if (loop_too_large && !count.unsupported_variable_indexing)
+   if (loop_too_large && !count.unsupported_variable_indexing &&
+       !count.array_indexed_by_induction_var_with_exact_iterations)
       return visit_continue;
 
    /* Note: the limiting terminator contributes 1 to ls->num_loop_jumps.