Mesa (master): i915: Refine the texture indirect lookup accounting.

Eric Anholt anholt at kemper.freedesktop.org
Sun Oct 5 01:43:48 UTC 2008


Module: Mesa
Branch: master
Commit: 91d0020eecb78ef2984fd0afafc5d555c0e957d8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=91d0020eecb78ef2984fd0afafc5d555c0e957d8

Author: Eric Anholt <eric at anholt.net>
Date:   Sat Oct  4 18:20:35 2008 -0700

i915: Refine the texture indirect lookup accounting.

Without this, we would reject programs which sampled multiple times from
registers defined in the same phase (block of instructions with the same
texture indirection count), as each sample would count as a new phase
beginning.  Instead, keep track of which phases registers were written in,
and only bump phase when we're reading from one generated in this phase.

On the other hand, we failed to count oC or oD texture samples as being new
phases.

Bug #17865.

---

 src/mesa/drivers/dri/i915/i915_context.h |    3 +++
 src/mesa/drivers/dri/i915/i915_program.c |   25 ++++++++++++++++++++++---
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h
index c6958dd..a2376e5 100644
--- a/src/mesa/drivers/dri/i915/i915_context.h
+++ b/src/mesa/drivers/dri/i915/i915_context.h
@@ -125,6 +125,9 @@ struct i915_fragment_program
    GLboolean on_hardware;
    GLboolean error;             /* If program is malformed for any reason. */
 
+   /** Record of which phases R registers were last written in. */
+   GLuint register_phases[16];
+   GLuint indirections;
    GLuint nr_tex_indirect;
    GLuint nr_tex_insn;
    GLuint nr_alu_insn;
diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c
index 4919329..350da5e 100644
--- a/src/mesa/drivers/dri/i915/i915_program.c
+++ b/src/mesa/drivers/dri/i915/i915_program.c
@@ -190,6 +190,9 @@ i915_emit_arith(struct i915_fragment_program * p,
    *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1));
    *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2));
 
+   if (GET_UREG_TYPE(dest) == REG_TYPE_R)
+      p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
+
    p->nr_alu_insn++;
    return dest;
 }
@@ -237,10 +240,22 @@ GLuint i915_emit_texld( struct i915_fragment_program *p,
    else {
       assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
       assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
+      /* Can't use unsaved temps for coords, as the phase boundary would result
+       * in the contents becoming undefined.
+       */
+      assert(GET_UREG_TYPE(coord) != REG_TYPE_U);
+
+      /* Output register being oC or oD defines a phase boundary */
+      if (GET_UREG_TYPE(dest) == REG_TYPE_OC ||
+	  GET_UREG_TYPE(dest) == REG_TYPE_OD)
+	 p->nr_tex_indirect++;
 
-      if (GET_UREG_TYPE(coord) != REG_TYPE_T) {
+      /* Reading from an r# register whose contents depend on output of the
+       * current phase defines a phase boundary.
+       */
+      if (GET_UREG_TYPE(coord) == REG_TYPE_R &&
+	  p->register_phases[GET_UREG_NR(coord)] == p->nr_tex_indirect)
 	 p->nr_tex_indirect++;
-      }
 
       *(p->csr++) = (op | 
 		     T0_DEST( dest ) |
@@ -249,6 +264,9 @@ GLuint i915_emit_texld( struct i915_fragment_program *p,
       *(p->csr++) = T1_ADDRESS_REG( coord );
       *(p->csr++) = T2_MBZ;
 
+      if (GET_UREG_TYPE(dest) == REG_TYPE_R)
+	 p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
+
       p->nr_tex_insn++;
       return dest;
    }
@@ -413,7 +431,8 @@ i915_init_program(struct i915_context *i915, struct i915_fragment_program *p)
    p->on_hardware = 0;
    p->error = 0;
 
-   p->nr_tex_indirect = 1;      /* correct? */
+   memset(&p->register_phases, 0, sizeof(p->register_phases));
+   p->nr_tex_indirect = 1;
    p->nr_tex_insn = 0;
    p->nr_alu_insn = 0;
    p->nr_decl_insn = 0;




More information about the mesa-commit mailing list