Module: Mesa
Branch: master
Commit: df35d691807656d3627b6fa6f51a08674bdc043e
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=df35d691807656d3627b6fa6f51a08674bdc043e

Author: Eric Anholt <[email protected]>
Date:   Tue Sep  6 22:32:33 2011 -0700

i965/vs: Add support for overflowing the number of available push constants.

Fixes glsl-vs-uniform-array-4.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=33742

Reviewed-by: Ian Romanick <[email protected]>
Acked-by: Kenneth Graunke <[email protected]>

---

 src/mesa/drivers/dri/i965/brw_vec4.cpp      |   85 +++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_vec4.h        |    1 +
 src/mesa/drivers/dri/i965/brw_vec4_emit.cpp |    1 +
 3 files changed, 87 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp 
b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index 9d64a40..e3562d2 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -277,4 +277,89 @@ vec4_visitor::pack_uniform_registers()
    }
 }
 
+/**
+ * Only a limited number of hardware registers may be used for push
+ * constants, so this turns access to the overflowed constants into
+ * pull constants.
+ */
+void
+vec4_visitor::move_push_constants_to_pull_constants()
+{
+   int pull_constant_loc[this->uniforms];
+
+   /* Only allow 32 registers (256 uniform components) as push constants,
+    * which is the limit on gen6.
+    */
+   int max_uniform_components = 32 * 8;
+   if (this->uniforms * 4 <= max_uniform_components)
+      return;
+
+   /* Make some sort of choice as to which uniforms get sent to pull
+    * constants.  We could potentially do something clever here like
+    * look for the most infrequently used uniform vec4s, but leave
+    * that for later.
+    */
+   for (int i = 0; i < this->uniforms * 4; i += 4) {
+      pull_constant_loc[i / 4] = -1;
+
+      if (i >= max_uniform_components) {
+        const float **values = &prog_data->param[i];
+
+        /* Try to find an existing copy of this uniform in the pull
+         * constants if it was part of an array access already.
+         */
+        for (unsigned int j = 0; j < prog_data->nr_pull_params; j += 4) {
+           int matches;
+
+           for (matches = 0; matches < 4; matches++) {
+              if (prog_data->pull_param[j + matches] != values[matches])
+                 break;
+           }
+
+           if (matches == 4) {
+              pull_constant_loc[i / 4] = j / 4;
+              break;
+           }
+        }
+
+        if (pull_constant_loc[i / 4] == -1) {
+           assert(prog_data->nr_pull_params % 4 == 0);
+           pull_constant_loc[i / 4] = prog_data->nr_pull_params / 4;
+
+           for (int j = 0; j < 4; j++) {
+              prog_data->pull_param[prog_data->nr_pull_params++] = values[j];
+           }
+        }
+      }
+   }
+
+   /* Now actually rewrite usage of the things we've moved to pull
+    * constants.
+    */
+   foreach_list_safe(node, &this->instructions) {
+      vec4_instruction *inst = (vec4_instruction *)node;
+
+      for (int i = 0 ; i < 3; i++) {
+        if (inst->src[i].file != UNIFORM ||
+            pull_constant_loc[inst->src[i].reg] == -1)
+           continue;
+
+        int uniform = inst->src[i].reg;
+
+        dst_reg temp = dst_reg(this, glsl_type::vec4_type);
+
+        emit_pull_constant_load(inst, temp, inst->src[i],
+                                pull_constant_loc[uniform]);
+
+        inst->src[i].file = temp.file;
+        inst->src[i].reg = temp.reg;
+        inst->src[i].reg_offset = temp.reg_offset;
+        inst->src[i].reladdr = NULL;
+      }
+   }
+
+   /* Repack push constants to remove the now-unused ones. */
+   pack_uniform_registers();
+}
+
 } /* namespace brw */
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h 
b/src/mesa/drivers/dri/i965/brw_vec4.h
index 0bfd88b..1597f98 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -381,6 +381,7 @@ public:
    void reg_allocate();
    void move_grf_array_access_to_scratch();
    void move_uniform_array_access_to_pull_constants();
+   void move_push_constants_to_pull_constants();
    void split_uniform_registers();
    void pack_uniform_registers();
    void calculate_live_intervals();
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp 
b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
index 3567949..78ffbd7 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
@@ -608,6 +608,7 @@ vec4_visitor::run()
    move_grf_array_access_to_scratch();
    move_uniform_array_access_to_pull_constants();
    pack_uniform_registers();
+   move_push_constants_to_pull_constants();
 
    bool progress;
    do {

_______________________________________________
mesa-commit mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to