mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-20 08:00:28 +01:00
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:
parent
926562fe27
commit
a55e50b082
2 changed files with 48 additions and 16 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue