mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 00:10:10 +01:00
Do individual negetation in swizzling, thus we can
save one instruction in some case.
This commit is contained in:
parent
c6f35dd8db
commit
acd1f16b35
1 changed files with 78 additions and 21 deletions
|
|
@ -360,27 +360,78 @@ static __inline pfs_reg_t absolute(pfs_reg_t r)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int swz_native(struct r300_fragment_program *rp,
|
static int swz_native(struct r300_fragment_program *rp,
|
||||||
pfs_reg_t src, pfs_reg_t *r)
|
pfs_reg_t src, pfs_reg_t *r, GLuint arbneg)
|
||||||
{
|
{
|
||||||
/* Native swizzle, nothing to see here */
|
/* Native swizzle, nothing to see here */
|
||||||
|
src.negate_s = (arbneg >> 3) & 1;
|
||||||
|
|
||||||
|
if ((arbneg & 0x7) == 0x0) {
|
||||||
|
src.negate_v = 0;
|
||||||
*r = src;
|
*r = src;
|
||||||
|
} else if ((arbneg & 0x7) == 0x7) {
|
||||||
|
src.negate_v = 1;
|
||||||
|
*r = src;
|
||||||
|
} else {
|
||||||
|
if (!r->valid)
|
||||||
|
*r = get_temp_reg(rp);
|
||||||
|
src.negate_v = 1;
|
||||||
|
emit_arith(rp, PFS_OP_MAD, *r, arbneg & 0x7,
|
||||||
|
keep(src), pfs_one, pfs_zero, 0);
|
||||||
|
src.negate_v = 0;
|
||||||
|
emit_arith(rp, PFS_OP_MAD, *r,
|
||||||
|
(arbneg ^ 0x7) | WRITEMASK_W,
|
||||||
|
src, pfs_one, pfs_zero, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int swz_emit_partial(struct r300_fragment_program *rp, pfs_reg_t src,
|
static int swz_emit_partial(struct r300_fragment_program *rp, pfs_reg_t src,
|
||||||
pfs_reg_t *r, int mask, int mc)
|
pfs_reg_t *r, int mask, int mc, GLuint arbneg)
|
||||||
{
|
{
|
||||||
|
GLuint tmp;
|
||||||
|
GLuint wmask = 0;
|
||||||
|
|
||||||
if (!r->valid)
|
if (!r->valid)
|
||||||
*r = get_temp_reg(rp);
|
*r = get_temp_reg(rp);
|
||||||
|
|
||||||
/* A partial match, src.v_swz/mask define what parts of the
|
/* A partial match, src.v_swz/mask define what parts of the
|
||||||
* desired swizzle we match */
|
* desired swizzle we match */
|
||||||
if (mc + s_mask[mask].count == 3)
|
if (mc + s_mask[mask].count == 3) {
|
||||||
emit_arith(rp, PFS_OP_MAD, *r, s_mask[mask].mask|WRITEMASK_W,
|
wmask = WRITEMASK_W;
|
||||||
|
src.negate_s = (arbneg >> 3) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = arbneg & s_mask[mask].mask;
|
||||||
|
if (tmp) {
|
||||||
|
tmp = tmp ^ s_mask[mask].mask;
|
||||||
|
if (tmp) {
|
||||||
|
src.negate_v = 1;
|
||||||
|
emit_arith(rp, PFS_OP_MAD, *r,
|
||||||
|
arbneg & s_mask[mask].mask,
|
||||||
|
keep(src), pfs_one, pfs_zero, 0);
|
||||||
|
src.negate_v = 0;
|
||||||
|
if (!wmask) src.no_use = GL_TRUE;
|
||||||
|
else src.no_use = GL_FALSE;
|
||||||
|
emit_arith(rp, PFS_OP_MAD, *r, tmp | wmask,
|
||||||
src, pfs_one, pfs_zero, 0);
|
src, pfs_one, pfs_zero, 0);
|
||||||
else
|
} else {
|
||||||
emit_arith(rp, PFS_OP_MAD, *r, s_mask[mask].mask, keep(src),
|
src.negate_v = 1;
|
||||||
pfs_one, pfs_zero, 0);
|
if (!wmask) src.no_use = GL_TRUE;
|
||||||
|
else src.no_use = GL_FALSE;
|
||||||
|
emit_arith(rp, PFS_OP_MAD, *r,
|
||||||
|
(arbneg & s_mask[mask].mask) | wmask,
|
||||||
|
src, pfs_one, pfs_zero, 0);
|
||||||
|
src.negate_v = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!wmask) src.no_use = GL_TRUE;
|
||||||
|
else src.no_use = GL_FALSE;
|
||||||
|
emit_arith(rp, PFS_OP_MAD, *r,
|
||||||
|
s_mask[mask].mask | wmask,
|
||||||
|
src, pfs_one, pfs_zero, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return s_mask[mask].count;
|
return s_mask[mask].count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -388,11 +439,11 @@ static int swz_emit_partial(struct r300_fragment_program *rp, pfs_reg_t src,
|
||||||
((SWIZZLE_##x<<0)| \
|
((SWIZZLE_##x<<0)| \
|
||||||
(SWIZZLE_##y<<3)| \
|
(SWIZZLE_##y<<3)| \
|
||||||
(SWIZZLE_##z<<6)| \
|
(SWIZZLE_##z<<6)| \
|
||||||
(SWIZZLE_##w<<9)))
|
(SWIZZLE_##w<<9)), \
|
||||||
|
0)
|
||||||
|
|
||||||
static pfs_reg_t do_swizzle(struct r300_fragment_program *rp,
|
static pfs_reg_t do_swizzle(struct r300_fragment_program *rp,
|
||||||
pfs_reg_t src,
|
pfs_reg_t src, GLuint arbswz, GLuint arbneg)
|
||||||
GLuint arbswz)
|
|
||||||
{
|
{
|
||||||
pfs_reg_t r = undef;
|
pfs_reg_t r = undef;
|
||||||
|
|
||||||
|
|
@ -415,12 +466,14 @@ static pfs_reg_t do_swizzle(struct r300_fragment_program *rp,
|
||||||
#define CUR_HASH (v_swiz[src.v_swz].hash & s_mask[c_mask].hash)
|
#define CUR_HASH (v_swiz[src.v_swz].hash & s_mask[c_mask].hash)
|
||||||
if (CUR_HASH == (arbswz & s_mask[c_mask].hash)) {
|
if (CUR_HASH == (arbswz & s_mask[c_mask].hash)) {
|
||||||
if (s_mask[c_mask].count == 3)
|
if (s_mask[c_mask].count == 3)
|
||||||
v_matched += swz_native(rp, src, &r);
|
v_matched += swz_native(rp, src, &r,
|
||||||
|
arbneg);
|
||||||
else
|
else
|
||||||
v_matched += swz_emit_partial(rp, src,
|
v_matched += swz_emit_partial(rp, src,
|
||||||
&r,
|
&r,
|
||||||
c_mask,
|
c_mask,
|
||||||
v_matched);
|
v_matched,
|
||||||
|
arbneg);
|
||||||
|
|
||||||
if (v_matched == 3)
|
if (v_matched == 3)
|
||||||
return r;
|
return r;
|
||||||
|
|
@ -455,14 +508,17 @@ static pfs_reg_t t_src(struct r300_fragment_program *rp,
|
||||||
r.valid = GL_TRUE;
|
r.valid = GL_TRUE;
|
||||||
break;
|
break;
|
||||||
case PROGRAM_LOCAL_PARAM:
|
case PROGRAM_LOCAL_PARAM:
|
||||||
r = emit_param4fv(rp, rp->mesa_program.Base.LocalParams[fpsrc.Index]);
|
r = emit_param4fv(rp,
|
||||||
|
rp->mesa_program.Base.LocalParams[fpsrc.Index]);
|
||||||
break;
|
break;
|
||||||
case PROGRAM_ENV_PARAM:
|
case PROGRAM_ENV_PARAM:
|
||||||
r = emit_param4fv(rp, rp->ctx->FragmentProgram.Parameters[fpsrc.Index]);
|
r = emit_param4fv(rp,
|
||||||
|
rp->ctx->FragmentProgram.Parameters[fpsrc.Index]);
|
||||||
break;
|
break;
|
||||||
case PROGRAM_STATE_VAR:
|
case PROGRAM_STATE_VAR:
|
||||||
case PROGRAM_NAMED_PARAM:
|
case PROGRAM_NAMED_PARAM:
|
||||||
r = emit_param4fv(rp, rp->mesa_program.Base.Parameters->ParameterValues[fpsrc.Index]);
|
r = emit_param4fv(rp,
|
||||||
|
rp->mesa_program.Base.Parameters->ParameterValues[fpsrc.Index]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROR("unknown SrcReg->File %x\n", fpsrc.File);
|
ERROR("unknown SrcReg->File %x\n", fpsrc.File);
|
||||||
|
|
@ -471,14 +527,14 @@ static pfs_reg_t t_src(struct r300_fragment_program *rp,
|
||||||
|
|
||||||
/* no point swizzling ONE/ZERO/HALF constants... */
|
/* no point swizzling ONE/ZERO/HALF constants... */
|
||||||
if (r.v_swz < SWIZZLE_111 && r.s_swz < SWIZZLE_ZERO)
|
if (r.v_swz < SWIZZLE_111 && r.s_swz < SWIZZLE_ZERO)
|
||||||
r = do_swizzle(rp, r, fpsrc.Swizzle);
|
r = do_swizzle(rp, r, fpsrc.Swizzle, fpsrc.NegateBase);
|
||||||
#if 0
|
#if 0
|
||||||
/* WRONG! Need to be able to do individual component negation,
|
/* WRONG! Need to be able to do individual component negation,
|
||||||
* should probably handle this in the swizzling code unless
|
* should probably handle this in the swizzling code unless
|
||||||
* all components are negated, then we can do this natively */
|
* all components are negated, then we can do this natively */
|
||||||
if ((fpsrc.NegateBase & 0xf) == 0xf)
|
if ((fpsrc.NegateBase & 0xf) == 0xf)
|
||||||
r.negate = GL_TRUE;
|
r.negate = GL_TRUE;
|
||||||
#endif
|
|
||||||
r.negate_s = (fpsrc.NegateBase >> 3) & 1;
|
r.negate_s = (fpsrc.NegateBase >> 3) & 1;
|
||||||
|
|
||||||
if ((fpsrc.NegateBase & 0x7) == 0x0) {
|
if ((fpsrc.NegateBase & 0x7) == 0x0) {
|
||||||
|
|
@ -504,6 +560,7 @@ static pfs_reg_t t_src(struct r300_fragment_program *rp,
|
||||||
r.negate_v = 0;
|
r.negate_v = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue