Mesa (7.9): i965: Make OPCODE_KIL_NV do its work in a temp, not the null reg!

Ian Romanick idr at kemper.freedesktop.org
Fri Feb 4 19:41:32 UTC 2011


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

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Fri Feb  4 10:00:18 2011 -0800

i965: Make OPCODE_KIL_NV do its work in a temp, not the null reg!

This is similar to commit 0efea25c in 7.10.  The change was made
directly in the 7.9 branch because the affected code does not exist in
Mesa 7.10 or later.  It was removed with the change to the new
fragment shader back-end.

Fixes the GPU hang in piglit test glsl-fs-discard-03.

---

 docs/relnotes-7.9.2.html                |    2 ++
 src/mesa/drivers/dri/i965/brw_wm.h      |    2 +-
 src/mesa/drivers/dri/i965/brw_wm_emit.c |   10 ++++------
 src/mesa/drivers/dri/i965/brw_wm_glsl.c |   10 +++++++---
 4 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/docs/relnotes-7.9.2.html b/docs/relnotes-7.9.2.html
index 268d35c..a17b2a9 100644
--- a/docs/relnotes-7.9.2.html
+++ b/docs/relnotes-7.9.2.html
@@ -42,6 +42,8 @@ TBD
 <li>Fix incorrect handling of <tt>layout</tt> qualifier
 with <tt>in</tt>, <tt>out</tt>, <tt>attribute</tt>, and <tt>varying</tt>.</li>
 
+<li>Fix an i965 GPU hang in GLSL shaders that contain an unconditional <tt>discard</tt> statement.</li>
+
 <li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=29164">Bug 29164</a> - [GLSL 1.20] invariant variable shouldn't be used before declaration</li>
 
 <li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=31923">Bug 31923</a> - [GLSL 1.20] allowing inconsistent centroid declaration between two vertex shaders</li>
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index ae6a1d5..936e936 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -379,7 +379,7 @@ void emit_fb_write(struct brw_wm_compile *c,
 void emit_frontfacing(struct brw_compile *p,
 		      const struct brw_reg *dst,
 		      GLuint mask);
-void emit_kil_nv(struct brw_wm_compile *c);
+void emit_kil_nv(struct brw_wm_compile *c, struct brw_reg temp);
 void emit_linterp(struct brw_compile *p,
 		  const struct brw_reg *dst,
 		  GLuint mask,
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index 0f9431a..ba9c69c 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -1326,15 +1326,16 @@ static void emit_kil( struct brw_wm_compile *c,
 /* KIL_NV kills the pixels that are currently executing, not based on a test
  * of the arguments.
  */
-void emit_kil_nv( struct brw_wm_compile *c )
+void emit_kil_nv( struct brw_wm_compile *c,
+		  struct brw_reg temp )
 {
    struct brw_compile *p = &c->func;
    struct brw_reg r0uw = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
 
    brw_push_insn_state(p);
    brw_set_mask_control(p, BRW_MASK_DISABLE);
-   brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); /* IMASK */
-   brw_AND(p, r0uw, c->emit_mask_reg, r0uw);
+   brw_NOT(p, temp, brw_mask_reg(1)); /* IMASK */
+   brw_AND(p, r0uw, temp, r0uw);
    brw_pop_insn_state(p);
 }
 
@@ -1897,9 +1898,6 @@ void brw_wm_emit( struct brw_wm_compile *c )
 	 break;
 
       case OPCODE_KIL_NV:
-	 emit_kil_nv(c);
-	 break;
-
       default:
 	 printf("Unsupported opcode %i (%s) in fragment shader\n",
 		inst->opcode, inst->opcode < MAX_OPCODE ?
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 55aceea..d043ac0 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -32,6 +32,7 @@ GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp)
 	    case OPCODE_BRK:
 	    case OPCODE_RET:
 	    case OPCODE_BGNLOOP:
+	    case OPCODE_KIL_NV:
 		return GL_TRUE; 
 	    default:
 		break;
@@ -903,9 +904,12 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
 			 inst->TexSrcTarget,
 			 c->fp->program.Base.SamplerUnits[inst->TexSrcUnit]);
 		break;
-	    case OPCODE_KIL_NV:
-		emit_kil_nv(c);
-		break;
+	    case OPCODE_KIL_NV: {
+	       struct brw_reg temp = get_reg(c, PROGRAM_TEMPORARY, 0, 0, 0,
+					     GL_FALSE, GL_FALSE);
+	       emit_kil_nv(c, brw_vec1_reg(temp.file, temp.nr, temp.subnr));
+	       break;
+	    }
 	    case OPCODE_IF:
 		assert(if_depth < MAX_IF_DEPTH);
 		if_inst[if_depth++] = brw_IF(p, BRW_EXECUTE_8);




More information about the mesa-commit mailing list