diff options
author | Kenneth Graunke <kenneth@whitecape.org> | 2010-12-27 03:21:23 -0800 |
---|---|---|
committer | Kenneth Graunke <kenneth@whitecape.org> | 2011-01-31 11:10:59 -0800 |
commit | 0f7325b89038937bd428f7c89ed9859189a0ab0b (patch) | |
tree | 491296efefc58a103babfa7c1bf6af3494b7ef5f /src/mesa/drivers/dri/i965 | |
parent | ca418cbde6377dd723c857582db2f8f3725ffdea (diff) |
i965: Emit texel offsets in sampler messages.
Diffstat (limited to 'src/mesa/drivers/dri/i965')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.cpp | 45 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.h | 2 |
2 files changed, 43 insertions, 4 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index c64a4c00c5..8fd120cb65 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -1337,6 +1337,37 @@ fs_visitor::visit(ir_texture *ir) ir->coordinate->accept(this); fs_reg coordinate = this->result; + if (ir->offset != NULL) { + ir_constant *offset = ir->offset->as_constant(); + assert(offset != NULL); + + signed char offsets[3]; + for (unsigned i = 0; i < ir->offset->type->vector_elements; i++) + offsets[i] = (signed char) offset->value.i[i]; + + /* Combine all three offsets into a single unsigned dword: + * + * bits 11:8 - U Offset (X component) + * bits 7:4 - V Offset (Y component) + * bits 3:0 - R Offset (Z component) + */ + unsigned offset_bits = 0; + for (unsigned i = 0; i < ir->offset->type->vector_elements; i++) { + const unsigned shift = 4 * (2 - i); + offset_bits |= (offsets[i] << shift) & (0xF << shift); + } + + /* Explicitly set up the message header by copying g0 to msg reg m1. */ + emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, 1, BRW_REGISTER_TYPE_UD), + fs_reg(GRF, 0, BRW_REGISTER_TYPE_UD))); + + /* Then set the offset bits in DWord 2 of the message header. */ + emit(fs_inst(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); @@ -1397,6 +1428,14 @@ fs_visitor::visit(ir_texture *ir) inst = emit_texture_gen5(ir, dst, coordinate); } + /* 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->src[0] = fs_reg(brw_null_reg()); + else + inst->src[0] = fs_reg(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW)); + inst->sampler = sampler; this->result = dst; @@ -2243,7 +2282,7 @@ fs_visitor::generate_math(fs_inst *inst, } void -fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst) +fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src) { int msg_type = -1; int rlen = 4; @@ -2301,7 +2340,7 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst) brw_SAMPLE(p, retype(dst, BRW_REGISTER_TYPE_UW), inst->base_mrf, - retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW), + src, SURF_INDEX_TEXTURE(inst->sampler), inst->sampler, WRITEMASK_XYZW, @@ -3539,7 +3578,7 @@ fs_visitor::generate_code() case FS_OPCODE_TEX: case FS_OPCODE_TXB: case FS_OPCODE_TXL: - generate_tex(inst, dst); + generate_tex(inst, dst, src[0]); break; case FS_OPCODE_DISCARD_NOT: generate_discard_not(inst, dst); diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 59a17f7f3b..8352760acf 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -453,7 +453,7 @@ public: void generate_fb_write(fs_inst *inst); void generate_linterp(fs_inst *inst, struct brw_reg dst, struct brw_reg *src); - void generate_tex(fs_inst *inst, struct brw_reg dst); + void generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src); void generate_math(fs_inst *inst, struct brw_reg dst, struct brw_reg *src); void generate_discard_not(fs_inst *inst, struct brw_reg temp); void generate_discard_and(fs_inst *inst, struct brw_reg temp); |