diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_glsl.c | 138 |
1 files changed, 25 insertions, 113 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index a42e6bf7a5..e3e6f66339 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -614,112 +614,6 @@ static void invoke_subroutine( struct brw_wm_compile *c, } } -/* 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 -unalias3(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 *arg2), - const struct brw_reg *dst, - GLuint mask, - const struct brw_reg *arg0, - const struct brw_reg *arg1, - const struct brw_reg *arg2) -{ - struct brw_compile *p = &c->func; - struct brw_reg tmp_arg0[4], tmp_arg1[4], tmp_arg2[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]; - tmp_arg2[j] = arg2[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]); - } - if (arg2[j].file == dst[i].file && - dst[i].nr == arg2[j].nr) { - tmp_arg2[j] = alloc_tmp(c); - brw_MOV(p, tmp_arg2[j], arg2[j]); - } - } - } - } - - func(p, dst, mask, tmp_arg0, tmp_arg1, tmp_arg2); - - 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) { @@ -1813,14 +1707,29 @@ static void get_argument_regs(struct brw_wm_compile *c, const struct prog_instruction *inst, int index, + struct brw_reg *dst, struct brw_reg *regs, int mask) { - int i; + struct brw_compile *p = &c->func; + int i, j; for (i = 0; i < 4; i++) { - if (mask & (1 << i)) + if (mask & (1 << i)) { regs[i] = get_src_reg(c, inst, index, i); + + /* Unalias destination registers from our sources. */ + if (regs[i].file == BRW_GENERAL_REGISTER_FILE) { + for (j = 0; j < 4; j++) { + if (memcmp(®s[i], &dst[j], sizeof(regs[0])) == 0) { + struct brw_reg tmp = alloc_tmp(c); + brw_MOV(p, tmp, regs[i]); + regs[i] = tmp; + break; + } + } + } + } } } @@ -1845,6 +1754,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) int dst_flags; struct brw_reg args[3][4], dst[4]; int j; + int mark = mark_tmps( c ); c->cur_inst = i; @@ -1866,7 +1776,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) } } for (j = 0; j < brw_wm_nr_args(inst->Opcode); j++) - get_argument_regs(c, inst, j, args[j], WRITEMASK_XYZW); + get_argument_regs(c, inst, j, dst, args[j], WRITEMASK_XYZW); dst_flags = inst->DstReg.WriteMask; if (inst->SaturateMode == SATURATE_ZERO_ONE) @@ -1920,8 +1830,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) emit_alu1(p, brw_RNDD, dst, dst_flags, args[0]); break; case OPCODE_LRP: - unalias3(c, emit_lrp, - dst, dst_flags, args[0], args[1], args[2]); + emit_lrp(p, dst, dst_flags, args[0], args[1], args[2]); break; case OPCODE_TRUNC: emit_alu1(p, brw_RNDZ, dst, dst_flags, args[0]); @@ -1964,10 +1873,10 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) emit_cmp(p, dst, dst_flags, args[0], args[1], args[2]); break; case OPCODE_MIN: - unalias2(c, emit_min, dst, dst_flags, args[0], args[1]); + emit_min(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_MAX: - unalias2(c, emit_max, dst, dst_flags, args[0], args[1]); + emit_max(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_DDX: case OPCODE_DDY: @@ -2122,6 +2031,9 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) inst->Opcode); } + /* Release temporaries containing any unaliased source regs. */ + release_tmps( c, mark ); + if (inst->CondUpdate) brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); else |