diff options
author | Eric Anholt <eric@anholt.net> | 2009-03-23 16:29:31 -0700 |
---|---|---|
committer | Ian Romanick <ian.d.romanick@intel.com> | 2009-03-26 15:15:51 -0700 |
commit | 1db913f687146c29b9af4bdc472729ffdc03383c (patch) | |
tree | 803d5e364aa60c35c17c56af8edaf19fc53851f7 | |
parent | 0e5d1f43af953ee344777ce67a2e87544f481302 (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.c | 32 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm.h | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_debug.c | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_emit.c | 32 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_fp.c | 11 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_glsl.c | 33 | ||||
-rw-r--r-- | 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 ffdb0ae6df..862835f157 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 655358b1c8..c6791da73f 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 13e4ebf8b6..3cbdf81535 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 8f07f89ebc..220821087c 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 b5050a3e40..bc8e8c9708 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 3b2883d1e7..7ebe5b9d77 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 11f592d1b8..5a5497e1b3 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 f6f3a38e9e..a1fea6f4b2 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; } |