summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2011-04-29 14:19:04 -0700
committerKenneth Graunke <[email protected]>2011-05-17 23:33:01 -0700
commitff6e3c73f6553cd29b915497b5b00e3ef158a27d (patch)
tree71ad60668df2889b9d14f797a9a2ef638ca91b1c
parent36f8de02e71ee5c2ca55d86c486eb00d043ae1f5 (diff)
i965: Add support for Ivybridge texturing messages.
Ivybridge puts the shadow comparator first, then lod/bias, and finally the coordinate---unlike previous generations which always reserved four slots for the coordinate at the beginning. Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Eric Anholt <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp68
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h1
2 files changed, 66 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 994f65a8c32..30e771aea4e 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1358,6 +1358,66 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate)
return inst;
}
+fs_inst *
+fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate)
+{
+ int mlen = 1; /* g0 header always present. */
+ int base_mrf = 1;
+ int reg_width = c->dispatch_width / 8;
+
+ if (ir->shadow_comparitor) {
+ ir->shadow_comparitor->accept(this);
+ emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
+ mlen += reg_width;
+ }
+
+ /* Set up the LOD info */
+ switch (ir->op) {
+ case ir_tex:
+ break;
+ case ir_txb:
+ ir->lod_info.bias->accept(this);
+ emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
+ mlen += reg_width;
+ break;
+ case ir_txl:
+ ir->lod_info.lod->accept(this);
+ emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
+ mlen += reg_width;
+ break;
+ case ir_txd:
+ case ir_txf:
+ assert(!"GLSL 1.30 features unsupported");
+ break;
+ }
+
+ /* Set up the coordinate */
+ for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
+ emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen),
+ coordinate);
+ coordinate.reg_offset++;
+ mlen += reg_width;
+ }
+
+ /* Generate the SEND */
+ fs_inst *inst = NULL;
+ switch (ir->op) {
+ case ir_tex: inst = emit(FS_OPCODE_TEX, dst); break;
+ case ir_txb: inst = emit(FS_OPCODE_TXB, dst); break;
+ case ir_txl: inst = emit(FS_OPCODE_TXL, dst); break;
+ case ir_txd: inst = emit(FS_OPCODE_TXD, dst); break;
+ case ir_txf: assert(!"TXF unsupported.");
+ }
+ inst->base_mrf = base_mrf;
+ inst->mlen = mlen;
+
+ if (mlen > 11) {
+ fail("Message length >11 disallowed by hardware\n");
+ }
+
+ return inst;
+}
+
void
fs_visitor::visit(ir_texture *ir)
{
@@ -1458,10 +1518,12 @@ fs_visitor::visit(ir_texture *ir)
*/
fs_reg dst = fs_reg(this, glsl_type::vec4_type);
- if (intel->gen < 5) {
- inst = emit_texture_gen4(ir, dst, coordinate);
- } else {
+ if (intel->gen >= 7) {
+ inst = emit_texture_gen7(ir, dst, coordinate);
+ } else if (intel->gen >= 5) {
inst = emit_texture_gen5(ir, dst, coordinate);
+ } else {
+ inst = emit_texture_gen4(ir, dst, coordinate);
}
/* If there's an offset, we already set up m1. To avoid the implied move,
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 518d09180c4..154ce7fdafb 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -516,6 +516,7 @@ public:
void emit_interpolation_setup_gen6();
fs_inst *emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate);
fs_inst *emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate);
+ fs_inst *emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate);
fs_inst *emit_math(fs_opcodes op, fs_reg dst, fs_reg src0);
fs_inst *emit_math(fs_opcodes op, fs_reg dst, fs_reg src0, fs_reg src1);
bool try_emit_saturate(ir_expression *ir);