i965: Mostly fix glsl-max-varyings.
authorEric Anholt <eric@anholt.net>
Tue, 20 Jul 2010 00:22:20 +0000 (17:22 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 20 Jul 2010 02:29:48 +0000 (19:29 -0700)
There was confusion on both the size of message we can send, and on
what the URB destination offset means.

The remaining problems appear to be due to spilling of regs in the
fragment shader being broken.

src/mesa/drivers/dri/i965/brw_vs_emit.c

index 5d22d548f3e490675d991014f8d1a0c49da47e45..2c18113ceb78539df87828105bf55b275d8da90b 100644 (file)
@@ -238,12 +238,25 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
            mrf++;              /* just a placeholder?  XXX fix later stages & remove this */
         }
         else {
-            if (mrf < 16) {
+           /* Two restrictions on our compute-to-MRF here.  The
+            * message length for all SEND messages is restricted to
+            * [1,15], so we can't use mrf 15, as that means a length
+            * of 16.
+            *
+            * Additionally, URB writes are aligned to URB rows, so we
+            * need to put an even number of registers of URB data in
+            * each URB write so that the later write is aligned.  A
+            * message length of 15 means 1 message header reg plus 14
+            * regs of URB data.
+            *
+            * For attributes beyond the compute-to-MRF, we compute to
+            * GRFs and they will be written in the second URB_WRITE.
+            */
+            if (mrf < 15) {
                c->regs[PROGRAM_OUTPUT][i] = brw_message_reg(mrf);
                mrf++;
             }
             else {
-               /* too many vertex results to fit in MRF, use GRF for overflow */
                if (!c->first_overflow_output)
                   c->first_overflow_output = i;
                c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0);
@@ -1426,29 +1439,26 @@ static void emit_vertex_write( struct brw_vs_compile *c)
        * Move the overflowed attributes from the GRF to the MRF and
        * issue another brw_urb_WRITE().
        */
-      /* XXX I'm not 100% sure about which MRF regs to use here.  Starting
-       * at mrf[4] atm...
-       */
-      GLuint i, mrf = 0;
+      GLuint i, mrf = 1;
       for (i = c->first_overflow_output; i < VERT_RESULT_MAX; i++) {
          if (c->prog_data.outputs_written & BITFIELD64_BIT(i)) {
             /* move from GRF to MRF */
-            brw_MOV(p, brw_message_reg(4+mrf), c->regs[PROGRAM_OUTPUT][i]);
+            brw_MOV(p, brw_message_reg(mrf), c->regs[PROGRAM_OUTPUT][i]);
             mrf++;
          }
       }
 
       brw_urb_WRITE(p,
                     brw_null_reg(), /* dest */
-                    4,              /* starting mrf reg nr */
+                    0,              /* starting mrf reg nr */
                     c->r0,          /* src */
                     0,              /* allocate */
                     1,              /* used */
-                    mrf+1,          /* msg len */
+                    mrf,            /* msg len */
                     0,              /* response len */
                     1,              /* eot */
                     1,              /* writes complete */
-                    BRW_MAX_MRF-1,  /* urb destination offset */
+                    14 / 2,  /* urb destination offset */
                     BRW_URB_SWIZZLE_INTERLEAVE);
    }
 }