i965: Share min/max between brw_wm_emit.c and brw_wm_glsl.c

This commit is contained in:
Eric Anholt
2009-08-19 11:57:32 -07:00
parent cfa927766a
commit ec66644ed0
3 changed files with 72 additions and 60 deletions
+10
View File
@@ -390,6 +390,16 @@ void emit_math2(struct brw_wm_compile *c,
GLuint mask,
const struct brw_reg *arg0,
const struct brw_reg *arg1);
void emit_min(struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
const struct brw_reg *arg0,
const struct brw_reg *arg1);
void emit_max(struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
const struct brw_reg *arg0,
const struct brw_reg *arg1);
void emit_pinterp(struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
+10 -10
View File
@@ -567,11 +567,11 @@ static void emit_cmp( struct brw_compile *p,
}
}
static void emit_max( struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
void emit_max(struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
const struct brw_reg *arg0,
const struct brw_reg *arg1)
{
GLuint i;
@@ -591,11 +591,11 @@ static void emit_max( struct brw_compile *p,
}
}
static void emit_min( struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
void emit_min(struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
const struct brw_reg *arg0,
const struct brw_reg *arg1)
{
GLuint i;
+52 -50
View File
@@ -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: