i965/fs: Move texel offset handling to visit(ir_texture *).
authorKenneth Graunke <kenneth@whitecape.org>
Mon, 1 Sep 2014 08:58:06 +0000 (01:58 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 16 Oct 2014 00:04:45 +0000 (17:04 -0700)
This moves the handling of non-constant texel offset subexpression trees
to the place where we visit other such subtrees.  It also removes some
uses of ir->offset in emit_texture_gen7, which will be useful when we
write the backend for our new upcoming IR.

Based on a patch by Connor Abbott.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_fs_fp.cpp
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp

index 943e6387b8eae55794ca4390cf224a491a7149dc..bba8d08ca89ae0f0201a9d78bf116361930d3471 100644 (file)
@@ -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);
index 9f0c0c7ac48f30f4f874d66fa7635a631d98e41d..fb24c5897c27978f77e84b965757c7304573a774 100644 (file)
@@ -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 {
index 163d6423d9e7c819de5de319a0291998ce8b271a..e4b87bbd5da5741208b049b1a20cfc361a1aa6bc 100644 (file)
@@ -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