Mesa (7.9): i915: Only mark a register as available if all components are written

Ian Romanick idr at kemper.freedesktop.org
Tue Mar 1 21:26:34 UTC 2011


Module: Mesa
Branch: 7.9
Commit: 38c93ba9211cba0634379f8c5a18000fe84cfebc
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=38c93ba9211cba0634379f8c5a18000fe84cfebc

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Tue Feb  1 13:35:36 2011 -0800

i915: Only mark a register as available if all components are written

Previously a register would be marked as available if any component
was written.  This caused shaders such as this:

  0: TEX TEMP[0].xyz, INPUT[14].xyyy, texture[0], 2D;
  1: MUL TEMP[1], UNIFORM[0], TEMP[0].xxxx;
  2: MAD TEMP[2], UNIFORM[1], TEMP[0].yyyy, TEMP[1];
  3: MAD TEMP[1], UNIFORM[2], TEMP[0].zzzz, TEMP[2];
  4: ADD TEMP[0].xyz, TEMP[1].xyzx, UNIFORM[3].xyzx;
  5: TEX TEMP[1].w, INPUT[14].xyyy, texture[0], 2D;
  6: MOV TEMP[0].w, TEMP[1].wwww;
  7: MOV OUTPUT[2], TEMP[0];
  8: END

to produce incorrect code such as this:

  BEGIN
  DCL S[0]
  DCL T_TEX0
  R[0] = MOV T_TEX0.xyyy
  U[0] = TEXLD S[0],R[0]
  R[0].xyz = MOV U[0]
  R[1] = MUL CONST[0], R[0].xxxx
  R[2] = MAD CONST[1], R[0].yyyy, R[1]
  R[1] = MAD CONST[2], R[0].zzzz, R[2]
  R[0].xyz = ADD R[1].xyzx, CONST[3].xyzx
  R[0] = MOV T_TEX0.xyyy
  U[0] = TEXLD S[0],R[0]
  R[1].w = MOV U[0]
  R[0].w = MOV R[1].wwww
  oC = MOV R[0]
  END

Note that T_TEX0 is copied to R[0], but the xyz components of R[0] are
still expected to hold a calculated value.

Fixes piglit tests draw-elements-vs-inputs, fp-kill, and
glsl-fs-color-matrix.  It also fixes Meego bugzilla #13005.

NOTE: This is a candidate for the 7.9 and 7.10 branches.
(cherry picked from commit a04582739e77b58cea9e2aa523109e878bf90b6a)

---

 src/mesa/drivers/dri/i915/i915_fragprog.c |   20 +++++++++++++++++---
 1 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index 4027c5f..5e21918 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -306,6 +306,7 @@ static void calc_live_regs( struct i915_fragment_program *p )
 {
     const struct gl_fragment_program *program = p->ctx->FragmentProgram._Current;
     GLuint regsUsed = 0xffff0000;
+    uint8_t live_components[16] = { 0, };
     GLint i;
    
     for (i = program->Base.NumInstructions - 1; i >= 0; i--) {
@@ -314,13 +315,26 @@ static void calc_live_regs( struct i915_fragment_program *p )
         int a;
 
         /* Register is written to: unmark as live for this and preceeding ops */ 
-        if (inst->DstReg.File == PROGRAM_TEMPORARY)
-            regsUsed &= ~(1 << inst->DstReg.Index);
+        if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+            live_components[inst->DstReg.Index] &= ~inst->DstReg.WriteMask;
+            if (live_components[inst->DstReg.Index] == 0)
+                regsUsed &= ~(1 << inst->DstReg.Index);
+        }
 
         for (a = 0; a < opArgs; a++) {
             /* Register is read from: mark as live for this and preceeding ops */ 
-            if (inst->SrcReg[a].File == PROGRAM_TEMPORARY)
+            if (inst->SrcReg[a].File == PROGRAM_TEMPORARY) {
+                unsigned c;
+
                 regsUsed |= 1 << inst->SrcReg[a].Index;
+
+                for (c = 0; c < 4; c++) {
+                    const unsigned field = GET_SWZ(inst->SrcReg[a].Swizzle, c);
+
+                    if (field <= SWIZZLE_W)
+                        live_components[inst->SrcReg[a].Index] |= (1U << field);
+                }
+            }
         }
 
         p->usedRegs[i] = regsUsed;




More information about the mesa-commit mailing list