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.
This commit is contained in:
Eric Anholt
2009-03-23 16:29:31 -07:00
parent 411d913cce
commit 699db6d842
8 changed files with 79 additions and 38 deletions
-32
View File
@@ -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);
+2
View File
@@ -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:
+2 -1
View File
@@ -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)
+3
View File
@@ -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;
+32
View File
@@ -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 *,
@@ -1160,6 +1188,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:
+6 -5
View File
@@ -58,7 +58,8 @@ static const char *wm_opcode_strings[] = {
"PINTERP",
"CINTERP",
"WPOSXY",
"FB_WRITE"
"FB_WRITE",
"FRONTFACING",
};
#if 0
@@ -384,12 +385,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,
+33
View File
@@ -653,6 +653,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)
{
@@ -2435,6 +2465,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;
+1
View File
@@ -268,6 +268,7 @@ void brw_wm_pass1( struct brw_wm_compile *c )
break;
case OPCODE_DST:
case WM_FRONTFACING:
default:
break;
}