summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Koƛcielnicki <koriakin@0x04.net>2016-12-04 18:02:48 +0100
committerMarcin Koƛcielnicki <koriakin@0x04.net>2016-12-04 18:02:48 +0100
commit3c524897be0fd732d9e2b0214ec7781a2cf815b7 (patch)
tree39734933b5cfd091d67baafeb6a62f0ef4b47f3b
parent8ee8cfffcf56453925ecb23d39c35a827af4c6c6 (diff)
hwtest/pgraph: Refactor uses of vtxid.
-rw-r--r--hwtest/pgraph_mthd_xy.cc270
-rw-r--r--hwtest/pgraph_state_tests.cc2
-rw-r--r--include/nvhw/pgraph.h22
-rw-r--r--nvhw/pgraph.c211
-rw-r--r--nvhw/pgraph_xy.c95
-rw-r--r--nvhw/pgraph_xy3.c149
6 files changed, 352 insertions, 397 deletions
diff --git a/hwtest/pgraph_mthd_xy.cc b/hwtest/pgraph_mthd_xy.cc
index 82d9fd48..14a45ff5 100644
--- a/hwtest/pgraph_mthd_xy.cc
+++ b/hwtest/pgraph_mthd_xy.cc
@@ -488,22 +488,26 @@ class MthdVtxTest : public MthdTest {
}
}
void emulate_mthd() override {
- int rcls;
- if (chipset.card_type < 3) {
- rcls = extr(exp.access, 12, 5);
- } else {
- rcls = cls;
+ int rcls = pgraph_class(&exp);
+ if (first) {
+ pgraph_clear_vtxid(&exp);
+ if (chipset.card_type >= 3) {
+ if (cls >= 9 && cls <= 0xb) {
+ exp.valid[0] &= ~0xffff;
+ insrt(exp.valid[0], 21, 1, 1);
+ }
+ if (cls == 0x18)
+ insrt(exp.valid[0], 21, 1, 1);
+ }
}
+ int vidx = pgraph_vtxid(&exp);
if (chipset.card_type < 3) {
- if (first)
- insrt(exp.xy_misc_0, 28, 4, 0);
- int idx = extr(exp.xy_misc_0, 28, 4);
if (rcls == 0x11 || rcls == 0x12 || rcls == 0x13)
- idx = 4;
- if (nv01_pgraph_is_tex_class(rcls)) {
- idx = (mthd - 0x10) >> 2 & 0xf;
- if (idx >= 12)
- idx -= 8;
+ vidx = 4;
+ if (nv01_pgraph_is_tex_class(&exp)) {
+ vidx = (mthd - 0x10) >> 2 & 0xf;
+ if (vidx >= 12)
+ vidx -= 8;
if (extr(exp.xy_misc_1[0], 24, 1) && extr(exp.xy_misc_1[0], 25, 1) != (uint32_t)fract) {
exp.valid[0] &= ~0xffffff;
}
@@ -513,57 +517,33 @@ class MthdVtxTest : public MthdTest {
insrt(exp.xy_misc_1[0], 0, 1, 0);
insrt(exp.xy_misc_1[0], 24, 1, 1);
insrt(exp.xy_misc_1[0], 25, 1, fract);
- nv01_pgraph_bump_vtxid(&exp);
- nv01_pgraph_set_vtx(&exp, 0, idx, extrs(val, 0, 16), false);
- nv01_pgraph_set_vtx(&exp, 1, idx, extrs(val, 16, 16), false);
+ pgraph_bump_vtxid(&exp);
+ nv01_pgraph_set_vtx(&exp, 0, vidx, extrs(val, 0, 16), false);
+ nv01_pgraph_set_vtx(&exp, 1, vidx, extrs(val, 16, 16), false);
if (!poly) {
- if (idx <= 8)
- exp.valid[0] |= 0x1001 << idx;
+ if (vidx <= 8)
+ exp.valid[0] |= 0x1001 << vidx;
if (rcls >= 0x09 && rcls <= 0x0b) {
if (first) {
exp.valid[0] &= ~0xffffff;
exp.valid[0] |= 0x011111;
} else {
- exp.valid[0] |= 0x10010 << (idx & 3);
+ exp.valid[0] |= 0x10010 << (vidx & 3);
}
}
if ((rcls == 0x10 || rcls == 0x0c) && first)
exp.valid[0] |= 0x100;
} else {
if (rcls >= 9 && rcls <= 0xb) {
- exp.valid[0] |= 0x10010 << (idx & 3);
+ exp.valid[0] |= 0x10010 << (vidx & 3);
}
}
- if (draw)
- nv01_pgraph_prep_draw(&exp, poly);
- // XXX
- if (draw && (rcls == 0x11 || rcls == 0x12 || rcls == 0x13))
- skip = true;
} else {
- int vidx;
- if (first) {
- vidx = 0;
- if (cls >= 9 && cls <= 0xb) {
- exp.valid[0] &= ~0xffff;
- insrt(exp.valid[0], 21, 1, 1);
- }
- if (cls == 0x18)
- insrt(exp.valid[0], 21, 1, 1);
- } else {
- vidx = extr(exp.xy_misc_0, 28, 4);
- }
int rvidx = ifc ? 4 : vidx;
int svidx = vidx & 3;
- int nvidx = (vidx + 1) & 0xf;
- if (cls == 0x8 || cls == 0x9 || cls == 0xa || cls == 0xc)
- nvidx &= 1;
- if (vidx == 2 && cls == 0xb)
- nvidx = 0;
- if (vidx == 3 && cls == 0x10)
- nvidx = 0;
if (cls == 0xc && !first)
vidx = rvidx = svidx = 1;
- insrt(exp.xy_misc_0, 28, 4, nvidx);
+ pgraph_bump_vtxid(&exp);
insrt(exp.xy_misc_1[0], 0, 1, 0);
insrt(exp.xy_misc_1[1], 0, 1, 1);
if (cls != 0xc || first)
@@ -605,18 +585,16 @@ class MthdVtxTest : public MthdTest {
insrt(exp.xy_clip[0][vidx >> 3], 4*((vidx|1) & 7), 4, xcstat);
insrt(exp.xy_clip[1][vidx >> 3], 4*((vidx|1) & 7), 4, ycstat);
}
- if (draw) {
- nv03_pgraph_prep_draw(&exp, poly, false);
- }
+ }
+ if (draw) {
+ pgraph_prep_draw(&exp, poly, false);
+ // XXX
+ if (rcls == 0x11 || rcls == 0x12 || rcls == 0x13)
+ skip = true;
}
}
bool other_fail() override {
- int rcls;
- if (chipset.card_type < 3) {
- rcls = extr(exp.access, 12, 5);
- } else {
- rcls = cls;
- }
+ int rcls = pgraph_class(&exp);
if (real.status && (rcls == 9 || rcls == 0xa || rcls == 0x0b || rcls == 0x0c || rcls == 0x10)) {
/* Hung PGRAPH... */
skip = true;
@@ -708,30 +686,38 @@ class MthdX32Test : public MthdTest {
}
}
void emulate_mthd() override {
- if (chipset.card_type < 3) {
- int rcls = extr(exp.access, 12, 5);
- if (first)
- insrt(exp.xy_misc_0, 28, 4, 0);
- int idx = extr(exp.xy_misc_0, 28, 4);
- if (nv01_pgraph_is_tex_class(rcls)) {
- if (extr(exp.xy_misc_1[0], 24, 1) && extr(exp.xy_misc_1[0], 25, 1)) {
- exp.valid[0] &= ~0xffffff;
+ int rcls = pgraph_class(&exp);
+ if (first) {
+ pgraph_clear_vtxid(&exp);
+ if (chipset.card_type >= 3) {
+ if (cls >= 9 && cls <= 0xb) {
+ exp.valid[0] &= ~0xffff;
+ insrt(exp.valid[0], 21, 1, 1);
}
+ if (cls == 0x18)
+ insrt(exp.valid[0], 21, 1, 1);
}
- insrt(exp.xy_misc_0, 28, 4, idx);
+ }
+ int vidx = pgraph_vtxid(&exp);
+ if (nv01_pgraph_is_tex_class(&exp)) {
+ if (extr(exp.xy_misc_1[0], 24, 1) && extr(exp.xy_misc_1[0], 25, 1)) {
+ exp.valid[0] &= ~0xffffff;
+ }
+ }
+ if (chipset.card_type < 3) {
insrt(exp.xy_misc_1[0], 0, 1, 0);
insrt(exp.xy_misc_1[0], 24, 1, 1);
insrt(exp.xy_misc_1[0], 25, 1, 0);
- nv01_pgraph_set_vtx(&exp, 0, idx, val, true);
+ nv01_pgraph_set_vtx(&exp, 0, vidx, val, true);
if (!poly) {
- if (idx <= 8)
- exp.valid[0] |= 1 << idx;
+ if (vidx <= 8)
+ exp.valid[0] |= 1 << vidx;
if (rcls >= 0x09 && rcls <= 0x0b) {
if (first) {
exp.valid[0] &= ~0xffffff;
exp.valid[0] |= 0x000111;
} else {
- exp.valid[0] |= 0x10 << (idx & 3);
+ exp.valid[0] |= 0x10 << (vidx & 3);
}
}
if ((rcls == 0x10 || rcls == 0x0c) && first)
@@ -740,24 +726,11 @@ class MthdX32Test : public MthdTest {
if (rcls >= 9 && rcls <= 0xb) {
if (exp.valid[0] & 0xf00f)
exp.valid[0] &= ~0x100;
- exp.valid[0] |= 0x10 << (idx & 3);
+ exp.valid[0] |= 0x10 << (vidx & 3);
}
}
} else {
- int vidx;
- if (first) {
- vidx = 0;
- if (cls >= 9 && cls <= 0xb) {
- exp.valid[0] &= ~0xffff;
- insrt(exp.valid[0], 21, 1, 1);
- }
- if (cls == 0x18)
- insrt(exp.valid[0], 21, 1, 1);
- } else {
- vidx = extr(exp.xy_misc_0, 28, 4);
- }
int svidx = vidx & 3;
- insrt(exp.xy_misc_0, 28, 4, vidx);
insrt(exp.xy_misc_1[0], 0, 1, 0);
insrt(exp.xy_misc_1[1], 0, 1, 1);
insrt(exp.xy_misc_3, 8, 1, 0);
@@ -884,45 +857,33 @@ class MthdY32Test : public MthdTest {
val = extrs(val, 0, 17);
}
void emulate_mthd() override {
+ int rcls = pgraph_class(&exp);
+ int vidx = pgraph_vtxid(&exp);
if (chipset.card_type < 3) {
- int rcls = extr(exp.access, 12, 5);
- int idx = extr(exp.xy_misc_0, 28, 4);
- if (nv01_pgraph_is_tex_class(rcls)) {
+ if (nv01_pgraph_is_tex_class(&exp)) {
if (extr(exp.xy_misc_1[0], 24, 1) && extr(exp.xy_misc_1[0], 25, 1)) {
exp.valid[0] &= ~0xffffff;
}
}
- nv01_pgraph_bump_vtxid(&exp);
+ pgraph_bump_vtxid(&exp);
insrt(exp.xy_misc_1[0], 0, 1, 0);
insrt(exp.xy_misc_1[0], 24, 1, 1);
insrt(exp.xy_misc_1[0], 25, 1, 0);
- nv01_pgraph_set_vtx(&exp, 1, idx, val, true);
+ nv01_pgraph_set_vtx(&exp, 1, vidx, val, true);
if (!poly) {
- if (idx <= 8)
- exp.valid[0] |= 0x1000 << idx;
+ if (vidx <= 8)
+ exp.valid[0] |= 0x1000 << vidx;
if (rcls >= 0x09 && rcls <= 0x0b) {
- exp.valid[0] |= 0x10000 << (idx & 3);
+ exp.valid[0] |= 0x10000 << (vidx & 3);
}
} else {
if (rcls >= 9 && rcls <= 0xb) {
- exp.valid[0] |= 0x10000 << (idx & 3);
+ exp.valid[0] |= 0x10000 << (vidx & 3);
}
}
- if (draw)
- nv01_pgraph_prep_draw(&exp, poly);
- // XXX
- if (draw && (rcls == 0x11 || rcls == 0x12 || rcls == 0x13))
- skip = true;
} else {
- int vidx;
- vidx = extr(exp.xy_misc_0, 28, 4);
int svidx = vidx & 3;
- int nvidx = (vidx + 1) & 0xf;
- if (cls == 0x8 || cls == 0x9 || cls == 0xa)
- nvidx &= 1;
- if (vidx == 2 && cls == 0xb)
- nvidx = 0;
- insrt(exp.xy_misc_0, 28, 4, nvidx);
+ pgraph_bump_vtxid(&exp);
insrt(exp.xy_misc_1[0], 0, 1, 0);
insrt(exp.xy_misc_1[1], 0, 1, 1);
insrt(exp.xy_misc_3, 8, 1, 0);
@@ -945,18 +906,16 @@ class MthdY32Test : public MthdTest {
} else {
insrt(exp.xy_clip[1][vidx >> 3], 4*(vidx & 7), 4, ycstat);
}
- if (draw) {
- nv03_pgraph_prep_draw(&exp, poly, false);
- }
+ }
+ if (draw) {
+ pgraph_prep_draw(&exp, poly, false);
+ // XXX
+ if (rcls == 0x11 || rcls == 0x12 || rcls == 0x13)
+ skip = true;
}
}
bool other_fail() override {
- int rcls;
- if (chipset.card_type < 3) {
- rcls = extr(exp.access, 12, 5);
- } else {
- rcls = cls;
- }
+ int rcls = pgraph_class(&exp);
if (real.status && (rcls == 9 || rcls == 0xa || rcls == 0x0b || rcls == 0x0c || rcls == 0x10)) {
/* Hung PGRAPH... */
skip = true;
@@ -1071,22 +1030,20 @@ class MthdIfcSizeTest : public MthdTest {
}
}
void emulate_mthd() override {
+ int rcls = pgraph_class(&exp);
if (chipset.card_type < 3) {
if (is_out) {
- int rcls = extr(exp.access, 12, 5);
exp.vtx_x[5] = extr(val, 0, 16);
exp.vtx_y[5] = extr(val, 16, 16);
if (rcls <= 0xb && rcls >= 9)
exp.valid[0] &= ~0xffffff;
exp.valid[0] |= 0x020020;
- insrt(exp.xy_misc_0, 28, 4, 0);
if (rcls >= 0x11 && rcls <= 0x13)
insrt(exp.xy_misc_1[0], 0, 1, 0);
if (rcls == 0x10 || (rcls >= 9 && rcls <= 0xc))
exp.valid[0] |= 0x100;
}
if (is_in) {
- int rcls = extr(exp.access, 12, 5);
exp.vtx_y[1] = 0;
exp.vtx_x[3] = extr(val, 0, 16);
exp.vtx_y[3] = -extr(val, 16, 16);
@@ -1121,8 +1078,8 @@ class MthdIfcSizeTest : public MthdTest {
extr(exp.xy_misc_4[1], 28, 2) == 0;
}
insrt(exp.xy_misc_0, 12, 1, zero);
- insrt(exp.xy_misc_0, 28, 4, 0);
}
+ pgraph_clear_vtxid(&exp);
} else {
if (is_out) {
exp.valid[0] |= 0x2020;
@@ -1150,7 +1107,7 @@ class MthdIfcSizeTest : public MthdTest {
}
insrt(exp.xy_misc_1[0], 0, 1, 0);
insrt(exp.xy_misc_1[1], 0, 1, cls != 0x15);
- insrt(exp.xy_misc_0, 28, 4, 0);
+ pgraph_clear_vtxid(&exp);
insrt(exp.xy_misc_3, 8, 1, 0);
}
}
@@ -1288,29 +1245,17 @@ class MthdRectTest : public MthdTest {
}
}
void emulate_mthd() override {
- int rcls;
- if (chipset.card_type < 3) {
- rcls = extr(exp.access, 12, 5);
- } else {
- rcls = cls;
- }
+ int rcls = pgraph_class(&exp);
if (rcls == 0x14) {
+ pgraph_bump_vtxid(&exp);
+ exp.vtx_x[3] = extr(val, 0, 16);
+ exp.vtx_y[3] = extr(val, 16, 16);
if (chipset.card_type < 3) {
- exp.vtx_x[3] = extr(val, 0, 16);
- exp.vtx_y[3] = extr(val, 16, 16);
nv01_pgraph_vtx_fixup(&exp, 0, 2, exp.vtx_x[3], 1, 0, 2);
nv01_pgraph_vtx_fixup(&exp, 1, 2, exp.vtx_y[3], 1, 0, 2);
exp.valid[0] |= 0x4004;
insrt(exp.xy_misc_0, 12, 1, !exp.vtx_x[3] || !exp.vtx_y[3]);
- nv01_pgraph_bump_vtxid(&exp);
} else {
- exp.vtx_x[3] = extr(val, 0, 16);
- exp.vtx_y[3] = extr(val, 16, 16);
- int vidx = extr(exp.xy_misc_0, 28, 4);
- int nvidx = vidx + 1;
- if (nvidx == 4)
- nvidx = 0;
- insrt(exp.xy_misc_0, 28, 4, nvidx);
nv03_pgraph_vtx_cmp(&exp, 0, 3, false);
nv03_pgraph_vtx_cmp(&exp, 1, 3, false);
bool zero = false;
@@ -1325,23 +1270,15 @@ class MthdRectTest : public MthdTest {
exp.valid[0] |= 0x404;
}
} else if (rcls == 0x10) {
+ pgraph_bump_vtxid(&exp);
+ pgraph_bump_vtxid(&exp);
if (chipset.card_type < 3) {
nv01_pgraph_vtx_fixup(&exp, 0, 2, extr(val, 0, 16), 1, 0, 2);
nv01_pgraph_vtx_fixup(&exp, 1, 2, extr(val, 16, 16), 1, 0, 2);
nv01_pgraph_vtx_fixup(&exp, 0, 3, extr(val, 0, 16), 1, 1, 3);
nv01_pgraph_vtx_fixup(&exp, 1, 3, extr(val, 16, 16), 1, 1, 3);
- nv01_pgraph_bump_vtxid(&exp);
- nv01_pgraph_bump_vtxid(&exp);
exp.valid[0] |= 0x00c00c;
} else {
- int vtxid = extr(exp.xy_misc_0, 28, 4);
- vtxid++;
- if (vtxid == 4)
- vtxid = 0;
- vtxid++;
- if (vtxid == 4)
- vtxid = 0;
- insrt(exp.xy_misc_0, 28, 4, vtxid);
insrt(exp.xy_misc_1[1], 0, 1, 1);
nv03_pgraph_vtx_add(&exp, 0, 2, exp.vtx_x[0], extr(val, 0, 16), 0, false);
nv03_pgraph_vtx_add(&exp, 1, 2, exp.vtx_y[0], extr(val, 16, 16), 0, false);
@@ -1353,16 +1290,12 @@ class MthdRectTest : public MthdTest {
}
} else if (rcls == 0x0c || rcls == 0x11 || rcls == 0x12 || rcls == 0x13 || (chipset.card_type >= 3 && rcls == 7)) {
if (chipset.card_type < 3) {
- int idx = extr(exp.xy_misc_0, 28, 4);
- nv01_pgraph_vtx_fixup(&exp, 0, idx, extr(val, 0, 16), 1, 0, idx & 3);
- nv01_pgraph_vtx_fixup(&exp, 1, idx, extr(val, 16, 16), 1, 0, idx & 3);
- nv01_pgraph_bump_vtxid(&exp);
- if (idx <= 8)
- exp.valid[0] |= 0x1001 << idx;
+ int vidx = pgraph_vtxid(&exp);
+ nv01_pgraph_vtx_fixup(&exp, 0, vidx, extr(val, 0, 16), 1, 0, vidx & 3);
+ nv01_pgraph_vtx_fixup(&exp, 1, vidx, extr(val, 16, 16), 1, 0, vidx & 3);
+ if (vidx <= 8)
+ exp.valid[0] |= 0x1001 << vidx;
} else {
- int vidx = extr(exp.xy_misc_0, 28, 4);
- int nvidx = (vidx + 1) & 1;
- insrt(exp.xy_misc_0, 28, 4, nvidx);
if (noclip) {
nv03_pgraph_vtx_add(&exp, 0, 1, exp.vtx_x[0], extr(val, 16, 16), 0, true);
nv03_pgraph_vtx_add(&exp, 1, 1, exp.vtx_y[0], extr(val, 0, 16), 0, true);
@@ -1380,24 +1313,21 @@ class MthdRectTest : public MthdTest {
exp.valid[0] |= 0x202;
insrt(exp.xy_misc_1[1], 0, 1, 1);
}
+ pgraph_bump_vtxid(&exp);
} else {
nv01_pgraph_vtx_fixup(&exp, 0, 15, extr(val, 0, 16), 1, 15, 1);
nv01_pgraph_vtx_fixup(&exp, 1, 15, extr(val, 16, 16), 1, 15, 1);
- nv01_pgraph_bump_vtxid(&exp);
+ pgraph_bump_vtxid(&exp);
if (rcls >= 0x09 && rcls <= 0x0b) {
exp.valid[0] |= 0x080080;
}
}
if (draw) {
- if (chipset.card_type < 3) {
- nv01_pgraph_prep_draw(&exp, false);
- } else {
- nv03_pgraph_prep_draw(&exp, false, noclip);
- }
+ pgraph_prep_draw(&exp, false, noclip);
+ // XXX
+ if (rcls == 0x11 || rcls == 0x12 || rcls == 0x13)
+ skip = true;
}
- // XXX
- if (draw && (rcls == 0x11 || rcls == 0x12 || rcls == 0x13))
- skip = true;
}
bool other_fail() override {
int rcls = extr(exp.access, 12, 5);
@@ -1461,9 +1391,9 @@ class MthdIfcDataTest : public MthdTest {
}
}
void emulate_mthd() override {
+ int rcls = pgraph_class(&exp);
exp.misc32[0] = is_bitmap ? pgraph_expand_mono(&exp, val) : val;
insrt(exp.xy_misc_1[0], 24, 1, 0);
- int rcls = exp.access >> 12 & 0x1f;
int steps = 4 / nv01_pgraph_cpp_in(exp.ctx_switch[0]);
if (rcls == 0x12)
steps = 0x20;
@@ -1505,7 +1435,7 @@ class MthdIfcDataTest : public MthdTest {
skip = true;
return;
}
- insrt(exp.xy_misc_0, 28, 4, 0);
+ pgraph_clear_vtxid(&exp);
vidx = 1;
exp.vtx_y[2] = exp.vtx_y[3] + 1;
nv01_pgraph_vtx_cmp(&exp, 1, 2);
@@ -1529,7 +1459,7 @@ class MthdIfcDataTest : public MthdTest {
exp.intr |= 1 << 12;
}
restart:;
- vidx = extr(exp.xy_misc_0, 28, 1);
+ vidx = pgraph_vtxid(&exp) & 1;
if (extr(exp.edgefill, 8, 1)) {
/* XXX */
skip = true;
@@ -1537,9 +1467,9 @@ restart:;
}
if (!exp.intr) {
if (extr(exp.xy_misc_4[0], 29, 1)) {
- nv01_pgraph_bump_vtxid(&exp);
+ pgraph_bump_vtxid(&exp);
} else {
- insrt(exp.xy_misc_0, 28, 4, 0);
+ pgraph_clear_vtxid(&exp);
vidx = 1;
bool check_y = false;
if (extr(exp.xy_misc_4[1], 28, 1)) {
@@ -1585,7 +1515,7 @@ restart:;
nv01_pgraph_vtx_add(&exp, 0, vidx, vidx, exp.vtx_x[2], exp.vtx_x[vidx], 0);
}
} else {
- nv01_pgraph_bump_vtxid(&exp);
+ pgraph_bump_vtxid(&exp);
if (extr(exp.xy_misc_4[0], 29, 1)) {
exp.vtx_x[2] -= steps;
nv01_pgraph_vtx_cmp(&exp, 0, 2);
@@ -1645,7 +1575,7 @@ class MthdZPointZetaTest : public MthdTest {
}
void emulate_mthd() override {
insrt(exp.misc32[1], 16, 16, extr(val, 16, 16));
- nv03_pgraph_prep_draw(&exp, false, false);
+ pgraph_prep_draw(&exp, false, false);
nv03_pgraph_vtx_add(&exp, 0, 0, exp.vtx_x[0], 1, 0, false);
}
public:
@@ -1675,7 +1605,7 @@ class MthdSifcDiffTest : public MthdTest {
exp.vtx_y[5] = val;
else
exp.vtx_x[5] = val;
- insrt(exp.xy_misc_0, 28, 4, 0);
+ pgraph_clear_vtxid(&exp);
insrt(exp.xy_misc_1[0], 0, 1, 0);
insrt(exp.xy_misc_1[1], 0, 1, 0);
}
@@ -1704,7 +1634,7 @@ class MthdSifcVtxTest : public MthdTest {
exp.vtx_y[3] = -exp.vtx_y[7];
exp.vtx_y[4] = extr(val, 16, 16) << 16;
insrt(exp.valid[0], 19, 1, 0);
- insrt(exp.xy_misc_0, 28, 4, 0);
+ pgraph_clear_vtxid(&exp);
insrt(exp.xy_misc_1[0], 0, 1, 0);
insrt(exp.xy_misc_1[1], 0, 1, 0);
int xcstat = nv03_pgraph_clip_status(&exp, extrs(val, 4, 12), 0, false);
diff --git a/hwtest/pgraph_state_tests.cc b/hwtest/pgraph_state_tests.cc
index e106c5b0..a92fd6ef 100644
--- a/hwtest/pgraph_state_tests.cc
+++ b/hwtest/pgraph_state_tests.cc
@@ -703,7 +703,7 @@ protected:
int32_t min, max;
int32_t min_exp[2], max_exp[2];
nv01_pgraph_clip_bounds(&exp, min_exp, max_exp);
- if (nv01_pgraph_is_tex_class(cls)) {
+ if (nv01_pgraph_is_tex_class(&exp)) {
min = max = 0x40000000;
int bit;
for (bit = 30; bit >= 15; bit--) {
diff --git a/include/nvhw/pgraph.h b/include/nvhw/pgraph.h
index 6df17665..58ca9bb1 100644
--- a/include/nvhw/pgraph.h
+++ b/include/nvhw/pgraph.h
@@ -254,6 +254,7 @@ int nv01_pgraph_dither_10to5(int val, int x, int y, bool isg);
uint32_t nv03_pgraph_rop(struct pgraph_state *state, int x, int y, uint32_t pixel, struct pgraph_color src);
uint32_t nv03_pgraph_solid_rop(struct pgraph_state *state, int x, int y, uint32_t pixel);
bool pgraph_cliprect_pass(struct pgraph_state *state, int32_t x, int32_t y);
+void pgraph_prep_draw(struct pgraph_state *state, bool poly, bool noclip);
/* pgraph_xy.c */
int nv01_pgraph_use_v16(struct pgraph_state *state);
@@ -265,8 +266,9 @@ void nv01_pgraph_iclip_fixup(struct pgraph_state *state, int xy, int32_t coord,
void nv01_pgraph_uclip_fixup(struct pgraph_state *state, int xy, int idx, int32_t coord, int rel);
void nv01_pgraph_set_clip(struct pgraph_state *state, int is_size, uint32_t val);
void nv01_pgraph_set_vtx(struct pgraph_state *state, int xy, int idx, int32_t coord, bool is32);
-void nv01_pgraph_bump_vtxid(struct pgraph_state *state);
-void nv01_pgraph_prep_draw(struct pgraph_state *state, bool poly);
+uint32_t pgraph_vtxid(struct pgraph_state *state);
+void pgraph_clear_vtxid(struct pgraph_state *state);
+void pgraph_bump_vtxid(struct pgraph_state *state);
/* pgraph_xy3.c */
int nv03_pgraph_clip_status(struct pgraph_state *state, int32_t coord, int xy, bool canvas_only);
@@ -275,7 +277,6 @@ void nv03_pgraph_iclip_fixup(struct pgraph_state *state, int xy, int32_t coord);
void nv03_pgraph_uclip_fixup(struct pgraph_state *state, int which, int xy, int idx, int32_t coord);
void nv03_pgraph_set_clip(struct pgraph_state *state, int which, int idx, uint32_t val, bool prev_inited);
void nv03_pgraph_vtx_add(struct pgraph_state *state, int xy, int idx, uint32_t a, uint32_t b, uint32_t c, bool noclip);
-void nv03_pgraph_prep_draw(struct pgraph_state *state, bool poly, bool noclip);
/* pgraph_xy4.c */
int nv04_pgraph_clip_status(struct pgraph_state *state, int32_t coord, int xy);
@@ -300,6 +301,16 @@ bool nv03_pgraph_d3d_cmp(int func, uint32_t a, uint32_t b);
bool nv03_pgraph_d3d_wren(int func, bool zeta_test, bool alpha_test);
uint16_t nv03_pgraph_zpoint_rop(struct pgraph_state *state, int32_t x, int32_t y, uint16_t pixel);
+static inline uint32_t pgraph_class(struct pgraph_state *state) {
+ if (state->chipset.card_type < 3) {
+ return extr(state->access, 12, 5);
+ } else if (state->chipset.card_type < 4) {
+ return extr(state->ctx_user, 16, 5);
+ } else {
+ return extr(state->ctx_switch[0], 0, 8);
+ }
+}
+
static inline int pgraph_vtx_count(struct pgraph_state *state) {
if (state->chipset.card_type < 3) {
return 18;
@@ -332,7 +343,10 @@ static inline void nv03_pgraph_vtx_cmp(struct pgraph_state *state, int xy, int i
insrt(state->xy_misc_4[xy], 28, 2, stat);
}
-static inline bool nv01_pgraph_is_tex_class(int cls) {
+static inline bool nv01_pgraph_is_tex_class(struct pgraph_state *state) {
+ if (state->chipset.card_type >= 3)
+ return false;
+ uint32_t cls = pgraph_class(state);
bool is_texlin_class = (cls & 0xf) == 0xd;
bool is_texquad_class = (cls & 0xf) == 0xe;
return is_texlin_class || is_texquad_class;
diff --git a/nvhw/pgraph.c b/nvhw/pgraph.c
index f3c9550d..cb658e46 100644
--- a/nvhw/pgraph.c
+++ b/nvhw/pgraph.c
@@ -869,3 +869,214 @@ bool pgraph_cliprect_pass(struct pgraph_state *state, int32_t x, int32_t y) {
}
return covered ^ extr(state->cliprect_ctrl, 4, 1);
}
+
+void pgraph_prep_draw(struct pgraph_state *state, bool poly, bool noclip) {
+ if (state->chipset.card_type < 3) {
+ uint32_t class = extr(state->access, 12, 5);
+ if (!nv01_pgraph_is_drawable_class(class))
+ return;
+ int vidx = pgraph_vtxid(state);
+ if (class == 0x08) {
+ if ((state->valid[0] & 0x1001) != 0x1001)
+ state->intr |= 1 << 16;
+ state->valid[0] &= ~0xffffff;
+ } else if (class == 0x0c) {
+ if ((state->valid[0] & 0x3103) != 0x3103)
+ state->intr |= 1 << 16;
+ state->valid[0] &= ~0xffffff;
+ } else if (class == 0x10) {
+ if ((state->valid[0] & 0xf10f) != 0xf10f)
+ state->intr |= 1 << 16;
+ state->valid[0] &= ~0xffffff;
+ } else if (class >= 0x09 && class <= 0x0a) {
+ if (!poly) {
+ if ((state->valid[0] & 0x3103) != 0x3103)
+ state->intr |= 1 << 16;
+ state->valid[0] &= ~0x00f00f;
+ } else {
+ if ((state->valid[0] & 0x3f13f) != 0x30130)
+ state->intr |= 1 << 16;
+ state->valid[0] &= ~(0x10010 << (vidx & 3));
+ if (state->valid[0] & 0xf00f)
+ state->valid[0] &= ~0x100;
+ }
+ } else if (class == 0x0b) {
+ if (!poly) {
+ if ((state->valid[0] & 0x7107) != 0x7107)
+ state->intr |= 1 << 16;
+ state->valid[0] &= ~0x00f00f;
+ } else {
+ if ((state->valid[0] & 0x7f17f) != 0x70170)
+ state->intr |= 1 << 16;
+ state->valid[0] &= ~(0x10010 << (vidx & 3));
+ if (state->valid[0] & 0xf00f)
+ state->valid[0] &= ~0x100;
+ }
+ } else if (class == 0x11 || class == 0x12) {
+ if ((state->valid[0] & 0x38038) != 0x38038)
+ state->intr |= 1 << 16;
+ /* XXX: this steps the IFC machine */
+ } else if (class == 0x13) {
+ /* XXX: this steps the IFM machine */
+ }
+ if (state->xy_misc_4[0] & 0xf0)
+ state->intr |= 1 << 12;
+ if (state->xy_misc_4[1] & 0xf0)
+ state->intr |= 1 << 12;
+ if (state->valid[0] & 0x11000000 && state->ctx_switch[0] & 0x80)
+ state->intr |= 1 << 16;
+ if (extr(state->canvas_config, 24, 1))
+ state->intr |= 1 << 20;
+ if (extr(state->cliprect_ctrl, 8, 1))
+ state->intr |= 1 << 24;
+ if (state->intr)
+ state->access &= ~0x101;
+ } else {
+ int cls = extr(state->ctx_user, 16, 5);
+ if (extr(state->cliprect_ctrl, 8, 1))
+ insrt(state->intr, 24, 1, 1);
+ if (extr(state->xy_misc_4[0], 4, 4) || extr(state->xy_misc_4[1], 4, 4))
+ insrt(state->intr, 12, 1, 1);
+ if (cls == 0xc) {
+ if (!noclip && state->valid[0] & 0xa0000000)
+ insrt(state->intr, 16, 1, 1);
+ } else {
+ if (state->valid[0] & 0x50000000 && extr(state->ctx_switch[0], 15, 1))
+ insrt(state->intr, 16, 1, 1);
+ }
+ if (extr(state->debug[3], 22, 1)) {
+ bool passthru = extr(state->ctx_switch[0], 24, 5) == 0x17 && extr(state->ctx_switch[0], 13, 2) == 0;
+ int msk = extr(state->ctx_switch[0], 20, 4);
+ int cfmt = extr(state->ctx_switch[0], 0, 3);
+ bool bad = false;
+ int fmt = -1;
+ int cnt = 0;
+ for (int j = 0; j < 4; j++) {
+ if (msk & 1 << j || (msk == 0 && j == 3)) {
+ cnt++;
+ if (fmt == -1)
+ fmt = extr(state->surf_format, 4*j, 3);
+ else if (fmt != (int)extr(state->surf_format, 4*j, 3))
+ bad = true;
+ }
+ }
+ if (fmt == 0 && msk)
+ bad = true;
+ if (cls == 0x18 && fmt != 6 && fmt != 2)
+ bad = true;
+ if (cls == 0x18 && fmt == 2 && msk)
+ bad = true;
+ if (cls == 0x10) {
+ int sidx = extr(state->ctx_switch[0], 16, 2);
+ int sfmt = extr(state->surf_format, 4*sidx, 3);
+ if (cnt == 1) {
+ if ((sfmt & 3) != (fmt & 3))
+ bad = true;
+ } else {
+ if (sfmt != (fmt & 3) && sfmt != fmt)
+ bad = true;
+ }
+ if (fmt < 4 && msk)
+ bad = true;
+ } else {
+ if ((fmt == 0 || fmt == 4) && (!passthru || cls == 0xc))
+ bad = true;
+ if ((fmt == 0 || fmt == 4) && (cfmt != 4))
+ bad = true;
+ }
+ if ((fmt == 5 || fmt == 1) && (cfmt != 3))
+ bad = true;
+ if (bad)
+ insrt(state->intr, 20, 1, 1);
+ }
+ int vidx = pgraph_vtxid(state);
+ switch (cls) {
+ case 8:
+ if ((state->valid[0] & 0x010101) != 0x010101)
+ insrt(state->intr, 16, 1, 1);
+ if (!(state->intr & 0x01111000)) {
+ insrt(state->valid[0], 0, 16, 0);
+ insrt(state->valid[0], 21, 1, 0);
+ }
+ break;
+ case 0x18:
+ if ((state->valid[0] & 0x4210000) != 0x4210000)
+ insrt(state->intr, 16, 1, 1);
+ break;
+ case 9:
+ case 0xa:
+ if (!poly) {
+ if ((state->valid[0] & 0x210303) != 0x210303)
+ insrt(state->intr, 16, 1, 1);
+ if (!(state->intr & 0x01111000)) {
+ insrt(state->valid[0], 0, 4, 0);
+ insrt(state->valid[0], 8, 4, 0);
+ }
+ } else {
+ if ((state->valid[0] & 0x213030) != 0x213030)
+ insrt(state->intr, 16, 1, 1);
+ if (!(state->intr & 0x01111000)) {
+ insrt(state->valid[0], 4+(vidx&3), 1, 0);
+ insrt(state->valid[0], 12+(vidx&3), 1, 0);
+ }
+ }
+ break;
+ case 0xb:
+ if (!poly) {
+ if ((state->valid[0] & 0x210707) != 0x210707)
+ insrt(state->intr, 16, 1, 1);
+ if (!(state->intr & 0x01111000)) {
+ insrt(state->valid[0], 0, 4, 0);
+ insrt(state->valid[0], 8, 4, 0);
+ }
+ } else {
+ if ((state->valid[0] & 0x217070) != 0x217070)
+ insrt(state->intr, 16, 1, 1);
+ if (!(state->intr & 0x01111000)) {
+ insrt(state->valid[0], 4+(vidx&3), 1, 0);
+ insrt(state->valid[0], 12+(vidx&3), 1, 0);
+ }
+ }
+ break;
+ case 0x7:
+ if ((state->valid[0] & 0x10203) != 0x10203)
+ insrt(state->intr, 16, 1, 1);
+ if ((uint32_t)extrs(state->vtx_x[1], 0, 16) != state->vtx_x[1])
+ insrt(state->intr, 12, 1, 1);
+ if ((uint32_t)extrs(state->vtx_y[1], 0, 16) != state->vtx_y[1])
+ insrt(state->intr, 12, 1, 1);
+ if (!(state->intr & 0x01111000)) {
+ insrt(state->valid[0], 0, 16, 0);
+ insrt(state->valid[0], 21, 1, 0);
+ }
+ break;
+ case 0xc:
+ if ((state->valid[0] & 0x10203) != 0x10203)
+ insrt(state->intr, 16, 1, 1);
+ if (!noclip && !extr(state->valid[0], 20, 1))
+ insrt(state->intr, 16, 1, 1);
+ if ((uint32_t)extrs(state->vtx_x[1], 0, 16) != state->vtx_x[1])
+ insrt(state->intr, 12, 1, 1);
+ if ((uint32_t)extrs(state->vtx_y[1], 0, 16) != state->vtx_y[1])
+ insrt(state->intr, 12, 1, 1);
+ if (!(state->intr & 0x01111000)) {
+ insrt(state->valid[0], 0, 2, 0);
+ insrt(state->valid[0], 8, 2, 0);
+ insrt(state->valid[0], 21, 1, 0);
+ }
+ break;
+ case 0x10:
+ if ((state->valid[0] & 0x00003) != 0x00003)
+ insrt(state->intr, 16, 1, 1);
+ if (!(state->intr & 0x01111000)) {
+ insrt(state->valid[0], 0, 16, 0);
+ insrt(state->valid[0], 21, 1, 0);
+ }
+ break;
+ default:
+ abort();
+ }
+ if (state->intr)
+ state->fifo_enable = 0;
+ }
+}
diff --git a/nvhw/pgraph_xy.c b/nvhw/pgraph_xy.c
index 179d5c52..b9fedf21 100644
--- a/nvhw/pgraph_xy.c
+++ b/nvhw/pgraph_xy.c
@@ -105,7 +105,7 @@ void nv01_pgraph_set_xym2(struct pgraph_state *state, int xy, int idx, int sid,
void nv01_pgraph_vtx_fixup(struct pgraph_state *state, int xy, int idx, int32_t coord, int rel, int ridx, int sid) {
uint32_t class = extr(state->access, 12, 5);
- bool is_tex_class = nv01_pgraph_is_tex_class(class);
+ bool is_tex_class = nv01_pgraph_is_tex_class(state);
int32_t cbase = extrs(state->dst_canvas_min, 16 * xy, 16);
if (ridx != -1)
cbase = (xy ? state->vtx_y : state->vtx_x)[ridx];
@@ -128,7 +128,7 @@ void nv01_pgraph_vtx_fixup(struct pgraph_state *state, int xy, int idx, int32_t
void nv01_pgraph_vtx_add(struct pgraph_state *state, int xy, int idx, int sid, uint32_t a, uint32_t b, uint32_t c) {
uint32_t class = extr(state->access, 12, 5);
- bool is_tex_class = nv01_pgraph_is_tex_class(class);
+ bool is_tex_class = nv01_pgraph_is_tex_class(state);
uint64_t val = (uint64_t)a + b + c;
if (xy == 0)
state->vtx_x[idx] = val;
@@ -144,7 +144,7 @@ void nv01_pgraph_vtx_add(struct pgraph_state *state, int xy, int idx, int sid, u
void nv01_pgraph_iclip_fixup(struct pgraph_state *state, int xy, int32_t coord, int rel) {
uint32_t class = extr(state->access, 12, 5);
- int is_tex_class = nv01_pgraph_is_tex_class(class);
+ int is_tex_class = nv01_pgraph_is_tex_class(state);
int max = extr(state->dst_canvas_max, xy * 16, 12);
if (state->xy_misc_1[0] & 0x2000 << (xy * 4) && state->ctx_switch[0] & 0x80)
max = state->uclip_max[xy] & 0xfff;
@@ -178,7 +178,7 @@ void nv01_pgraph_iclip_fixup(struct pgraph_state *state, int xy, int32_t coord,
void nv01_pgraph_uclip_fixup(struct pgraph_state *state, int xy, int idx, int32_t coord, int rel) {
uint32_t class = extr(state->access, 12, 5);
- int is_tex_class = nv01_pgraph_is_tex_class(class);
+ int is_tex_class = nv01_pgraph_is_tex_class(state);
int32_t cbase = extrs(state->dst_canvas_min, 16 * xy, 16);
if (rel)
coord += cbase;
@@ -210,7 +210,7 @@ void nv01_pgraph_uclip_fixup(struct pgraph_state *state, int xy, int idx, int32_
void nv01_pgraph_set_clip(struct pgraph_state *state, int is_size, uint32_t val) {
uint32_t class = extr(state->access, 12, 5);
- int is_tex_class = nv01_pgraph_is_tex_class(class);
+ int is_tex_class = nv01_pgraph_is_tex_class(state);
int is_tex = is_tex_class && !is_size;
int xy;
if (is_size) {
@@ -241,7 +241,7 @@ void nv01_pgraph_set_clip(struct pgraph_state *state, int is_size, uint32_t val)
int mvidx = is_size;
if ((class == 0xc || class == 0x11 || class == 0x12 || class == 0x13) && is_size) {
svidx = 0;
- dvidx = extr(state->xy_misc_0, 28, 4);
+ dvidx = pgraph_vtxid(state);
mvidx = dvidx%4;
}
if (class == 0x14 && is_size) {
@@ -303,7 +303,7 @@ void nv01_pgraph_set_clip(struct pgraph_state *state, int is_size, uint32_t val)
void nv01_pgraph_set_vtx(struct pgraph_state *state, int xy, int idx, int32_t coord, bool is32) {
uint32_t class = extr(state->access, 12, 5);
- int is_tex_class = nv01_pgraph_is_tex_class(class);
+ int is_tex_class = nv01_pgraph_is_tex_class(state);
int sid = idx & 3;
int32_t cbase = extrs(state->dst_canvas_min, 16 * xy, 16);
int fract = is_tex_class && extr(state->xy_misc_1[0], 25, 1);
@@ -326,10 +326,20 @@ void nv01_pgraph_set_vtx(struct pgraph_state *state, int xy, int idx, int32_t co
}
}
-void nv01_pgraph_bump_vtxid(struct pgraph_state *state) {
- uint32_t class = extr(state->access, 12, 5);
- if (class < 8 || class == 0x0f || (class > 0x14 && class < 0x1d) || class == 0x1f)
- return;
+uint32_t pgraph_vtxid(struct pgraph_state *state) {
+ return extr(state->xy_misc_0, 28, 4);
+}
+
+void pgraph_clear_vtxid(struct pgraph_state *state) {
+ insrt(state->xy_misc_0, 28, 4, 0);
+}
+
+void pgraph_bump_vtxid(struct pgraph_state *state) {
+ uint32_t class = pgraph_class(state);
+ if (state->chipset.card_type < 3) {
+ if (class < 8 || class == 0x0f || (class > 0x14 && class < 0x1d) || class == 0x1f)
+ return;
+ }
int vtxid = extr(state->xy_misc_0, 28, 4);
vtxid++;
if (class == 0x0b) {
@@ -338,7 +348,7 @@ void nv01_pgraph_bump_vtxid(struct pgraph_state *state) {
} else if (class == 0x10 || class == 0x14) {
if (vtxid == 4)
vtxid = 0;
- } else if (nv01_pgraph_is_tex_class(class)) {
+ } else if (nv01_pgraph_is_tex_class(state)) {
if (vtxid == 3 + nv01_pgraph_use_v16(state))
vtxid = 0;
} else {
@@ -346,64 +356,3 @@ void nv01_pgraph_bump_vtxid(struct pgraph_state *state) {
}
insrt(state->xy_misc_0, 28, 4, vtxid);
}
-
-void nv01_pgraph_prep_draw(struct pgraph_state *state, bool poly) {
- uint32_t class = extr(state->access, 12, 5);
- if (!nv01_pgraph_is_drawable_class(class))
- return;
- if (class == 0x08) {
- if ((state->valid[0] & 0x1001) != 0x1001)
- state->intr |= 1 << 16;
- state->valid[0] &= ~0xffffff;
- } else if (class == 0x0c) {
- if ((state->valid[0] & 0x3103) != 0x3103)
- state->intr |= 1 << 16;
- state->valid[0] &= ~0xffffff;
- } else if (class == 0x10) {
- if ((state->valid[0] & 0xf10f) != 0xf10f)
- state->intr |= 1 << 16;
- state->valid[0] &= ~0xffffff;
- } else if (class >= 0x09 && class <= 0x0a) {
- if (!poly) {
- if ((state->valid[0] & 0x3103) != 0x3103)
- state->intr |= 1 << 16;
- state->valid[0] &= ~0x00f00f;
- } else {
- if ((state->valid[0] & 0x3f13f) != 0x30130)
- state->intr |= 1 << 16;
- state->valid[0] &= ~(0x10010 << (extr(state->xy_misc_0, 28, 2)));
- if (state->valid[0] & 0xf00f)
- state->valid[0] &= ~0x100;
- }
- } else if (class == 0x0b) {
- if (!poly) {
- if ((state->valid[0] & 0x7107) != 0x7107)
- state->intr |= 1 << 16;
- state->valid[0] &= ~0x00f00f;
- } else {
- if ((state->valid[0] & 0x7f17f) != 0x70170)
- state->intr |= 1 << 16;
- state->valid[0] &= ~(0x10010 << (extr(state->xy_misc_0, 28, 2)));
- if (state->valid[0] & 0xf00f)
- state->valid[0] &= ~0x100;
- }
- } else if (class == 0x11 || class == 0x12) {
- if ((state->valid[0] & 0x38038) != 0x38038)
- state->intr |= 1 << 16;
- /* XXX: this steps the IFC machine */
- } else if (class == 0x13) {
- /* XXX: this steps the IFM machine */
- }
- if (state->xy_misc_4[0] & 0xf0)
- state->intr |= 1 << 12;
- if (state->xy_misc_4[1] & 0xf0)
- state->intr |= 1 << 12;
- if (state->valid[0] & 0x11000000 && state->ctx_switch[0] & 0x80)
- state->intr |= 1 << 16;
- if (extr(state->canvas_config, 24, 1))
- state->intr |= 1 << 20;
- if (extr(state->cliprect_ctrl, 8, 1))
- state->intr |= 1 << 24;
- if (state->intr)
- state->access &= ~0x101;
-}
diff --git a/nvhw/pgraph_xy3.c b/nvhw/pgraph_xy3.c
index 5ad9f0e3..ca16b165 100644
--- a/nvhw/pgraph_xy3.c
+++ b/nvhw/pgraph_xy3.c
@@ -245,152 +245,3 @@ void nv03_pgraph_vtx_add(struct pgraph_state *state, int xy, int idx, uint32_t a
int cstat = nv03_pgraph_clip_status(state, val, xy, noclip);
nv03_pgraph_set_xym2(state, xy, idx, val >> 32 & 1, oob, cstat);
}
-
-void nv03_pgraph_prep_draw(struct pgraph_state *state, bool poly, bool noclip) {
- int cls = extr(state->ctx_user, 16, 5);
- if (extr(state->cliprect_ctrl, 8, 1))
- insrt(state->intr, 24, 1, 1);
- if (extr(state->xy_misc_4[0], 4, 4) || extr(state->xy_misc_4[1], 4, 4))
- insrt(state->intr, 12, 1, 1);
- if (cls == 0xc) {
- if (!noclip && state->valid[0] & 0xa0000000)
- insrt(state->intr, 16, 1, 1);
- } else {
- if (state->valid[0] & 0x50000000 && extr(state->ctx_switch[0], 15, 1))
- insrt(state->intr, 16, 1, 1);
- }
- if (extr(state->debug[3], 22, 1)) {
- bool passthru = extr(state->ctx_switch[0], 24, 5) == 0x17 && extr(state->ctx_switch[0], 13, 2) == 0;
- int msk = extr(state->ctx_switch[0], 20, 4);
- int cfmt = extr(state->ctx_switch[0], 0, 3);
- bool bad = false;
- int fmt = -1;
- int cnt = 0;
- for (int j = 0; j < 4; j++) {
- if (msk & 1 << j || (msk == 0 && j == 3)) {
- cnt++;
- if (fmt == -1)
- fmt = extr(state->surf_format, 4*j, 3);
- else if (fmt != (int)extr(state->surf_format, 4*j, 3))
- bad = true;
- }
- }
- if (fmt == 0 && msk)
- bad = true;
- if (cls == 0x18 && fmt != 6 && fmt != 2)
- bad = true;
- if (cls == 0x18 && fmt == 2 && msk)
- bad = true;
- if (cls == 0x10) {
- int sidx = extr(state->ctx_switch[0], 16, 2);
- int sfmt = extr(state->surf_format, 4*sidx, 3);
- if (cnt == 1) {
- if ((sfmt & 3) != (fmt & 3))
- bad = true;
- } else {
- if (sfmt != (fmt & 3) && sfmt != fmt)
- bad = true;
- }
- if (fmt < 4 && msk)
- bad = true;
- } else {
- if ((fmt == 0 || fmt == 4) && (!passthru || cls == 0xc))
- bad = true;
- if ((fmt == 0 || fmt == 4) && (cfmt != 4))
- bad = true;
- }
- if ((fmt == 5 || fmt == 1) && (cfmt != 3))
- bad = true;
- if (bad)
- insrt(state->intr, 20, 1, 1);
- }
- int vidx = extr(state->xy_misc_0, 28, 4);
- switch (cls) {
- case 8:
- if ((state->valid[0] & 0x010101) != 0x010101)
- insrt(state->intr, 16, 1, 1);
- if (!(state->intr & 0x01111000)) {
- insrt(state->valid[0], 0, 16, 0);
- insrt(state->valid[0], 21, 1, 0);
- }
- break;
- case 0x18:
- if ((state->valid[0] & 0x4210000) != 0x4210000)
- insrt(state->intr, 16, 1, 1);
- break;
- case 9:
- case 0xa:
- if (!poly) {
- if ((state->valid[0] & 0x210303) != 0x210303)
- insrt(state->intr, 16, 1, 1);
- if (!(state->intr & 0x01111000)) {
- insrt(state->valid[0], 0, 4, 0);
- insrt(state->valid[0], 8, 4, 0);
- }
- } else {
- if ((state->valid[0] & 0x213030) != 0x213030)
- insrt(state->intr, 16, 1, 1);
- if (!(state->intr & 0x01111000)) {
- insrt(state->valid[0], 4+(vidx&3), 1, 0);
- insrt(state->valid[0], 12+(vidx&3), 1, 0);
- }
- }
- break;
- case 0xb:
- if (!poly) {
- if ((state->valid[0] & 0x210707) != 0x210707)
- insrt(state->intr, 16, 1, 1);
- if (!(state->intr & 0x01111000)) {
- insrt(state->valid[0], 0, 4, 0);
- insrt(state->valid[0], 8, 4, 0);
- }
- } else {
- if ((state->valid[0] & 0x217070) != 0x217070)
- insrt(state->intr, 16, 1, 1);
- if (!(state->intr & 0x01111000)) {
- insrt(state->valid[0], 4+(vidx&3), 1, 0);
- insrt(state->valid[0], 12+(vidx&3), 1, 0);
- }
- }
- break;
- case 0x7:
- if ((state->valid[0] & 0x10203) != 0x10203)
- insrt(state->intr, 16, 1, 1);
- if ((uint32_t)extrs(state->vtx_x[1], 0, 16) != state->vtx_x[1])
- insrt(state->intr, 12, 1, 1);
- if ((uint32_t)extrs(state->vtx_y[1], 0, 16) != state->vtx_y[1])
- insrt(state->intr, 12, 1, 1);
- if (!(state->intr & 0x01111000)) {
- insrt(state->valid[0], 0, 16, 0);
- insrt(state->valid[0], 21, 1, 0);
- }
- break;
- case 0xc:
- if ((state->valid[0] & 0x10203) != 0x10203)
- insrt(state->intr, 16, 1, 1);
- if (!noclip && !extr(state->valid[0], 20, 1))
- insrt(state->intr, 16, 1, 1);
- if ((uint32_t)extrs(state->vtx_x[1], 0, 16) != state->vtx_x[1])
- insrt(state->intr, 12, 1, 1);
- if ((uint32_t)extrs(state->vtx_y[1], 0, 16) != state->vtx_y[1])
- insrt(state->intr, 12, 1, 1);
- if (!(state->intr & 0x01111000)) {
- insrt(state->valid[0], 0, 2, 0);
- insrt(state->valid[0], 8, 2, 0);
- insrt(state->valid[0], 21, 1, 0);
- }
- break;
- case 0x10:
- if ((state->valid[0] & 0x00003) != 0x00003)
- insrt(state->intr, 16, 1, 1);
- if (!(state->intr & 0x01111000)) {
- insrt(state->valid[0], 0, 16, 0);
- insrt(state->valid[0], 21, 1, 0);
- }
- break;
- default:
- abort();
- }
- if (state->intr)
- state->fifo_enable = 0;
-}