summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h3
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_fp.cpp3
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp34
3 files changed, 29 insertions, 11 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 943e6387b8e..bba8d08ca89 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -478,7 +478,8 @@ public:
fs_reg sample_index, uint32_t sampler);
fs_inst *emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
fs_reg shadow_comp, fs_reg lod, fs_reg lod2,
- fs_reg sample_index, fs_reg mcs, fs_reg sampler);
+ fs_reg sample_index, fs_reg mcs, fs_reg sampler,
+ fs_reg offset_value);
fs_reg emit_mcs_fetch(ir_texture *ir, fs_reg coordinate, fs_reg sampler);
void emit_gen6_gather_wa(uint8_t wa, fs_reg dst);
fs_reg fix_math_operand(fs_reg src);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_fp.cpp b/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
index 9f0c0c7ac48..fb24c5897c2 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
@@ -404,6 +404,7 @@ fs_visitor::emit_fragment_program_code()
fs_reg coordinate = src[0];
fs_reg shadow_c;
fs_reg sample_index;
+ fs_reg texel_offset; /* No offsets; leave as BAD_FILE. */
switch (fpi->Opcode) {
case OPCODE_TEX:
@@ -487,7 +488,7 @@ fs_visitor::emit_fragment_program_code()
fs_inst *inst;
if (brw->gen >= 7) {
- inst = emit_texture_gen7(ir, dst, coordinate, shadow_c, lod, dpdy, sample_index, fs_reg(0u), fs_reg(fpi->TexSrcUnit));
+ inst = emit_texture_gen7(ir, dst, coordinate, shadow_c, lod, dpdy, sample_index, fs_reg(0u), fs_reg(fpi->TexSrcUnit), texel_offset);
} else if (brw->gen >= 5) {
inst = emit_texture_gen5(ir, dst, coordinate, shadow_c, lod, dpdy, sample_index, fpi->TexSrcUnit);
} else {
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 163d6423d9e..e4b87bbd5da 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -1481,7 +1481,8 @@ is_high_sampler(struct brw_context *brw, fs_reg sampler)
fs_inst *
fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
fs_reg shadow_c, fs_reg lod, fs_reg lod2,
- fs_reg sample_index, fs_reg mcs, fs_reg sampler)
+ fs_reg sample_index, fs_reg mcs, fs_reg sampler,
+ fs_reg offset_value)
{
int reg_width = dispatch_width / 8;
bool header_present = false;
@@ -1492,7 +1493,8 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
}
int length = 0;
- if (ir->op == ir_tg4 || ir->offset || is_high_sampler(brw, sampler)) {
+ if (ir->op == ir_tg4 || offset_value.file != BAD_FILE ||
+ is_high_sampler(brw, sampler)) {
/* For general texture offsets (no txf workaround), we need a header to
* put them in. Note that for SIMD16 we're making space for two actual
* hardware registers here, so the emit will have to fix up for this.
@@ -1513,7 +1515,8 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
length++;
}
- bool has_nonconstant_offset = ir->offset && !ir->offset->as_constant();
+ bool has_nonconstant_offset =
+ offset_value.file != BAD_FILE && offset_value.file != IMM;
bool coordinate_done = false;
/* Set up the LOD info */
@@ -1607,9 +1610,6 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
no16("Gen7 does not support gather4_po_c in SIMD16 mode.");
/* More crazy intermixing */
- ir->offset->accept(this);
- fs_reg offset_value = this->result;
-
for (int i = 0; i < 2; i++) { /* u, v */
emit(MOV(sources[length], coordinate));
coordinate = offset(coordinate, 1);
@@ -1935,6 +1935,21 @@ fs_visitor::visit(ir_texture *ir)
shadow_comparitor = this->result;
}
+ fs_reg offset_value;
+ if (ir->offset) {
+ ir_constant *const_offset = ir->offset->as_constant();
+ if (const_offset) {
+ /* Store the header bitfield in an IMM register. This allows us to
+ * use offset_value.file to distinguish between no offset, a constant
+ * offset, and a non-constant offset.
+ */
+ offset_value = fs_reg(brw_texture_offset(ctx, const_offset));
+ } else {
+ ir->offset->accept(this);
+ offset_value = this->result;
+ }
+ }
+
fs_reg lod, lod2, sample_index, mcs;
switch (ir->op) {
case ir_tex:
@@ -1979,7 +1994,8 @@ fs_visitor::visit(ir_texture *ir)
if (brw->gen >= 7) {
inst = emit_texture_gen7(ir, dst, coordinate, shadow_comparitor,
- lod, lod2, sample_index, mcs, sampler_reg);
+ lod, lod2, sample_index, mcs, sampler_reg,
+ offset_value);
} else if (brw->gen >= 5) {
inst = emit_texture_gen5(ir, dst, coordinate, shadow_comparitor,
lod, lod2, sample_index, sampler);
@@ -1988,8 +2004,8 @@ fs_visitor::visit(ir_texture *ir)
lod, lod2, sampler);
}
- if (ir->offset != NULL)
- inst->texture_offset = brw_texture_offset(ctx, ir->offset->as_constant());
+ if (offset_value.file == IMM)
+ inst->texture_offset = offset_value.fixed_hw_reg.dw1.ud;
if (ir->op == ir_tg4)
inst->texture_offset |= gather_channel(ir, sampler) << 16; // M0.2:16-17