NV30/NV40 CMP and SCS src == dst handling

CMP and SCS can produce incorrect results if the source and
destination are the same.
This patch should fix the issues.
CMP is fixed by predicating both moves.
SCS by changing the order if the source component is X.
This commit is contained in:
Luca Barbieri 2009-12-26 08:12:15 +01:00 committed by Younes Manton
parent 926562fe27
commit a55e50b082
2 changed files with 48 additions and 16 deletions

View file

@ -435,10 +435,11 @@ nv30_fragprog_parse_instruction(struct nv30_fpc *fpc,
arith(fpc, sat, ADD, dst, mask, src[0], src[1], none);
break;
case TGSI_OPCODE_CMP:
tmp = temp(fpc);
arith(fpc, sat, MOV, dst, mask, src[2], none, none);
tmp = nv30_sr(NV30SR_NONE, 0);
tmp.cc_update = 1;
arith(fpc, 0, MOV, tmp, 0xf, src[0], none, none);
dst.cc_test = NV30_VP_INST_COND_GE;
arith(fpc, sat, MOV, dst, mask, src[2], none, none);
dst.cc_test = NV30_VP_INST_COND_LT;
arith(fpc, sat, MOV, dst, mask, src[1], none, none);
break;
@ -517,13 +518,28 @@ nv30_fragprog_parse_instruction(struct nv30_fpc *fpc,
arith(fpc, sat, RSQ, dst, mask, abs(swz(src[0], X, X, X, X)), none, none);
break;
case TGSI_OPCODE_SCS:
if (mask & MASK_X) {
arith(fpc, sat, COS, dst, MASK_X,
swz(src[0], X, X, X, X), none, none);
/* avoid overwriting the source */
if(src[0].swz[SWZ_X] != SWZ_X)
{
if (mask & MASK_X) {
arith(fpc, sat, COS, dst, MASK_X,
swz(src[0], X, X, X, X), none, none);
}
if (mask & MASK_Y) {
arith(fpc, sat, SIN, dst, MASK_Y,
swz(src[0], X, X, X, X), none, none);
}
}
if (mask & MASK_Y) {
arith(fpc, sat, SIN, dst, MASK_Y,
swz(src[0], X, X, X, X), none, none);
else
{
if (mask & MASK_Y) {
arith(fpc, sat, SIN, dst, MASK_Y,
swz(src[0], X, X, X, X), none, none);
}
if (mask & MASK_X) {
arith(fpc, sat, COS, dst, MASK_X,
swz(src[0], X, X, X, X), none, none);
}
}
break;
case TGSI_OPCODE_SIN:

View file

@ -445,10 +445,11 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
arith(fpc, sat, ADD, dst, mask, src[0], src[1], none);
break;
case TGSI_OPCODE_CMP:
tmp = temp(fpc);
arith(fpc, sat, MOV, dst, mask, src[2], none, none);
tmp = nv40_sr(NV40SR_NONE, 0);
tmp.cc_update = 1;
arith(fpc, 0, MOV, tmp, 0xf, src[0], none, none);
dst.cc_test = NV40_VP_INST_COND_GE;
arith(fpc, sat, MOV, dst, mask, src[2], none, none);
dst.cc_test = NV40_VP_INST_COND_LT;
arith(fpc, sat, MOV, dst, mask, src[1], none, none);
break;
@ -573,13 +574,28 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
neg(swz(tmp, X, X, X, X)), none, none);
break;
case TGSI_OPCODE_SCS:
if (mask & MASK_X) {
arith(fpc, sat, COS, dst, MASK_X,
swz(src[0], X, X, X, X), none, none);
/* avoid overwriting the source */
if(src[0].swz[SWZ_X] != SWZ_X)
{
if (mask & MASK_X) {
arith(fpc, sat, COS, dst, MASK_X,
swz(src[0], X, X, X, X), none, none);
}
if (mask & MASK_Y) {
arith(fpc, sat, SIN, dst, MASK_Y,
swz(src[0], X, X, X, X), none, none);
}
}
if (mask & MASK_Y) {
arith(fpc, sat, SIN, dst, MASK_Y,
swz(src[0], X, X, X, X), none, none);
else
{
if (mask & MASK_Y) {
arith(fpc, sat, SIN, dst, MASK_Y,
swz(src[0], X, X, X, X), none, none);
}
if (mask & MASK_X) {
arith(fpc, sat, COS, dst, MASK_X,
swz(src[0], X, X, X, X), none, none);
}
}
break;
case TGSI_OPCODE_SEQ: