From 82bfb4b41af7d61aa45e41d62c1842b6a09e9585 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Sat, 4 Aug 2012 20:33:13 -0700 Subject: [PATCH] i965/fs: Move message header and texture offset setup to generate_tex(). Setting the texture offset bits in the message header involves very specific hardware register descriptions. As such, I feel it's better suited for the lower level "generate" layer that has direct access to the weird register layouts, rather than at the fs_inst abstraction layer. This also parallels the approach I took in the VS backend. Signed-off-by: Kenneth Graunke Reviewed-by: Eric Anholt --- src/mesa/drivers/dri/i965/brw_fs.h | 1 + src/mesa/drivers/dri/i965/brw_fs_emit.cpp | 21 ++++++++++++++++ src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 26 ++++---------------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 031d5414ba1..246dcf0f4e4 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -164,6 +164,7 @@ public: int mlen; /**< SEND message length */ int base_mrf; /**< First MRF in the SEND message, if mlen is nonzero. */ + uint32_t texture_offset; /**< Texture offset bitfield */ int sampler; int target; /**< MRT target. */ bool eot; diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp index dc5f3e16134..0bd056d5c1a 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp @@ -381,6 +381,27 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src) dst = vec16(dst); } + /* Load the message header if present. If there's a texture offset, + * we need to set it up explicitly and load the offset bitfield. + * Otherwise, we can use an implied move from g0 to the first message reg. + */ + if (inst->texture_offset) { + brw_push_insn_state(p); + brw_set_compression_control(p, BRW_COMPRESSION_NONE); + /* Explicitly set up the message header by copying g0 to the MRF. */ + brw_MOV(p, retype(brw_message_reg(inst->base_mrf), BRW_REGISTER_TYPE_UD), + retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD)); + + /* Then set the offset bits in DWord 2. */ + brw_MOV(p, retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, + inst->base_mrf, 2), BRW_REGISTER_TYPE_UD), + brw_imm_ud(inst->texture_offset)); + brw_pop_insn_state(p); + } else if (inst->header_present) { + /* Set up an implied move from g0 to the MRF. */ + src = retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW); + } + brw_SAMPLE(p, retype(dst, BRW_REGISTER_TYPE_UW), inst->base_mrf, diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index fefe2c7d15d..08b7fb887aa 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -1167,20 +1167,6 @@ fs_visitor::visit(ir_texture *ir) ir->coordinate->accept(this); fs_reg coordinate = this->result; - if (ir->offset != NULL && !(intel->gen == 7 && ir->op == ir_txf)) { - uint32_t offset_bits = brw_texture_offset(ir->offset->as_constant()); - - /* Explicitly set up the message header by copying g0 to msg reg m1. */ - emit(BRW_OPCODE_MOV, fs_reg(MRF, 1, BRW_REGISTER_TYPE_UD), - fs_reg(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD))); - - /* Then set the offset bits in DWord 2 of the message header. */ - emit(BRW_OPCODE_MOV, - fs_reg(retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, 1, 2), - BRW_REGISTER_TYPE_UD)), - fs_reg(brw_imm_uw(offset_bits))); - } - /* Should be lowered by do_lower_texture_projection */ assert(!ir->projector); @@ -1297,13 +1283,11 @@ fs_visitor::visit(ir_texture *ir) inst = emit_texture_gen4(ir, dst, coordinate, sampler); } - /* If there's an offset, we already set up m1. To avoid the implied move, - * use the null register. Otherwise, we want an implied move from g0. - */ - if (ir->offset != NULL || !inst->header_present) - inst->src[0] = reg_undef; - else - inst->src[0] = fs_reg(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW)); + /* The header is set up by generate_tex() when necessary. */ + inst->src[0] = reg_undef; + + if (ir->offset != NULL && ir->op != ir_txf) + inst->texture_offset = brw_texture_offset(ir->offset->as_constant()); inst->sampler = sampler; -- 2.30.2