Mesa (mesa_7_5_branch): i965: Fix register allocation of GLSL fp inputs.

Eric Anholt anholt at kemper.freedesktop.org
Wed Jun 17 19:06:13 UTC 2009


Module: Mesa
Branch: mesa_7_5_branch
Commit: 988b61be2743de6850c8042516db28d14ee3002f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=988b61be2743de6850c8042516db28d14ee3002f

Author: Eric Anholt <eric at anholt.net>
Date:   Thu May 14 09:49:45 2009 -0700

i965: Fix register allocation of GLSL fp inputs.

Before, if the VP output something that is in the attributes coming into
the WM but which isn't used by the WM, then WM would end up reading subsequent
varyings from the wrong places.  This was visible with a GLSL demo
using gl_PointSize in the VS and a varying in the WM, as point size is in
the VUE but not used by the WM.  There is now a regression test in piglit,
glsl-unused-varying.

(cherry picked from commit 0f5113deed91611ecdda6596542530b1849bb161)

---

 src/mesa/drivers/dri/i965/brw_wm.c       |    5 +++-
 src/mesa/drivers/dri/i965/brw_wm.h       |    1 +
 src/mesa/drivers/dri/i965/brw_wm_glsl.c  |   31 ++++++++++++++++++++---------
 src/mesa/drivers/dri/i965/brw_wm_pass2.c |    3 +-
 4 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index c0b07da..bd296aa 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -312,6 +312,9 @@ static void brw_wm_populate_key( struct brw_context *brw,
       key->drawable_height = brw->intel.driDrawable->h;
    }
 
+   /* CACHE_NEW_VS_PROG */
+   key->vp_outputs_written = brw->vs.prog_data->outputs_written & DO_SETUP_BITS;
+
    /* The unique fragment program ID */
    key->program_string_id = fp->id;
 }
@@ -350,7 +353,7 @@ const struct brw_tracked_state brw_wm_prog = {
       .brw   = (BRW_NEW_FRAGMENT_PROGRAM |
 		BRW_NEW_WM_INPUT_DIMENSIONS |
 		BRW_NEW_REDUCED_PRIMITIVE),
-      .cache = 0
+      .cache = CACHE_NEW_VS_PROG,
    },
    .prepare = brw_prepare_wm_prog
 };
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index 0408034..295fed8 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -75,6 +75,7 @@ struct brw_wm_prog_key {
    GLuint program_string_id:32;
    GLuint origin_x, origin_y;
    GLuint drawable_height;
+   GLuint vp_outputs_written;
 };
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 1174608..875683e 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -177,7 +177,7 @@ static void prealloc_reg(struct brw_wm_compile *c)
 {
     int i, j;
     struct brw_reg reg;
-    int nr_interp_regs = 0;
+    int urb_read_length = 0;
     GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted | c->fp_deriv_emitted;
 
     for (i = 0; i < 4; i++) {
@@ -231,18 +231,29 @@ static void prealloc_reg(struct brw_wm_compile *c)
     }
 
     /* fragment shader inputs */
-    for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
-	if (inputs & (1<<i)) {
-	    nr_interp_regs++;
-	    reg = brw_vec8_grf(c->reg_index, 0);
-	    for (j = 0; j < 4; j++)
-		set_reg(c, PROGRAM_PAYLOAD, i, j, reg);
-	    c->reg_index += 2;
-	}
+    for (i = 0; i < VERT_RESULT_MAX; i++) {
+       int fp_input;
+
+       if (i >= VERT_RESULT_VAR0)
+	  fp_input = i - VERT_RESULT_VAR0 + FRAG_ATTRIB_VAR0;
+       else if (i <= VERT_RESULT_TEX7)
+	  fp_input = i;
+       else
+	  fp_input = -1;
+
+       if (fp_input >= 0 && inputs & (1 << fp_input)) {
+	  urb_read_length = c->reg_index;
+	  reg = brw_vec8_grf(c->reg_index, 0);
+	  for (j = 0; j < 4; j++)
+	     set_reg(c, PROGRAM_PAYLOAD, fp_input, j, reg);
+       }
+       if (c->key.vp_outputs_written & (1 << i)) {
+	  c->reg_index += 2;
+       }
     }
 
     c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
-    c->prog_data.urb_read_length = nr_interp_regs * 2;
+    c->prog_data.urb_read_length = urb_read_length;
     c->prog_data.curb_read_length = c->nr_creg;
     c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
     c->reg_index++;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass2.c b/src/mesa/drivers/dri/i965/brw_wm_pass2.c
index 780edbc..08cac73 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass2.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass2.c
@@ -70,7 +70,6 @@ static void prealloc_reg(struct brw_wm_compile *c,
 static void init_registers( struct brw_wm_compile *c )
 {
    struct brw_context *brw = c->func.brw;
-   GLuint inputs = (brw->vs.prog_data->outputs_written & DO_SETUP_BITS);
    GLuint nr_interp_regs = 0;
    GLuint i = 0;
    GLuint j;
@@ -85,7 +84,7 @@ static void init_registers( struct brw_wm_compile *c )
       prealloc_reg(c, &c->creg[j], i++);
 
    for (j = 0; j < FRAG_ATTRIB_MAX; j++) {
-      if (inputs & (1<<j)) {
+      if (c->key.vp_outputs_written & (1<<j)) {
 	 /* index for vs output and ps input are not the same 
 	    in shader varying */
 	 GLuint index;




More information about the mesa-commit mailing list