Mesa (mesa_7_4_branch): i965: Fix glFrontFacing in twoside GLSL demo.

Ian Romanick idr at kemper.freedesktop.org
Thu Mar 26 22:32:55 UTC 2009


Module: Mesa
Branch: mesa_7_4_branch
Commit: 1db913f687146c29b9af4bdc472729ffdc03383c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1db913f687146c29b9af4bdc472729ffdc03383c

Author: Eric Anholt <eric at anholt.net>
Date:   Mon Mar 23 16:29:31 2009 -0700

i965: Fix glFrontFacing in twoside GLSL demo.

This also cuts instructions by just using the existing bit in the payload
rather than computing it from the determinant in the SF unit and passing it
as a varying down to the WM.  Something still goes wrong with getting the
backface color right, but a simpler shader appears to get the right result.
(cherry picked from commit 699db6d842c52d0b3b98b320f8ef1104a65fa783)

---

 src/mesa/drivers/dri/i965/brw_sf_emit.c  |   32 -----------------------------
 src/mesa/drivers/dri/i965/brw_wm.c       |    2 +
 src/mesa/drivers/dri/i965/brw_wm.h       |    3 +-
 src/mesa/drivers/dri/i965/brw_wm_debug.c |    3 ++
 src/mesa/drivers/dri/i965/brw_wm_emit.c  |   32 +++++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_wm_fp.c    |   11 +++++----
 src/mesa/drivers/dri/i965/brw_wm_glsl.c  |   33 ++++++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_wm_pass1.c |    1 +
 8 files changed, 79 insertions(+), 38 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c
index ffdb0ae..862835f 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c
@@ -59,37 +59,6 @@ static GLboolean have_attr(struct brw_sf_compile *c,
    return (c->key.attrs & (1<<attr)) ? 1 : 0;
 }
 
-/**
- * Sets VERT_RESULT_FOGC.Y  for gl_FrontFacing
- *
- * This is currently executed if the fragment program uses VERT_RESULT_FOGC
- * at all, but this could be eliminated with a scan of the FP contents.
- */
-static void
-do_front_facing( struct brw_sf_compile *c )
-{
-   struct brw_compile *p = &c->func; 
-   int i;
-
-   if (!have_attr(c, VERT_RESULT_FOGC))
-      return;
-
-   brw_push_insn_state(p);
-   brw_CMP(p, brw_null_reg(), 
-        c->key.frontface_ccw ? BRW_CONDITIONAL_G : BRW_CONDITIONAL_L,
-        c->det, brw_imm_f(0));
-   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
-   for (i = 0; i < 3; i++) {
-       struct brw_reg fogc = get_vert_attr(c, c->vert[i],FRAG_ATTRIB_FOGC);
-       brw_MOV(p, get_element(fogc, 1), brw_imm_f(0));
-       brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
-       brw_MOV(p, get_element(fogc, 1), brw_imm_f(1));
-       brw_set_predicate_control(p, BRW_PREDICATE_NONE);
-   }
-   brw_pop_insn_state(p);
-}
-
-			 
 /*********************************************************************** 
  * Twoside lighting
  */
@@ -384,7 +353,6 @@ void brw_emit_tri_setup( struct brw_sf_compile *c, GLboolean allocate)
 
    invert_det(c);
    copy_z_inv_w(c);
