summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-03-23 16:29:31 -0700
committerIan Romanick <ian.d.romanick@intel.com>2009-03-26 15:15:51 -0700
commit1db913f687146c29b9af4bdc472729ffdc03383c (patch)
tree803d5e364aa60c35c17c56af8edaf19fc53851f7
parent0e5d1f43af953ee344777ce67a2e87544f481302 (diff)
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)
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf_emit.c32
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h3
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_debug.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c32
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c11
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c33
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass1.c1
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 ffdb0ae6df8..862835f157a 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 655358b1c82..c6791da73fa 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 13e4ebf8b6c..3cbdf815357 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 8f07f89ebc5..220821087c1 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 b5050a3e40b..bc8e8c97082 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 3b2883d1e7d..7ebe5b9d77b 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 11f592d1b88..5a5497e1b31 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 f6f3a38e9e0..a1fea6f4b25 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;
}