Mesa (master): i965: Pre-gen6, map VS outputs (not FS inputs) to URB setup in the new FS.

Eric Anholt anholt at kemper.freedesktop.org
Fri Oct 1 19:21:59 UTC 2010


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

Author: Eric Anholt <eric at anholt.net>
Date:   Fri Oct  1 12:15:48 2010 -0700

i965: Pre-gen6, map VS outputs (not FS inputs) to URB setup in the new FS.

We should fix the SF to actually give us just the data we need, but
this fixes regressions in the new FS until then.

Fixes:
glsl-kwin-blur
glsl-routing

---

 src/mesa/drivers/dri/i965/brw_fs.cpp |   72 ++++++++++++++++++++++-----------
 1 files changed, 48 insertions(+), 24 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 9567141..9783e61 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -450,6 +450,7 @@ public:
 
    fs_inst *emit(fs_inst inst);
    void assign_curb_setup();
+   void calculate_urb_setup();
    void assign_urb_setup();
    void assign_regs();
    void assign_regs_trivial();
@@ -499,6 +500,7 @@ public:
    struct hash_table *variable_ht;
    ir_variable *frag_color, *frag_data, *frag_depth;
    int first_non_payload_grf;
+   int urb_setup[FRAG_ATTRIB_MAX];
 
    /** @{ debug annotation info */
    const char *current_annotation;
@@ -780,10 +782,9 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
    int location = ir->location;
    for (unsigned int i = 0; i < array_elements; i++) {
       for (unsigned int j = 0; j < type->matrix_columns; j++) {
-	 if (!(fp->Base.InputsRead & BITFIELD64_BIT(location))) {
+	 if (urb_setup[location] == -1) {
 	    /* If there's no incoming setup data for this slot, don't
-	     * emit interpolation for it (since it's not used, and
-	     * we'd fall over later trying to find the setup data.
+	     * emit interpolation for it.
 	     */
 	    attr.reg_offset += type->vector_elements;
 	    location++;
@@ -1656,9 +1657,11 @@ fs_visitor::emit_dummy_fs()
 struct brw_reg
 fs_visitor::interp_reg(int location, int channel)
 {
-   int regnr = location * 2 + channel / 2;
+   int regnr = urb_setup[location] * 2 + channel / 2;
    int stride = (channel & 1) * 4;
 
+   assert(urb_setup[location] != -1);
+
    return brw_vec1_grf(regnr, stride);
 }
 
@@ -2085,28 +2088,51 @@ fs_visitor::assign_curb_setup()
 }
 
 void
-fs_visitor::assign_urb_setup()
+fs_visitor::calculate_urb_setup()
 {
-   int urb_start = c->prog_data.first_curbe_grf + c->prog_data.curb_read_length;
-   int interp_reg_nr[FRAG_ATTRIB_MAX];
-
-   c->prog_data.urb_read_length = 0;
+   for (unsigned int i = 0; i < FRAG_ATTRIB_MAX; i++) {
+      urb_setup[i] = -1;
+   }
 
+   int urb_next = 0;
    /* Figure out where each of the incoming setup attributes lands. */
-   for (unsigned int i = 0; i < FRAG_ATTRIB_MAX; i++) {
-      interp_reg_nr[i] = -1;
+   if (intel->gen >= 6) {
+      for (unsigned int i = 0; i < FRAG_ATTRIB_MAX; i++) {
+	 if (i == FRAG_ATTRIB_WPOS ||
+	     (brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(i))) {
+	    urb_setup[i] = urb_next++;
+	 }
+      }
+   } else {
+      /* FINISHME: The sf doesn't map VS->FS inputs for us very well. */
+      for (unsigned int i = 0; i < VERT_RESULT_MAX; i++) {
+	 if (c->key.vp_outputs_written & BITFIELD64_BIT(i)) {
+	    int fp_index;
+
+	    if (i >= VERT_RESULT_VAR0)
+	       fp_index = i - (VERT_RESULT_VAR0 - FRAG_ATTRIB_VAR0);
+	    else if (i <= VERT_RESULT_TEX7)
+	       fp_index = i;
+	    else
+	       fp_index = -1;
+
+	    if (fp_index >= 0)
+	       urb_setup[fp_index] = urb_next++;
+	 }
+      }
+   }
 
-      if (i != FRAG_ATTRIB_WPOS &&
-	  !(brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(i)))
-	 continue;
+   /* Each attribute is 4 setup channels, each of which is half a reg. */
+   c->prog_data.urb_read_length = urb_next * 2;
+}
 
-      /* Each attribute is 4 setup channels, each of which is half a reg. */
-      interp_reg_nr[i] = urb_start + c->prog_data.urb_read_length;
-      c->prog_data.urb_read_length += 2;
-   }
+void
+fs_visitor::assign_urb_setup()
+{
+   int urb_start = c->prog_data.first_curbe_grf + c->prog_data.curb_read_length;
 
-   /* Map the register numbers for FS_OPCODE_LINTERP so that it uses
-    * the correct setup input.
+   /* Offset all the urb_setup[] index by the actual position of the
+    * setup regs, now that the location of the constants has been chosen.
     */
    foreach_iter(exec_list_iterator, iter, this->instructions) {
       fs_inst *inst = (fs_inst *)iter.get();
@@ -2116,10 +2142,7 @@ fs_visitor::assign_urb_setup()
 
       assert(inst->src[2].file == FIXED_HW_REG);
 
-      int location = inst->src[2].fixed_hw_reg.nr / 2;
-      assert(interp_reg_nr[location] != -1);
-      inst->src[2].fixed_hw_reg.nr = (interp_reg_nr[location] +
-				      (inst->src[2].fixed_hw_reg.nr & 1));
+      inst->src[2].fixed_hw_reg.nr += urb_start;
    }
 
    this->first_non_payload_grf = urb_start + c->prog_data.urb_read_length;
@@ -2648,6 +2671,7 @@ brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c)
    if (0) {
       v.emit_dummy_fs();
    } else {
+      v.calculate_urb_setup();
       if (intel->gen < 6)
 	 v.emit_interpolation_setup_gen4();
       else




More information about the mesa-commit mailing list