diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm.h | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_fp.c | 37 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_glsl.c | 66 |
3 files changed, 103 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index 931c0038d4..22e77287f4 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -194,6 +194,7 @@ struct brw_wm_compile { GLuint nr_fp_insns; GLuint fp_temp; GLuint fp_interp_emitted; + GLuint fp_deriv_emitted; struct prog_src_register pixel_xy; struct prog_src_register delta_xy; diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index 403160c494..0a6e516b93 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -361,6 +361,37 @@ static void emit_interp( struct brw_wm_compile *c, c->fp_interp_emitted |= 1<<idx; } +static void emit_ddx( struct brw_wm_compile *c, + const struct prog_instruction *inst ) +{ + GLuint idx = inst->SrcReg[0].Index; + struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx); + + c->fp_deriv_emitted |= 1<<idx; + emit_op(c, + OPCODE_DDX, + inst->DstReg, + 0, 0, 0, + interp, + get_pixel_w(c), + src_undef()); +} + +static void emit_ddy( struct brw_wm_compile *c, + const struct prog_instruction *inst ) +{ + GLuint idx = inst->SrcReg[0].Index; + struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx); + + c->fp_deriv_emitted |= 1<<idx; + emit_op(c, + OPCODE_DDY, + inst->DstReg, + 0, 0, 0, + interp, + get_pixel_w(c), + src_undef()); +} /*********************************************************************** * Hacks to extend the program parameter and constant lists. @@ -907,6 +938,12 @@ void brw_wm_pass_fp( struct brw_wm_compile *c ) */ out->DstReg.WriteMask = 0; break; + case OPCODE_DDX: + emit_ddx(c, inst); + break; + case OPCODE_DDY: + emit_ddy(c, inst); + break; case OPCODE_END: emit_fog(c); emit_fb_write(c); diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index 09e7590367..f47f139282 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -16,6 +16,8 @@ GLboolean brw_wm_is_glsl(struct gl_fragment_program *fp) case OPCODE_CAL: case OPCODE_BRK: case OPCODE_RET: + case OPCODE_DDX: + case OPCODE_DDY: case OPCODE_BGNLOOP: return GL_TRUE; default: @@ -92,7 +94,7 @@ static void prealloc_reg(struct brw_wm_compile *c) int i, j; struct brw_reg reg; int nr_interp_regs = 0; - GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted; + GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted | c->fp_deriv_emitted; for (i = 0; i < 4; i++) { reg = (i < c->key.nr_depth_regs) @@ -862,6 +864,62 @@ static void emit_sne(struct brw_wm_compile *c, { emit_sop(c, inst, BRW_CONDITIONAL_NEQ); } + +static void emit_ddx(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + struct brw_reg interp[4]; + struct brw_reg dst; + struct brw_reg src0, w; + GLuint nr, i; + src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); + w = get_src_reg(c, &inst->SrcReg[1], 3, 1); + nr = src0.nr; + interp[0] = brw_vec1_grf(nr, 0); + interp[1] = brw_vec1_grf(nr, 4); + interp[2] = brw_vec1_grf(nr+1, 0); + interp[3] = brw_vec1_grf(nr+1, 4); + brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF); + for(i = 0; i < 4; i++ ) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + brw_MOV(p, dst, interp[i]); + brw_MUL(p, dst, dst, w); + } + } + brw_set_saturate(p, 0); +} + +static void emit_ddy(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + struct brw_reg interp[4]; + struct brw_reg dst; + struct brw_reg src0, w; + GLuint nr, i; + + src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); + nr = src0.nr; + w = get_src_reg(c, &inst->SrcReg[1], 3, 1); + interp[0] = brw_vec1_grf(nr, 0); + interp[1] = brw_vec1_grf(nr, 4); + interp[2] = brw_vec1_grf(nr+1, 0); + interp[3] = brw_vec1_grf(nr+1, 4); + brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF); + for(i = 0; i < 4; i++ ) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + brw_MOV(p, dst, suboffset(interp[i], 1)); + brw_MUL(p, dst, dst, w); + } + } + brw_set_saturate(p, 0); +} + /* TODO BIAS on SIMD8 not workind yet... */ @@ -1088,6 +1146,12 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c) case OPCODE_MIN: emit_min(c, inst); break; + case OPCODE_DDX: + emit_ddx(c, inst); + break; + case OPCODE_DDY: + emit_ddy(c, inst); + break; case OPCODE_SLT: emit_slt(c, inst); break; |