diff options
author | Eric Anholt <[email protected]> | 2009-08-19 11:57:32 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2009-11-06 21:08:55 -0800 |
commit | ec66644ed0af976cacb069ca7c7f0d6731666359 (patch) | |
tree | 8e2a11c392b26952e3ade2d85982652fdf657d72 /src/mesa/drivers/dri/i965/brw_wm_glsl.c | |
parent | cfa927766ab610a9a76730d337d77008d876ebbd (diff) |
i965: Share min/max between brw_wm_emit.c and brw_wm_glsl.c
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_wm_glsl.c')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_glsl.c | 102 |
1 files changed, 52 insertions, 50 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index be89bcf4ba6..9d3bc66f494 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -671,6 +671,55 @@ unalias3(struct brw_wm_compile *c, release_tmps(c, mark); } +/* Workaround for using brw_wm_emit.c's emit functions, which expect + * destination regs to be uniquely written. Moves arguments out to + * temporaries as necessary for instructions which use their destination as + * a temporary. + */ +static void +unalias2(struct brw_wm_compile *c, + void (*func)(struct brw_compile *c, + const struct brw_reg *dst, + GLuint mask, + const struct brw_reg *arg0, + const struct brw_reg *arg1), + const struct brw_reg *dst, + GLuint mask, + const struct brw_reg *arg0, + const struct brw_reg *arg1) +{ + struct brw_compile *p = &c->func; + struct brw_reg tmp_arg0[4], tmp_arg1[4]; + int i, j; + int mark = mark_tmps(c); + + for (j = 0; j < 4; j++) { + tmp_arg0[j] = arg0[j]; + tmp_arg1[j] = arg1[j]; + } + + for (i = 0; i < 4; i++) { + if (mask & (1<<i)) { + for (j = 0; j < 4; j++) { + if (arg0[j].file == dst[i].file && + dst[i].nr == arg0[j].nr) { + tmp_arg0[j] = alloc_tmp(c); + brw_MOV(p, tmp_arg0[j], arg0[j]); + } + if (arg1[j].file == dst[i].file && + dst[i].nr == arg1[j].nr) { + tmp_arg1[j] = alloc_tmp(c); + brw_MOV(p, tmp_arg1[j], arg1[j]); + } + } + } + } + + func(p, dst, mask, tmp_arg0, tmp_arg1); + + release_tmps(c, mark); +} + static void emit_arl(struct brw_wm_compile *c, const struct prog_instruction *inst) { @@ -684,55 +733,6 @@ static void emit_arl(struct brw_wm_compile *c, brw_set_saturate(p, 0); } - -static void emit_min_max(struct brw_wm_compile *c, - const struct prog_instruction *inst) -{ - struct brw_compile *p = &c->func; - const GLuint mask = inst->DstReg.WriteMask; - const int mark = mark_tmps(c); - int i; - brw_push_insn_state(p); - for (i = 0; i < 4; i++) { - if (mask & (1<<i)) { - struct brw_reg real_dst = get_dst_reg(c, inst, i); - struct brw_reg src0 = get_src_reg(c, inst, 0, i); - struct brw_reg src1 = get_src_reg(c, inst, 1, i); - struct brw_reg dst; - /* if dst==src0 or dst==src1 we need to use a temp reg */ - GLboolean use_temp = brw_same_reg(dst, src0) || - brw_same_reg(dst, src1); - if (use_temp) - dst = alloc_tmp(c); - else - dst = real_dst; - - /* - printf(" Min/max: dst %d src0 %d src1 %d\n", - dst.nr, src0.nr, src1.nr); - */ - brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); - brw_MOV(p, dst, src0); - brw_set_saturate(p, 0); - - if (inst->Opcode == OPCODE_MIN) - brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src1, src0); - else - brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, src1, src0); - - brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); - brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); - brw_MOV(p, dst, src1); - brw_set_saturate(p, 0); - brw_set_predicate_control_flag_value(p, 0xff); - if (use_temp) - brw_MOV(p, real_dst, dst); - } - } - brw_pop_insn_state(p); - release_tmps(c, mark); -} - /** * For GLSL shaders, this KIL will be unconditional. * It may be contained inside an IF/ENDIF structure of course. @@ -2122,8 +2122,10 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) emit_math1(c, BRW_MATH_FUNCTION_LOG, dst, dst_flags, args[0]); break; case OPCODE_MIN: + unalias2(c, emit_min, dst, dst_flags, args[0], args[1]); + break; case OPCODE_MAX: - emit_min_max(c, inst); + unalias2(c, emit_max, dst, dst_flags, args[0], args[1]); break; case OPCODE_DDX: case OPCODE_DDY: |