static struct brw_fp_src get_delta_xy( struct brw_wm_compile *c ) { if (src_is_undef(c->fp_delta_xy)) { struct brw_fp_dst delta_xy = get_temp(c); struct brw_fp_src pixel_xy = get_pixel_xy(c); struct brw_fp_src payload_r0_depth = src_reg(BRW_FILE_PAYLOAD, PAYLOAD_DEPTH); /* deltas.xy = DELTAXY pixel_xy, payload[0] */ emit_op3(c, WM_DELTAXY, dst_mask(delta_xy, BRW_WRITEMASK_XY), pixel_xy, payload_r0_depth, src_undef()); c->fp_delta_xy = src_reg_from_dst(delta_xy); } return c->fp_delta_xy; }
static struct prog_src_register get_delta_xy( struct brw_wm_compile *c ) { if (src_is_undef(c->delta_xy)) { struct prog_dst_register delta_xy = get_temp(c); struct prog_src_register pixel_xy = get_pixel_xy(c); struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH); /* deltas.xy = DELTAXY pixel_xy, payload[0] */ emit_op(c, WM_DELTAXY, dst_mask(delta_xy, WRITEMASK_XY), 0, pixel_xy, payload_r0_depth, src_undef()); c->delta_xy = src_reg_from_dst(delta_xy); } return c->delta_xy; }
static void emit_interp( struct brw_wm_compile *c, GLuint idx, GLuint semantic, GLuint interp_mode ) { struct brw_fp_dst dst = dst_reg(TGSI_FILE_INPUT, idx); struct brw_fp_src interp = src_reg(BRW_FILE_PAYLOAD, idx); struct brw_fp_src deltas = get_delta_xy(c); /* Need to use PINTERP on attributes which have been * multiplied by 1/W in the SF program, and LINTERP on those * which have not: */ switch (semantic) { case TGSI_SEMANTIC_POSITION: /* Have to treat wpos.xy specially: */ emit_op1(c, WM_WPOSXY, dst_mask(dst, BRW_WRITEMASK_XY), get_pixel_xy(c)); /* TGSI_FILE_INPUT.attr.xyzw = INTERP payload.interp[attr].x, deltas.xyw */ emit_op2(c, WM_LINTERP, dst_mask(dst, BRW_WRITEMASK_ZW), interp, deltas); break; case TGSI_SEMANTIC_COLOR: if (c->key.flat_shade) { emit_op1(c, WM_CINTERP, dst, interp); } else if (interp_mode == TGSI_INTERPOLATE_LINEAR) { emit_op2(c, WM_LINTERP, dst, interp, deltas); } else { emit_op3(c, WM_PINTERP, dst, interp, deltas, get_pixel_w(c)); } break; case TGSI_SEMANTIC_FOG: /* Interpolate the fog coordinate */ emit_op3(c, WM_PINTERP, dst_mask(dst, BRW_WRITEMASK_X), interp, deltas, get_pixel_w(c)); emit_op1(c, TGSI_OPCODE_MOV, dst_mask(dst, BRW_WRITEMASK_YZ), src_imm1f(c, 0.0)); emit_op1(c, TGSI_OPCODE_MOV, dst_mask(dst, BRW_WRITEMASK_W), src_imm1f(c, 1.0)); break; case TGSI_SEMANTIC_FACE: /* XXX review/test this case */ emit_op0(c, WM_FRONTFACING, dst_mask(dst, BRW_WRITEMASK_X)); emit_op1(c, TGSI_OPCODE_MOV, dst_mask(dst, BRW_WRITEMASK_YZ), src_imm1f(c, 0.0)); emit_op1(c, TGSI_OPCODE_MOV, dst_mask(dst, BRW_WRITEMASK_W), src_imm1f(c, 1.0)); break; case TGSI_SEMANTIC_PSIZE: /* XXX review/test this case */ emit_op3(c, WM_PINTERP, dst_mask(dst, BRW_WRITEMASK_XY), interp, deltas, get_pixel_w(c)); emit_op1(c, TGSI_OPCODE_MOV, dst_mask(dst, BRW_WRITEMASK_Z), src_imm1f(c, 0.0f)); emit_op1(c, TGSI_OPCODE_MOV, dst_mask(dst, BRW_WRITEMASK_W), src_imm1f(c, 1.0f)); break; default: switch (interp_mode) { case TGSI_INTERPOLATE_CONSTANT: emit_op1(c, WM_CINTERP, dst, interp); break; case TGSI_INTERPOLATE_LINEAR: emit_op2(c, WM_LINTERP, dst, interp, deltas); break; case TGSI_INTERPOLATE_PERSPECTIVE: emit_op3(c, WM_PINTERP, dst, interp, deltas, get_pixel_w(c)); break; } break; } }
static void emit_interp( struct brw_wm_compile *c, GLuint idx ) { struct prog_dst_register dst = dst_reg(PROGRAM_INPUT, idx); struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx); struct prog_src_register deltas = get_delta_xy(c); /* Need to use PINTERP on attributes which have been * multiplied by 1/W in the SF program, and LINTERP on those * which have not: */ switch (idx) { case FRAG_ATTRIB_WPOS: /* Have to treat wpos.xy specially: */ emit_op(c, WM_WPOSXY, dst_mask(dst, WRITEMASK_XY), 0, get_pixel_xy(c), src_undef(), src_undef()); dst = dst_mask(dst, WRITEMASK_ZW); /* PROGRAM_INPUT.attr.xyzw = INTERP payload.interp[attr].x, deltas.xyw */ emit_op(c, WM_LINTERP, dst, 0, interp, deltas, src_undef()); break; case FRAG_ATTRIB_COL0: case FRAG_ATTRIB_COL1: if (c->key.flat_shade) { emit_op(c, WM_CINTERP, dst, 0, interp, src_undef(), src_undef()); } else { if (c->key.linear_color) { emit_op(c, WM_LINTERP, dst, 0, interp, deltas, src_undef()); } else { /* perspective-corrected color interpolation */ emit_op(c, WM_PINTERP, dst, 0, interp, deltas, get_pixel_w(c)); } } break; case FRAG_ATTRIB_FOGC: /* Interpolate the fog coordinate */ emit_op(c, WM_PINTERP, dst_mask(dst, WRITEMASK_X), 0, interp, deltas, get_pixel_w(c)); emit_op(c, OPCODE_MOV, dst_mask(dst, WRITEMASK_YZW), 0, src_swizzle(interp, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE), src_undef(), src_undef()); break; case FRAG_ATTRIB_FACE: emit_op(c, WM_FRONTFACING, dst_mask(dst, WRITEMASK_X), 0, src_undef(), src_undef(), src_undef()); break; case FRAG_ATTRIB_PNTC: /* XXX review/test this case */ emit_op(c, WM_PINTERP, dst_mask(dst, WRITEMASK_XY), 0, interp, deltas, get_pixel_w(c)); emit_op(c, OPCODE_MOV, dst_mask(dst, WRITEMASK_ZW), 0, src_swizzle(interp, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE), src_undef(), src_undef()); break; default: emit_op(c, WM_PINTERP, dst, 0, interp, deltas, get_pixel_w(c)); break; } c->fp_interp_emitted |= 1<<idx; }
static void emit_interp( struct brw_wm_compile *c, GLuint idx ) { struct prog_dst_register dst = dst_reg(PROGRAM_INPUT, idx); struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx); struct prog_src_register deltas = get_delta_xy(c); struct prog_src_register arg2; GLuint opcode; /* Need to use PINTERP on attributes which have been * multiplied by 1/W in the SF program, and LINTERP on those * which have not: */ switch (idx) { case FRAG_ATTRIB_WPOS: opcode = WM_LINTERP; arg2 = src_undef(); /* Have to treat wpos.xy specially: */ emit_op(c, WM_WPOSXY, dst_mask(dst, WRITEMASK_XY), 0, 0, 0, get_pixel_xy(c), src_undef(), src_undef()); dst = dst_mask(dst, WRITEMASK_ZW); /* PROGRAM_INPUT.attr.xyzw = INTERP payload.interp[attr].x, deltas.xyw */ emit_op(c, WM_LINTERP, dst, 0, 0, 0, interp, deltas, arg2); break; case FRAG_ATTRIB_COL0: case FRAG_ATTRIB_COL1: if (c->key.flat_shade) { emit_op(c, WM_CINTERP, dst, 0, 0, 0, interp, src_undef(), src_undef()); } else { emit_op(c, WM_LINTERP, dst, 0, 0, 0, interp, deltas, src_undef()); } break; default: emit_op(c, WM_PINTERP, dst, 0, 0, 0, interp, deltas, get_pixel_w(c)); break; } c->fp_interp_emitted |= 1<<idx; }