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
*/
invert_det(c);
copy_z_inv_w(c);
- do_front_facing(c);
if (c->key.do_twoside_color)
do_twoside_color(c);
GLuint brw_wm_nr_args( GLuint opcode )
{
switch (opcode) {
+ case WM_FRONTFACING:
+ return 0;
case WM_PIXELXY:
case WM_CINTERP:
case WM_WPOSXY:
#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)
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;
}
}
+/* 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 *,
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:
"PINTERP",
"CINTERP",
"WPOSXY",
- "FB_WRITE"
+ "FB_WRITE",
+ "FRONTFACING",
};
#if 0
/* 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,
}
}
+/* 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)
{
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;
break;
case OPCODE_DST:
+ case WM_FRONTFACING:
default:
break;
}