summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2010-10-01 12:15:48 -0700
committerEric Anholt <[email protected]>2010-10-01 12:21:51 -0700
commit8f63a44636e4fef2f35fe73f24c27db9b04389b1 (patch)
tree924bc25a9b424a55bcae43475ecf3008722a9494 /src
parentff5ce9289b5159e7de34706b31be771d3e3cefd6 (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
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp72
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