diff options
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vs_emit.c | 35 |
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 */ |