From ff6e3c73f6553cd29b915497b5b00e3ef158a27d Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Fri, 29 Apr 2011 14:19:04 -0700 Subject: [PATCH] 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 Reviewed-by: Eric Anholt --- src/mesa/drivers/dri/i965/brw_fs.cpp | 68 ++++++++++++++++++++++++++-- src/mesa/drivers/dri/i965/brw_fs.h | 1 + 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); -- 2.30.2