i965: Fix register allocation of GLSL fp inputs.
authorEric Anholt <eric@anholt.net>
Thu, 14 May 2009 16:49:45 +0000 (09:49 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 14 May 2009 18:41:04 +0000 (11:41 -0700)
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.

src/mesa/drivers/dri/i965/brw_wm.c
src/mesa/drivers/dri/i965/brw_wm.h
src/mesa/drivers/dri/i965/brw_wm_glsl.c
src/mesa/drivers/dri/i965/brw_wm_pass2.c

index cd65f57bbc97d5bb3f931bc5576fb4148e9ac6c9..3e476fd3be50570b7a60f3116c89b891ca844a45 100644 (file)
@@ -319,6 +319,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;
 }
@@ -357,7 +360,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
 };
index 59ead757b514b297bd8f7ed3658e077c90063225..fb15c03e83d9b7092718008a29e99b6648e58c62 100644 (file)
@@ -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;
 };
 
 
index 23caf59435f7c29797106467de3d33efa2b71afc..4936703799157156f9b6f13dcabd3f68889296c4 100644 (file)
@@ -302,7 +302,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;
     GLuint reg_index = 0;
 
@@ -366,18 +366,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(reg_index, 0);
-           for (j = 0; j < 4; j++)
-               set_reg(c, PROGRAM_PAYLOAD, i, j, reg);
-           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 = reg_index;
+         reg = brw_vec8_grf(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)) {
+         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, reg_index, 0);
     reg_index++;
index 780edbc42e67a30fa95fc8c597b025c66cc0b8a8..08cac730c2981f8d9e2f64fd1c7618af4b1ad5a3 100644 (file)
@@ -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;