[Mesa-dev] [PATCH 16/20] i965/vec4: Pack UBO registers right after uniform registers

Abdiel Janulgue abdiel.janulgue at linux.intel.com
Fri Sep 11 01:33:30 PDT 2015


Since we now consider UBOs as push constants, we need to layout
our push constant register space in such a way that UBO registers
are packed right after uniform registers.

Signed-off-by: Abdiel Janulgue <abdiel.janulgue at linux.intel.com>
---
 src/mesa/drivers/dri/i965/brw_vec4.cpp | 38 ++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 13 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index 549fcd3..5bc1f10 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -516,9 +516,10 @@ vec4_visitor::split_uniform_registers()
 void
 vec4_visitor::pack_uniform_registers()
 {
-   bool uniform_used[this->uniforms];
-   int new_loc[this->uniforms];
-   int new_chan[this->uniforms];
+   int total_uniforms = this->uniforms + this->ubo_uniforms;
+   bool uniform_used[total_uniforms];
+   int new_loc[total_uniforms];
+   int new_chan[total_uniforms];
 
    memset(uniform_used, 0, sizeof(uniform_used));
    memset(new_loc, 0, sizeof(new_loc));
@@ -542,7 +543,7 @@ vec4_visitor::pack_uniform_registers()
    /* Now, figure out a packing of the live uniform vectors into our
     * push constants.
     */
-   for (int src = 0; src < uniforms; src++) {
+   for (int src = 0; src < total_uniforms; src++) {
       assert(src < uniform_array_size);
       int size = this->uniform_vector_size[src];
 
@@ -552,9 +553,16 @@ vec4_visitor::pack_uniform_registers()
       }
 
       int dst;
-      /* Find the lowest place we can slot this uniform in. */
+      /* Find the lowest place we can slot this uniform in. However, when
+       * our constants come from a mix of UBO and uniform sources, don't allow registers
+       * assigned to UBOs fall into half-filled uniform slots when repacking,
+       * otherwise we could mix up uniform and UBO register fetches in one vec4.
+       */
       for (dst = 0; dst < src; dst++) {
-	 if (this->uniform_vector_size[dst] + size <= 4)
+         bool allow_repack = ((src >= uniforms && dst >= uniforms) ||
+                              (src < uniforms && dst < uniforms)   ||
+                              this->uniform_vector_size[dst] == 0);
+	 if (this->uniform_vector_size[dst] + size <= 4 && allow_repack)
 	    break;
       }
 
@@ -565,17 +573,20 @@ vec4_visitor::pack_uniform_registers()
 	 new_loc[src] = dst;
 	 new_chan[src] = this->uniform_vector_size[dst];
 
-	 /* Move the references to the data */
-	 for (int j = 0; j < size; j++) {
-	    stage_prog_data->param[dst * 4 + new_chan[src] + j] =
-	       stage_prog_data->param[src * 4 + j];
-	 }
+	 /* Move the references only for uniform data */
+         if (src < uniforms) {
+            for (int j = 0; j < size; j++) {
+               stage_prog_data->param[dst * 4 + new_chan[src] + j] =
+                  stage_prog_data->param[src * 4 + j];
+            }
+         }
 
 	 this->uniform_vector_size[dst] += size;
 	 this->uniform_vector_size[src] = 0;
       }
 
-      new_uniform_count = MAX2(new_uniform_count, dst + 1);
+      if (src < uniforms)
+         new_uniform_count = MAX2(new_uniform_count, dst + 1);
    }
 
    this->uniforms = new_uniform_count;
@@ -1616,7 +1627,8 @@ vec4_visitor::setup_uniforms(int reg)
       this->uniforms++;
       reg++;
    } else {
-      reg += ALIGN(uniforms, 2) / 2;
+      int ubo_regs = ALIGN(ubo_uniforms, 4) / 4;
+      reg += ALIGN(ubo_regs + uniforms, 2) / 2;
    }
 
    stage_prog_data->nr_params = this->uniforms * 4;
-- 
1.9.1



More information about the mesa-dev mailing list