summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2011-04-29 15:59:30 -0700
committerEric Anholt <[email protected]>2011-05-01 20:13:10 -0700
commit484b51d484e52836bd2d2ded64626342203df0d3 (patch)
treeab9093886fef74fedae03125b73db84fe126c1ef /src/mesa
parenteb0a9e9a5a3e1d86bce24cf4839be60ce72d89e3 (diff)
i965/gen6: Align interleaved URB writes for overflow outputs as well.
Fixes glsl-max-varyings. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=35614 Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index dd4e1e6c6ad..a28cdc0bfe9 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -1553,6 +1553,26 @@ static void emit_swz( struct brw_vs_compile *c,
}
}
+static int
+align_interleaved_urb_mlen(struct brw_context *brw, int mlen)
+{
+ struct intel_context *intel = &brw->intel;
+
+ if (intel->gen >= 6) {
+ /* URB data written (does not include the message header reg) must
+ * be a multiple of 256 bits, or 2 VS registers. See vol5c.5,
+ * section 5.4.3.2.2: URB_INTERLEAVED.
+ *
+ * URB entries are allocated on a multiple of 1024 bits, so an
+ * extra 128 bits written here to make the end align to 256 is
+ * no problem.
+ */
+ if ((mlen % 2) != 1)
+ mlen++;
+ }
+
+ return mlen;
+}
/**
* Post-vertex-program processing. Send the results to the URB.
@@ -1734,12 +1754,11 @@ static void emit_vertex_write( struct brw_vs_compile *c)
eot = (c->first_overflow_output == 0);
- msg_len = c->nr_outputs + 2 + len_vertex_header;
- if (intel->gen >= 6) {
- /* interleaved urb write message length for gen6 should be multiple of 2 */
- if ((msg_len % 2) != 0)
- msg_len++;
- }
+ /* Message header, plus VUE header, plus the (first set of) outputs. */
+ msg_len = 1 + len_vertex_header + c->nr_outputs;
+ msg_len = align_interleaved_urb_mlen(brw, msg_len);
+ /* Any outputs beyond BRW_MAX_MRF should be past first_overflow_output */
+ msg_len = MIN2(msg_len, (BRW_MAX_MRF - 1)),
brw_urb_WRITE(p,
brw_null_reg(), /* dest */
@@ -1747,7 +1766,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
c->r0, /* src */
0, /* allocate */
1, /* used */
- MIN2(msg_len - 1, (BRW_MAX_MRF - 1)), /* msg len */
+ msg_len,
0, /* response len */
eot, /* eot */
eot, /* writes complete */
@@ -1774,7 +1793,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
c->r0, /* src */
0, /* allocate */
1, /* used */
- mrf, /* msg len */
+ align_interleaved_urb_mlen(brw, mrf),
0, /* response len */
1, /* eot */
1, /* writes complete */