-   do_front_facing(c);
 
    if (c->key.do_twoside_color) 
       do_twoside_color(c);
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 655358b..c6791da 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -40,6 +40,8 @@
 GLuint brw_wm_nr_args( GLuint opcode )
 {
    switch (opcode) {
+   case WM_FRONTFACING:
+      return 0;
    case WM_PIXELXY:
    case WM_CINTERP:
    case WM_WPOSXY:
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index 13e4ebf..3cbdf81 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -172,7 +172,8 @@ struct brw_wm_instruction {
 #define WM_CINTERP        (MAX_OPCODE + 5)
 #define WM_WPOSXY         (MAX_OPCODE + 6)
 #define WM_FB_WRITE       (MAX_OPCODE + 7)
-#define MAX_WM_OPCODE     (MAX_OPCODE + 8)
+#define WM_FRONTFACING    (MAX_OPCODE + 8)
+#define MAX_WM_OPCODE     (MAX_OPCODE + 9)
 
 #define PROGRAM_PAYLOAD   (PROGRAM_FILE_MAX)
 #define PAYLOAD_DEPTH     (FRAG_ATTRIB_MAX)
diff --git a/src/mesa/drivers/dri/i965/brw_wm_debug.c b/src/mesa/drivers/dri/i965/brw_wm_debug.c
index 8f07f89..2208210 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_debug.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_debug.c
@@ -130,6 +130,9 @@ void brw_wm_print_insn( struct brw_wm_compile *c,
    case WM_FB_WRITE:
       _mesa_printf(" = FB_WRITE");
       break;
+   case WM_FRONTFACING:
+      _mesa_printf(" = FRONTFACING");
+      break;
    default:
       _mesa_printf(" = %s", _mesa_opcode_string(inst->opcode));
       break;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index b5050a3..bc8e8c9 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -254,6 +254,34 @@ static void emit_cinterp( struct brw_compile *p,
    }
 }
 
+/* Sets the destination channels to 1.0 or 0.0 according to glFrontFacing. */
+static void emit_frontfacing( struct brw_compile *p,
+			      const struct brw_reg *dst,
+			      GLuint mask )
+{
+   struct brw_reg r1_6ud = retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_UD);
+   GLuint i;
+
+   if (!(mask & WRITEMASK_XYZW))
+      return;
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {
+	 brw_MOV(p, dst[i], brw_imm_f(0.0));
+      }
+   }
+
+   /* bit 31 is "primitive is back face", so checking < (1 << 31) gives
+    * us front face
+    */
+   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, r1_6ud, brw_imm_ud(1 << 31));
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {
+	 brw_MOV(p, dst[i], brw_imm_f(1.0));
+      }
+   }
+   brw_set_predicate_control_flag_value(p, 0xff);
+}
 
 static void emit_alu1( struct brw_compile *p, 
 		       struct brw_instruction *(*func)(struct brw_compile *, 
@@ -1158,6 +1186,10 @@ void brw_wm_emit( struct brw_wm_compile *c )
 	 emit_fb_write(c, args[0], args[1], args[2], inst->target, inst->eot);
 	 break;
 
+      case WM_FRONTFACING:
+	 emit_frontfacing(p, dst, dst_flags);
+	 break;
+
 	 /* Straightforward arithmetic:
 	  */
       case OPCODE_ADD:
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index 3b2883d..7ebe5b9 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -58,7 +58,8 @@ static const char *wm_opcode_strings[] = {
    "PINTERP",
    "CINTERP",
    "WPOSXY",
-   "FB_WRITE"
+   "FB_WRITE",
+   "FRONTFACING",
 };
 
 #if 0
@@ -377,12 +378,12 @@ static void emit_interp( struct brw_wm_compile *c,
       /* Move the front facing value into FOGC.y if it's needed. */
       if (c->fp->program.UsesFrontFacing) {
 	 emit_op(c,
-		 WM_PINTERP,
+		 WM_FRONTFACING,
 		 dst_mask(dst, WRITEMASK_Y),
 		 0,
-		 interp,
-		 deltas,
-		 get_pixel_w(c));
+		 src_undef(),
+		 src_undef(),
+		 src_undef());
       } else {
 	 emit_op(c,
 		 OPCODE_MOV,
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 11f592d..5a5497e 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -564,6 +564,36 @@ static void emit_pinterp(struct brw_wm_compile *c,
     }
 }
 
+/* Sets the destination channels to 1.0 or 0.0 according to glFrontFacing. */
+static void emit_frontfacing(struct brw_wm_compile *c,
+			     struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg r1_6ud = retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_UD);
+    struct brw_reg dst;
+    GLuint mask = inst->DstReg.WriteMask;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    brw_MOV(p, dst, brw_imm_f(0.0));
+	}
+    }
+
+    /* bit 31 is "primitive is back face", so checking < (1 << 31) gives
+     * us front face
+     */
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, r1_6ud, brw_imm_ud(1 << 31));
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    brw_MOV(p, dst, brw_imm_f(1.0));
+	}
+    }
+    brw_set_predicate_control_flag_value(p, 0xff);
+}
+
 static void emit_xpd(struct brw_wm_compile *c,
 		struct prog_instruction *inst)
 {
@@ -2342,6 +2372,9 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
 	    case WM_FB_WRITE:
 		emit_fb_write(c, inst);
 		break;
+	    case WM_FRONTFACING:
+		emit_frontfacing(c, inst);
+		break;
 	    case OPCODE_ABS:
 		emit_abs(c, inst);
 		break;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass1.c b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
index f6f3a38..a1fea6f 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass1.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
@@ -260,6 +260,7 @@ void brw_wm_pass1( struct brw_wm_compile *c )
 
       case OPCODE_DST:
       case OPCODE_TXP:
+      case WM_FRONTFACING:
       default:
 	 break;
       }




More information about the mesa-commit mailing list