diff options
author | Eric Anholt <[email protected]> | 2010-10-01 12:15:48 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2010-10-01 12:21:51 -0700 |
commit | 8f63a44636e4fef2f35fe73f24c27db9b04389b1 (patch) | |
tree | 924bc25a9b424a55bcae43475ecf3008722a9494 | |
parent | ff5ce9289b5159e7de34706b31be771d3e3cefd6 (diff) |
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
-rw-r--r-- | 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 95671412296..9783e6170b8 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 |