i965/vs: Add support for VUEs larger than a single URB write.

Fixes glsl-max-varyings.
This commit is contained in:
Eric Anholt
2011-08-05 21:53:00 -07:00
parent 31ef2e3ec2
commit 160a5a3ff0
+34 -8
View File
@@ -1703,6 +1703,7 @@ vec4_visitor::emit_urb_writes()
int base_mrf = 1;
int mrf = base_mrf;
int urb_entry_size;
uint64_t outputs_remaining = c->prog_data.outputs_written;
/* FINISHME: edgeflag */
@@ -1717,11 +1718,14 @@ vec4_visitor::emit_urb_writes()
mrf = emit_vue_header_gen4(mrf);
}
/* Set up the VUE data for the first URB write */
int attr;
for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
if (!(c->prog_data.outputs_written & BITFIELD64_BIT(attr)))
continue;
outputs_remaining &= ~BITFIELD64_BIT(attr);
/* This is set up in the VUE header. */
if (attr == VERT_RESULT_HPOS)
continue;
@@ -1734,27 +1738,49 @@ vec4_visitor::emit_urb_writes()
emit(BRW_OPCODE_MOV, brw_message_reg(mrf++), src_reg(output_reg[attr]));
/* If this is MRF 15, we can't fit anything more into this URB
/* If this was MRF 15, we can't fit anything more into this URB
* WRITE. Note that base_mrf of 1 means that MRF 15 is an
* even-numbered amount of URB write data, which will meet
* gen6's requirements for length alignment.
*/
if (mrf == 15)
if (mrf == 16) {
attr++;
break;
}
}
vec4_instruction *inst = emit(VS_OPCODE_URB_WRITE);
inst->base_mrf = base_mrf;
inst->mlen = align_interleaved_urb_mlen(brw, mrf - base_mrf);
inst->eot = true;
inst->eot = !outputs_remaining;
urb_entry_size = mrf - base_mrf;
for (; attr < VERT_RESULT_MAX; attr++) {
if (!(c->prog_data.outputs_written & BITFIELD64_BIT(attr)))
continue;
fail("Second URB write not supported.\n");
break;
/* Optional second URB write */
if (outputs_remaining) {
mrf = base_mrf + 1;
for (; attr < VERT_RESULT_MAX; attr++) {
if (!(c->prog_data.outputs_written & BITFIELD64_BIT(attr)))
continue;
emit(BRW_OPCODE_MOV, brw_message_reg(mrf++), src_reg(output_reg[attr]));
assert(mrf != 16);
}
inst = emit(VS_OPCODE_URB_WRITE);
inst->base_mrf = base_mrf;
inst->mlen = align_interleaved_urb_mlen(brw, mrf - base_mrf);
inst->eot = true;
/* URB destination offset. In the previous write, we got MRFs 2-
* 15 MRFs minus the one header MRF, so 14 regs. URB offset is in
* URB row increments, and each of our MRFs is half of one of
* those, since we're doing interleaved writes.
*/
inst->offset = 14 / 2;
urb_entry_size += mrf - base_mrf;
}
if (intel->gen == 6)