diff options
| -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 | 
