summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorChris Forbes <[email protected]>2013-10-08 22:10:34 +1300
committerChris Forbes <[email protected]>2013-10-26 22:08:51 +1300
commit938d9098943c11e4583ad01270ab3c8f10ceb934 (patch)
tree665af4b6a65850b4ce7aa979476aa634b005c045 /src/mesa
parentbdcacaed9c64c49827d325d15ada2c482bfe1578 (diff)
i965/fs: add support for gather4 with nonconstant offsets
V3: fixup crazy check for whether we need to emit the coordinate after custom handling. Signed-off-by: Chris Forbes <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp53
1 files changed, 46 insertions, 7 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 7dabc4767dc..314fe2ab519 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -1251,11 +1251,13 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
next.reg_offset++;
}
+ bool has_nonconstant_offset = ir->offset && !ir->offset->as_constant();
+ bool coordinate_done = false;
+
/* Set up the LOD info */
switch (ir->op) {
case ir_tex:
case ir_lod:
- case ir_tg4:
break;
case ir_txb:
emit(MOV(next, lod));
@@ -1290,6 +1292,8 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
next.reg_offset++;
}
}
+
+ coordinate_done = true;
break;
}
case ir_txs:
@@ -1328,6 +1332,8 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
coordinate.reg_offset++;
next.reg_offset++;
}
+
+ coordinate_done = true;
break;
case ir_txf_ms:
emit(MOV(next.retype(BRW_REGISTER_TYPE_UD), sample_index));
@@ -1348,15 +1354,44 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
coordinate.reg_offset++;
next.reg_offset++;
}
+
+ coordinate_done = true;
+ break;
+ case ir_tg4:
+ if (has_nonconstant_offset) {
+ /* More crazy intermixing */
+ ir->offset->accept(this);
+ fs_reg offset_value = this->result;
+
+ for (int i = 0; i < 2; i++) { /* u, v */
+ emit(MOV(next, coordinate));
+ coordinate.reg_offset++;
+ next.reg_offset++;
+ }
+
+ for (int i = 0; i < 2; i++) { /* offu, offv */
+ emit(MOV(next.retype(BRW_REGISTER_TYPE_D), offset_value));
+ offset_value.reg_offset++;
+ next.reg_offset++;
+ }
+
+ if (ir->coordinate->type->vector_elements == 3) { /* r if present */
+ emit(MOV(next, coordinate));
+ coordinate.reg_offset++;
+ next.reg_offset++;
+ }
+
+ coordinate_done = true;
+ }
break;
}
/* Set up the coordinate (except for cases where it was done above) */
- if (ir->op != ir_txd && ir->op != ir_txs && ir->op != ir_txf && ir->op != ir_txf_ms && ir->op != ir_query_levels) {
+ if (ir->coordinate && !coordinate_done) {
for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
- emit(MOV(next, coordinate));
- coordinate.reg_offset++;
- next.reg_offset++;
+ emit(MOV(next, coordinate));
+ coordinate.reg_offset++;
+ next.reg_offset++;
}
}
@@ -1372,14 +1407,18 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
case ir_txs: inst = emit(SHADER_OPCODE_TXS, dst, payload); break;
case ir_query_levels: inst = emit(SHADER_OPCODE_TXS, dst, payload); break;
case ir_lod: inst = emit(SHADER_OPCODE_LOD, dst, payload); break;
- case ir_tg4: inst = emit(SHADER_OPCODE_TG4, dst, payload); break;
+ case ir_tg4:
+ if (has_nonconstant_offset)
+ inst = emit(SHADER_OPCODE_TG4_OFFSET, dst, payload);
+ else
+ inst = emit(SHADER_OPCODE_TG4, dst, payload);
+ break;
}
inst->base_mrf = -1;
if (reg_width == 2)
inst->mlen = next.reg_offset * reg_width - header_present;
else
inst->mlen = next.reg_offset * reg_width;
-
inst->header_present = header_present;
inst->regs_written = 4;