summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Koƛcielnicki <koriakin@0x04.net>2016-12-30 20:27:16 +0000
committerMarcin Koƛcielnicki <koriakin@0x04.net>2016-12-30 20:27:16 +0000
commite14f0d144548fd95529ed719fa173b66d01e644f (patch)
treea9005276050fb0dc6a301d9ab0ddc02a0af69853
parentec493bb6f07fa89d6ea2d58552c99252d5322b4f (diff)
hwtest/pgraph: Initial Kelvin method support.
-rw-r--r--hwtest/CMakeLists.txt1
-rw-r--r--hwtest/pgraph.cc21
-rw-r--r--hwtest/pgraph_class.h10
-rw-r--r--hwtest/pgraph_class_sifm.cc2
-rw-r--r--hwtest/pgraph_class_solid.cc21
-rw-r--r--hwtest/pgraph_class_surf.cc51
-rw-r--r--hwtest/pgraph_mthd.cc34
-rw-r--r--hwtest/pgraph_mthd.h4
-rw-r--r--hwtest/pgraph_mthd_grobj.cc35
-rw-r--r--hwtest/pgraph_mthd_misc.cc8
-rw-r--r--include/nvhw/pgraph.h35
-rw-r--r--nvhw/pgraph_xy4.c45
12 files changed, 195 insertions, 72 deletions
diff --git a/hwtest/CMakeLists.txt b/hwtest/CMakeLists.txt
index 3db21d34..41358f3e 100644
--- a/hwtest/CMakeLists.txt
+++ b/hwtest/CMakeLists.txt
@@ -22,6 +22,7 @@ if (NOT DISABLE_HWTEST)
pgraph_class_m2mf.cc pgraph_class_d3d0.cc
pgraph_class_sifm.cc pgraph_class_d3d56.cc
pgraph_class_celsius.cc pgraph_class_emu_d3d56.cc
+ pgraph_class_kelvin.cc
pgraph_rop.cc nv04_pgraph.cc
vram.cc nv10_tile.cc
nv50_ptherm.cc nv84_ptherm.cc
diff --git a/hwtest/pgraph.cc b/hwtest/pgraph.cc
index e29357a6..5adf96ad 100644
--- a/hwtest/pgraph.cc
+++ b/hwtest/pgraph.cc
@@ -34,7 +34,7 @@ using namespace hwtest::pgraph;
class PGraphClassTests : public hwtest::Test {
public:
bool supported() override {
- return chipset.card_type < 0x20;
+ return chipset.card_type < 0x30;
}
std::vector<Class *> classes() {
if (chipset.card_type < 3) {
@@ -102,7 +102,6 @@ public:
new Surf(opt, rnd(), 0x5b, "surf_zeta"),
new Surf2D(opt, rnd(), 0x42, "surf2d_nv4"),
new SurfSwz(opt, rnd(), 0x52, "surfswz_nv4"),
- new Surf3D(opt, rnd(), 0x53, "surf3d_nv4"),
new Line(opt, rnd(), 0x1c, "lin_nv1"),
new Tri(opt, rnd(), 0x1d, "tri_nv1"),
new Rect(opt, rnd(), 0x1e, "rect_nv1"),
@@ -122,6 +121,11 @@ public:
new Sifm(opt, rnd(), 0x77, "sifm_nv4"),
new Dvd(opt, rnd(), 0x38, "dvd_nv4"),
};
+ if (chipset.card_type < 0x20) {
+ res.insert(res.end(), {
+ new Surf3D(opt, rnd(), 0x53, "surf3d_nv4"),
+ });
+ }
if (chipset.chipset < 5) {
res.insert(res.end(), {
new OpClip(opt, rnd(), 0x10, "op_clip"),
@@ -150,6 +154,7 @@ public:
res.insert(res.end(), {
new EmuD3D5(opt, rnd(), 0x54, "d3d5_nv4"),
new EmuD3D6(opt, rnd(), 0x55, "d3d6_nv4"),
+ new Surf3D(opt, rnd(), 0x93, "surf3d_nv10"),
new EmuD3D5(opt, rnd(), 0x94, "d3d5_nv10"),
new EmuD3D6(opt, rnd(), 0x95, "d3d6_nv10"),
new Celsius(opt, rnd(), 0x56, "celsius_nv10"),
@@ -169,6 +174,17 @@ public:
new Celsius(opt, rnd(), 0x99, "celsius_nv17"),
});
}
+ } else if (chipset.card_type == 0x20) {
+ res.insert(res.end(), {
+ new EmuCelsius(opt, rnd(), 0x56, "celsius_nv10"),
+ new EmuCelsius(opt, rnd(), 0x96, "celsius_nv15"),
+ new Kelvin(opt, rnd(), 0x97, "kelvin_nv20"),
+ });
+ if (nv04_pgraph_is_nv25p(&chipset)) {
+ res.insert(res.end(), {
+ new Kelvin(opt, rnd(), 0x597, "kelvin_nv25"),
+ });
+ }
}
if (chipset.card_type >= 0x10) {
res.insert(res.end(), {
@@ -178,7 +194,6 @@ public:
new Sifm(opt, rnd(), 0x89, "sifm_nv10"),
new Dvd(opt, rnd(), 0x88, "dvd_nv10"),
new Surf2D(opt, rnd(), 0x62, "surf2d_nv10"),
- new Surf3D(opt, rnd(), 0x93, "surf3d_nv10"),
});
}
if (nv04_pgraph_is_nv15p(&chipset)) {
diff --git a/hwtest/pgraph_class.h b/hwtest/pgraph_class.h
index 6a112f53..7d1f8656 100644
--- a/hwtest/pgraph_class.h
+++ b/hwtest/pgraph_class.h
@@ -260,6 +260,16 @@ class Celsius : public Class {
using Class::Class;
};
+class EmuCelsius : public Class {
+ std::vector<SingleMthdTest *> mthds() override;
+ using Class::Class;
+};
+
+class Kelvin : public Class {
+ std::vector<SingleMthdTest *> mthds() override;
+ using Class::Class;
+};
+
class OpClip : public Class {
std::vector<SingleMthdTest *> mthds() override;
using Class::Class;
diff --git a/hwtest/pgraph_class_sifm.cc b/hwtest/pgraph_class_sifm.cc
index db9cb4d4..c28b15f7 100644
--- a/hwtest/pgraph_class_sifm.cc
+++ b/hwtest/pgraph_class_sifm.cc
@@ -651,7 +651,7 @@ std::vector<SingleMthdTest *> Dvd::mthds() {
new MthdSifmXy(opt, rnd(), "xy", 5, cls, 0x300),
new MthdSifmRect(opt, rnd(), "rect", 6, cls, 0x304),
new MthdSurfDvdFormat(opt, rnd(), "surf_format", 7, cls, 0x308),
- new MthdSurfOffset(opt, rnd(), "surf_offset", 8, cls, 0x30c, 4, SURF_NV4),
+ new MthdSurfOffset(opt, rnd(), "surf_offset", 8, cls, 0x30c, 4, SURF_NV10),
new MthdSifmDuDx(opt, rnd(), "src.dudx", 9, cls, 0x310, 0),
new MthdSifmDvDy(opt, rnd(), "src.dvdy", 10, cls, 0x314, 0),
new MthdSifmSrcSize(opt, rnd(), "src.size", 11, cls, 0x318, 0),
diff --git a/hwtest/pgraph_class_solid.cc b/hwtest/pgraph_class_solid.cc
index f1238fe4..41753694 100644
--- a/hwtest/pgraph_class_solid.cc
+++ b/hwtest/pgraph_class_solid.cc
@@ -94,10 +94,14 @@ class MthdSolidFormat : public SingleMthdTest {
if (extr(exp.debug[1], 20, 1))
exp.ctx_switch[1] = exp.ctx_cache[subc][1];
}
+ bool has_format = cls == 0x4a;
+ if (chipset.card_type >= 0x20 && cls == 0x5e)
+ has_format = true;
bool likes_format = false;
- if (nv04_pgraph_is_nv17p(&chipset) || chipset.chipset == 5)
+ // XXX untrue, figure it out some day
+ if (nv04_pgraph_is_nv17p(&chipset) || chipset.chipset == 5 || chipset.card_type >= 0x20)
likes_format = true;
- if (cls == 0x4a && likes_format) {
+ if (has_format && likes_format) {
insrt(exp.ctx_format, 0, 8, extr(exp.ctx_switch[1], 8, 8));
}
}
@@ -191,6 +195,17 @@ class MthdCharCode : public SingleMthdTest {
using SingleMthdTest::SingleMthdTest;
};
+class MthdVeryMissing : public SingleMthdTest {
+ bool supported() override {
+ return chipset.card_type >= 4;
+ }
+ void emulate_mthd() override {
+ insrt(exp.intr, 4, 1, 1);
+ exp.fifo_enable = 0;
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
std::vector<SingleMthdTest *> Point::mthds() {
return {
new MthdNotify(opt, rnd(), "notify", -1, cls, 0x104),
@@ -301,7 +316,7 @@ std::vector<SingleMthdTest *> Rect::mthds() {
new MthdCtxPattern(opt, rnd(), "ctx_pattern", 3, cls, 0x188, cls != 0x1e),
new MthdCtxRop(opt, rnd(), "ctx_rop", 4, cls, 0x18c),
new MthdCtxBeta(opt, rnd(), "ctx_beta", 5, cls, 0x190),
- new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200),
+ new MthdVeryMissing(opt, rnd(), "missing", -1, cls, 0x200),
new MthdOperation(opt, rnd(), "operation", 8, cls, 0x2fc, cls != 0x1e),
new MthdSolidFormat(opt, rnd(), "format", 9, cls, 0x300, cls != 0x1e),
new MthdSolidColor(opt, rnd(), "color", 10, cls, 0x304),
diff --git a/hwtest/pgraph_class_surf.cc b/hwtest/pgraph_class_surf.cc
index 5bdf23c5..5535dd87 100644
--- a/hwtest/pgraph_class_surf.cc
+++ b/hwtest/pgraph_class_surf.cc
@@ -57,13 +57,22 @@ class MthdSurfFormat : public SingleMthdTest {
int which = cls & 3;
int fmt = 0;
if (val == 1) {
- fmt = 7;
+ if (which == 3 && chipset.card_type >= 0x20)
+ fmt = 2;
+ else
+ fmt = 7;
} else if (val == 0x01010000) {
fmt = 1;
} else if (val == 0x01000000) {
- fmt = 2;
+ if (which == 3 && chipset.card_type >= 0x20)
+ fmt = 1;
+ else
+ fmt = 2;
} else if (val == 0x01010001) {
- fmt = 6;
+ if (which == 3 && chipset.card_type >= 0x20)
+ fmt = 1;
+ else
+ fmt = 6;
}
insrt(exp.surf_format, which*4, 4, fmt);
}
@@ -144,6 +153,12 @@ class MthdSurf2DFormat : public SingleMthdTest {
using SingleMthdTest::SingleMthdTest;
};
+class MthdSurf2DFormatAlt : public MthdSurf2DFormat {
+ // yeah... no idea.
+ bool supported() override { return chipset.card_type >= 0x20; }
+ using MthdSurf2DFormat::MthdSurf2DFormat;
+};
+
class MthdSurfSwzFormat : public SingleMthdTest {
bool is_valid_val() override {
int fmt = extr(val, 0, 16);
@@ -206,7 +221,7 @@ class MthdSurfSwzFormat : public SingleMthdTest {
}
int swzx = extr(val, 16, 4);
int swzy = extr(val, 24, 4);
- if (cls == 0x9e) {
+ if (cls == 0x9e && chipset.card_type < 0x20) {
fmt = 0;
}
insrt(exp.surf_format, 20, 4, fmt);
@@ -246,7 +261,7 @@ void MthdDmaSurf::emulate_mthd() {
uint32_t base = (pobj[2] & ~0xfff) | extr(pobj[0], 20, 12);
uint32_t limit = pobj[1];
uint32_t dcls = extr(pobj[0], 0, 12);
- exp.surf_limit[which] = (limit & offset_mask) | 0xf | (dcls == 0x30) << 31;
+ exp.surf_limit[which] = (limit & offset_mask) | (chipset.card_type < 0x20 ? 0xf : 0x3f) | (dcls == 0x30) << 31;
exp.surf_base[which] = base & offset_mask;
bool bad = true;
if (dcls == 0x30 || dcls == 0x3d)
@@ -259,9 +274,13 @@ void MthdDmaSurf::emulate_mthd() {
nv04_pgraph_blowup(&exp, 0x2);
}
bool prot_err = false;
- if (extr(base, 0, 4 + kind))
+ int ekind = kind;
+ if (chipset.card_type >= 0x20 && kind == SURF_NV4 && extr(exp.debug[3], 6, 1))
+ ekind = SURF_NV10;
+ if (extr(base, 0, 4 + ekind))
prot_err = true;
- if (extr(pobj[0], 16, 2))
+ int mem = extr(pobj[0], 16, 2);
+ if (mem > (chipset.card_type < 0x20 ? 0 : 1))
prot_err = true;
if (chipset.chipset >= 5 && ((bad && chipset.card_type < 0x10) || dcls == 0x30))
prot_err = false;
@@ -273,9 +292,14 @@ void MthdDmaSurf::emulate_mthd() {
bool MthdSurfOffset::is_valid_val() {
if (chipset.card_type < 4)
return true;
- if (kind == SURF_NV3)
+ int ekind = kind;
+ if (chipset.card_type < 0x20 && cls == 0x88)
+ ekind = SURF_NV4;
+ if (chipset.card_type >= 0x20 && kind == SURF_NV4 && extr(exp.debug[3], 6, 1))
+ ekind = SURF_NV10;
+ if (ekind == SURF_NV3)
return !(val & 0xf);
- else if (kind == SURF_NV4)
+ else if (ekind == SURF_NV4)
return !(val & 0x1f);
else
return !(val & 0x3f);
@@ -298,9 +322,13 @@ bool MthdSurfPitch2::is_valid_val() {
if (!extr(val, 16, 16))
return false;
if (kind == SURF_NV4)
- return !(val & 0xe01fe01f);
- else
+ if (chipset.card_type >= 0x20 && extr(exp.debug[3], 6, 1))
+ return !(val & 0xe03fe03f);
+ else
+ return !(val & 0xe01fe01f);
+ else {
return !(val & 0x3f003f);
+ }
}
void MthdSurfPitch2::emulate_mthd() {
@@ -415,6 +443,7 @@ std::vector<SingleMthdTest *> Surf2D::mthds() {
new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180),
new MthdDmaSurf(opt, rnd(), "dma_surf_src", 2, cls, 0x184, 1, kind),
new MthdDmaSurf(opt, rnd(), "dma_surf_dst", 3, cls, 0x188, 0, kind),
+ new MthdSurf2DFormatAlt(opt, rnd(), "format_alt", 4, cls, 0x200),
new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200, 0x40),
new MthdSurf2DFormat(opt, rnd(), "format", 4, cls, 0x300),
new MthdSurfPitch2(opt, rnd(), "pitch2", 5, cls, 0x304, 1, 0, kind),
diff --git a/hwtest/pgraph_mthd.cc b/hwtest/pgraph_mthd.cc
index de275393..c8d40688 100644
--- a/hwtest/pgraph_mthd.cc
+++ b/hwtest/pgraph_mthd.cc
@@ -208,7 +208,10 @@ static void nv04_pgraph_prep_mthd(int cnum, std::mt19937 &rnd, uint32_t grobj[4]
int old_subc = extr(state->ctx_user, 13, 3);
uint32_t inst;
if (extr(addr, 2, 11) == 0) {
- insrt(grobj[0], 0, 8, cls);
+ if (!nv04_pgraph_is_nv25p(&state->chipset))
+ insrt(grobj[0], 0, 8, cls);
+ else
+ insrt(grobj[0], 0, 12, cls);
if (state->chipset.card_type >= 0x10) {
insrt(grobj[0], 23, 1, 0);
}
@@ -220,14 +223,20 @@ static void nv04_pgraph_prep_mthd(int cnum, std::mt19937 &rnd, uint32_t grobj[4]
else
reload = extr(state->debug[3], 14, 1);
if (reload) {
- insrt(grobj[0], 0, 8, cls);
+ if (!nv04_pgraph_is_nv25p(&state->chipset))
+ insrt(grobj[0], 0, 8, cls);
+ else
+ insrt(grobj[0], 0, 12, cls);
if (state->chipset.card_type >= 0x10) {
insrt(grobj[0], 23, 1, 0);
}
if (rnd() & 3)
grobj[3] = 0;
} else {
- insrt(state->ctx_cache[subc][0], 0, 8, cls);
+ if (!nv04_pgraph_is_nv25p(&state->chipset))
+ insrt(state->ctx_cache[subc][0], 0, 8, cls);
+ else
+ insrt(state->ctx_cache[subc][0], 0, 12, cls);
if (nv04_pgraph_is_nv15p(&state->chipset)) {
insrt(state->ctx_cache[subc][0], 23, 1, 0);
}
@@ -236,7 +245,10 @@ static void nv04_pgraph_prep_mthd(int cnum, std::mt19937 &rnd, uint32_t grobj[4]
}
inst = state->ctx_cache[subc][3];
} else {
- insrt(state->ctx_switch[0], 0, 8, cls);
+ if (!nv04_pgraph_is_nv25p(&state->chipset))
+ insrt(state->ctx_switch[0], 0, 8, cls);
+ else
+ insrt(state->ctx_switch[0], 0, 12, cls);
inst = state->ctx_switch[3];
if (rnd() & 3)
state->ctx_switch[4] = 0;
@@ -261,17 +273,19 @@ static void nv04_pgraph_mthd(struct pgraph_state *state, uint32_t grobj[4], int
if (ctxsw) {
state->ctx_cache[subc][3] = state->fifo_data_st2[0] & 0xffff;
}
- uint32_t ctxs_mask, ctxc_mask;
+ uint32_t ctxc_mask;
if (state->chipset.chipset < 5)
- ctxs_mask = ctxc_mask = 0x0303f0ff;
+ ctxc_mask = 0x0303f0ff;
else if (state->chipset.card_type < 0x10)
- ctxs_mask = ctxc_mask = 0x7f73f0ff;
+ ctxc_mask = 0x7f73f0ff;
else if (!nv04_pgraph_is_nv15p(&state->chipset))
- ctxs_mask = 0x7fb3f0ff, ctxc_mask = 0x7f33f0ff;
+ ctxc_mask = 0x7f33f0ff;
else if (!nv04_pgraph_is_nv11p(&state->chipset))
- ctxs_mask = ctxc_mask = 0x7fb3f0ff;
+ ctxc_mask = 0x7fb3f0ff;
+ else if (!nv04_pgraph_is_nv25p(&state->chipset))
+ ctxc_mask = 0x7ffff0ff;
else
- ctxs_mask = ctxc_mask = 0x7ffff0ff;
+ ctxc_mask = 0x7fffffff;
bool reload = false;
if (state->chipset.card_type < 0x10)
reload = extr(state->debug[1], 15, 1);
diff --git a/hwtest/pgraph_mthd.h b/hwtest/pgraph_mthd.h
index a1c0e7ec..6a005f8c 100644
--- a/hwtest/pgraph_mthd.h
+++ b/hwtest/pgraph_mthd.h
@@ -94,7 +94,7 @@ class MthdSync : public SingleMthdTest {
class MthdMissing : public SingleMthdTest {
bool supported() override {
- return chipset.card_type >= 4;
+ return chipset.card_type >= 4 && chipset.card_type < 0x20;
}
void emulate_mthd() override {
insrt(exp.intr, 4, 1, 1);
@@ -404,6 +404,8 @@ class MthdCtxSurf2D : public SingleMthdTest {
return chipset.chipset >= 5;
}
bool is_valid_mthd() override {
+ if (chipset.card_type >= 0x20 && ((cls & 0xff) == 0x7b || cls == 0x79))
+ return true;
return extr(exp.debug[3], 29, 1);
}
bool takes_ctxobj() override { return true; }
diff --git a/hwtest/pgraph_mthd_grobj.cc b/hwtest/pgraph_mthd_grobj.cc
index 6a6392b5..db0cc754 100644
--- a/hwtest/pgraph_mthd_grobj.cc
+++ b/hwtest/pgraph_mthd_grobj.cc
@@ -32,7 +32,10 @@ namespace pgraph {
void MthdOperation::emulate_mthd() {
if (!extr(exp.nsource, 1, 1)) {
- insrt(egrobj[0], 8, 24, extr(exp.ctx_switch[0], 8, 24));
+ if (chipset.card_type < 0x20)
+ insrt(egrobj[0], 8, 24, extr(exp.ctx_switch[0], 8, 24));
+ else
+ egrobj[0] = exp.ctx_switch[0];
insrt(egrobj[0], 15, 3, val);
exp.ctx_cache[subc][0] = exp.ctx_switch[0];
insrt(exp.ctx_cache[subc][0], 15, 3, val);
@@ -52,7 +55,10 @@ void MthdDither::emulate_mthd() {
if ((val & 3) == 3)
rval = 3;
if (!extr(exp.nsource, 1, 1)) {
- insrt(egrobj[0], 8, 24, extr(exp.ctx_switch[0], 8, 24));
+ if (chipset.card_type < 0x20)
+ insrt(egrobj[0], 8, 24, extr(exp.ctx_switch[0], 8, 24));
+ else
+ egrobj[0] = exp.ctx_switch[0];
insrt(egrobj[0], 20, 2, rval);
exp.ctx_cache[subc][0] = exp.ctx_switch[0];
insrt(exp.ctx_cache[subc][0], 20, 2, rval);
@@ -75,7 +81,10 @@ void MthdPatch::emulate_mthd() {
}
}
if (!extr(exp.nsource, 1, 1) && !extr(exp.intr, 4, 1)) {
- insrt(egrobj[0], 24, 8, extr(exp.ctx_switch[0], 24, 8));
+ if (chipset.card_type < 0x20)
+ insrt(egrobj[0], 24, 8, extr(exp.ctx_switch[0], 24, 8));
+ else
+ egrobj[0] = exp.ctx_switch[0];
insrt(egrobj[0], 24, 1, 0);
}
} else {
@@ -161,7 +170,10 @@ static void nv04_pgraph_set_ctx(struct pgraph_state *state, uint32_t grobj[4], u
nv04_pgraph_blowup(state, 2);
if (!extr(state->nsource, 1, 1)) {
if (state->chipset.card_type >= 0x10) {
- insrt(grobj[0], 8, 24, extr(state->ctx_switch[0], 8, 24));
+ if (state->chipset.card_type < 0x20)
+ insrt(grobj[0], 8, 24, extr(state->ctx_switch[0], 8, 24));
+ else
+ grobj[0] = state->ctx_switch[0];
insrt(grobj[0], bit, 1, ccls != 0x30);
}
int subc = extr(state->ctx_user, 13, 3);
@@ -216,7 +228,10 @@ void MthdCtxSurf::emulate_mthd() {
nv04_pgraph_blowup(&exp, 2);
if (!extr(exp.nsource, 1, 1)) {
if (chipset.card_type >= 0x10) {
- insrt(egrobj[0], 8, 24, extr(exp.ctx_switch[0], 8, 24));
+ if (chipset.card_type < 0x20)
+ insrt(egrobj[0], 8, 24, extr(exp.ctx_switch[0], 8, 24));
+ else
+ egrobj[0] = exp.ctx_switch[0];
insrt(egrobj[0], 25 + (which & 1), 1, ccls != 0x30);
if (which == 0 || which == 2)
insrt(egrobj[0], 14, 1, isswz);
@@ -252,7 +267,10 @@ void MthdCtxSurf2D::emulate_mthd() {
nv04_pgraph_blowup(&exp, 2);
if (!extr(exp.nsource, 1, 1)) {
if (chipset.card_type >= 0x10) {
- insrt(egrobj[0], 8, 24, extr(exp.ctx_switch[0], 8, 24));
+ if (chipset.card_type < 0x20)
+ insrt(egrobj[0], 8, 24, extr(exp.ctx_switch[0], 8, 24));
+ else
+ egrobj[0] = exp.ctx_switch[0];
insrt(egrobj[0], 25, 1, ccls != 0x30);
insrt(egrobj[0], 14, 1, isswz);
}
@@ -291,7 +309,10 @@ void MthdCtxSurf3D::emulate_mthd() {
} else {
if (!extr(exp.nsource, 1, 1)) {
if (chipset.card_type >= 0x10) {
- insrt(egrobj[0], 8, 24, extr(exp.ctx_switch[0], 8, 24));
+ if (chipset.card_type < 0x20)
+ insrt(egrobj[0], 8, 24, extr(exp.ctx_switch[0], 8, 24));
+ else
+ egrobj[0] = exp.ctx_switch[0];
insrt(egrobj[0], 25, 1, ccls != 0x30);
insrt(egrobj[0], 14, 1, isswz);
}
diff --git a/hwtest/pgraph_mthd_misc.cc b/hwtest/pgraph_mthd_misc.cc
index f10cb5f9..0430fe0f 100644
--- a/hwtest/pgraph_mthd_misc.cc
+++ b/hwtest/pgraph_mthd_misc.cc
@@ -112,6 +112,8 @@ class MthdNopTest : public MthdTest {
void choose_mthd() override {
mthd = 0x100;
cls = rnd() & 0xff;
+ if (nv04_pgraph_is_nv25p(&chipset) && rnd() & 1)
+ cls = rnd() & 0xfff;
trapbit = -1;
}
bool is_valid_val() override {
@@ -122,6 +124,8 @@ class MthdNopTest : public MthdTest {
void emulate_mthd_pre() override {
if (sync) {
trapbit = 0;
+ if (chipset.card_type >= 0x20 && nv04_pgraph_is_3d_class(&exp))
+ trapbit = -1;
}
}
void emulate_mthd() override {
@@ -173,6 +177,8 @@ void MthdNop::adjust_orig_mthd() {
void MthdNop::emulate_mthd_pre() {
if (sync) {
trapbit = 0;
+ if (chipset.card_type >= 0x20 && nv04_pgraph_is_3d_class(&exp))
+ trapbit = -1;
}
}
@@ -273,7 +279,7 @@ void MthdFlipBumpWrite::emulate_mthd() {
bool PGraphMthdMiscTests::supported() {
- return chipset.card_type < 0x20;
+ return chipset.card_type < 0x30;
}
Test::Subtests PGraphMthdMiscTests::subtests() {
diff --git a/include/nvhw/pgraph.h b/include/nvhw/pgraph.h
index a167848e..277b1f5d 100644
--- a/include/nvhw/pgraph.h
+++ b/include/nvhw/pgraph.h
@@ -340,14 +340,31 @@ uint32_t pgraph_celsius_short_to_float(struct pgraph_state *state, int16_t val);
uint32_t pgraph_celsius_nshort_to_float(int16_t val);
void pgraph_celsius_icmd(struct pgraph_state *state, int cmd, uint32_t val);
+static inline bool nv04_pgraph_is_nv11p(const struct chipset_info *chipset) {
+ return chipset->chipset > 0x10 && chipset->chipset != 0x15;
+}
+
+static inline bool nv04_pgraph_is_nv15p(const struct chipset_info *chipset) {
+ return chipset->chipset > 0x10;
+}
+
+static inline bool nv04_pgraph_is_nv17p(const struct chipset_info *chipset) {
+ return chipset->chipset >= 0x17 && chipset->chipset != 0x1a && chipset->card_type < 0x20;
+}
+
+static inline bool nv04_pgraph_is_nv25p(const struct chipset_info *chipset) {
+ return chipset->chipset >= 0x25 && chipset->chipset != 0x2a;
+}
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 {
+ } else if (!nv04_pgraph_is_nv25p(&state->chipset)) {
return extr(state->ctx_switch[0], 0, 8);
+ } else {
+ return extr(state->ctx_switch[0], 0, 12);
}
}
@@ -391,22 +408,6 @@ static inline bool nv01_pgraph_is_drawable_class(int cls) {
return nv01_pgraph_is_solid_class(cls) || (cls >= 0x10 && cls <= 0x13);
}
-static inline bool nv04_pgraph_is_nv11p(const struct chipset_info *chipset) {
- return chipset->chipset > 0x10 && chipset->chipset != 0x15;
-}
-
-static inline bool nv04_pgraph_is_nv15p(const struct chipset_info *chipset) {
- return chipset->chipset > 0x10;
-}
-
-static inline bool nv04_pgraph_is_nv17p(const struct chipset_info *chipset) {
- return chipset->chipset >= 0x17 && chipset->chipset != 0x1a && chipset->card_type < 0x20;
-}
-
-static inline bool nv04_pgraph_is_nv25p(const struct chipset_info *chipset) {
- return chipset->chipset >= 0x25 && chipset->chipset != 0x2a;
-}
-
static inline uint32_t pgraph_offset_mask(const struct chipset_info *chipset) {
if (chipset->chipset < 4)
return chipset->is_nv03t ? 0x007ffff0 : 0x003ffff0;
diff --git a/nvhw/pgraph_xy4.c b/nvhw/pgraph_xy4.c
index 7373a469..b563651b 100644
--- a/nvhw/pgraph_xy4.c
+++ b/nvhw/pgraph_xy4.c
@@ -48,7 +48,7 @@ uint32_t nv04_pgraph_hswap(struct pgraph_state *state, uint32_t val) {
bool nv04_pgraph_is_syncable_class(struct pgraph_state *state) {
if (!nv04_pgraph_is_nv15p(&state->chipset))
return false;
- int cls = extr(state->ctx_switch[0], 0, 8);
+ int cls = pgraph_class(state);
bool alt = extr(state->debug[3], 16, 1) && state->chipset.card_type >= 0x10;
switch (cls) {
case 0x8a:
@@ -66,6 +66,7 @@ bool nv04_pgraph_is_syncable_class(struct pgraph_state *state) {
return state->chipset.card_type >= 0x10 && alt;
case 0x94:
case 0x95:
+ return nv04_pgraph_is_nv15p(&state->chipset) && state->chipset.card_type < 0x20;
case 0x96:
case 0x9e:
case 0x9f:
@@ -78,7 +79,6 @@ bool nv04_pgraph_is_syncable_class(struct pgraph_state *state) {
case 0x39:
case 0x42:
case 0x52:
- case 0x53:
case 0x5c:
case 0x5d:
case 0x5e:
@@ -92,10 +92,12 @@ bool nv04_pgraph_is_syncable_class(struct pgraph_state *state) {
case 0x66:
case 0x64:
case 0x60:
+ return nv04_pgraph_is_nv11p(&state->chipset);
+ case 0x53:
case 0x54:
case 0x55:
case 0x93:
- return nv04_pgraph_is_nv11p(&state->chipset);
+ return nv04_pgraph_is_nv11p(&state->chipset) && state->chipset.card_type < 0x20;
case 0x63:
return nv04_pgraph_is_nv11p(&state->chipset) && !alt;
case 0x67:
@@ -103,13 +105,15 @@ bool nv04_pgraph_is_syncable_class(struct pgraph_state *state) {
case 0x98:
case 0x99:
return nv04_pgraph_is_nv17p(&state->chipset);
+ case 0x97:
+ return state->chipset.card_type >= 0x20;
default:
return false;
}
}
bool nv04_pgraph_is_sync_class(struct pgraph_state *state) {
- int cls = extr(state->ctx_switch[0], 0, 8);
+ int cls = pgraph_class(state);
bool alt = extr(state->debug[3], 16, 1) && state->chipset.card_type >= 0x10;
switch (cls) {
case 0x8a:
@@ -127,22 +131,25 @@ bool nv04_pgraph_is_sync_class(struct pgraph_state *state) {
return state->chipset.card_type >= 0x10 && alt;
case 0x94:
case 0x95:
+ return nv04_pgraph_is_nv15p(&state->chipset) && state->chipset.card_type < 0x20;
case 0x96:
case 0x9e:
case 0x9f:
return nv04_pgraph_is_nv15p(&state->chipset);
case 0x93:
- return nv04_pgraph_is_nv11p(&state->chipset);
+ return nv04_pgraph_is_nv11p(&state->chipset) && state->chipset.card_type < 0x20;
case 0x98:
case 0x99:
return nv04_pgraph_is_nv17p(&state->chipset);
+ case 0x97:
+ return state->chipset.card_type >= 0x20;
default:
return false;
}
}
bool nv04_pgraph_is_sync(struct pgraph_state *state) {
- int cls = extr(state->ctx_switch[0], 0, 8);
+ int cls = pgraph_class(state);
bool alt = extr(state->debug[3], 16, 1) && state->chipset.card_type >= 0x10;
if (state->chipset.card_type < 0x10)
return false;
@@ -163,21 +170,19 @@ bool nv04_pgraph_is_sync(struct pgraph_state *state) {
}
bool nv04_pgraph_is_3d_class(struct pgraph_state *state) {
- int cls = extr(state->ctx_switch[0], 0, 8);
+ int cls = pgraph_class(state);
bool alt = extr(state->debug[3], 16, 1) && state->chipset.card_type >= 0x10;
- if (state->chipset.card_type >= 0x20)
- return false;
switch (cls) {
case 0x48:
return state->chipset.chipset <= 0x10;
case 0x54:
case 0x55:
- return true;
+ return state->chipset.card_type < 0x20;
case 0x56:
return state->chipset.card_type >= 0x10 && !alt;
case 0x94:
case 0x95:
- return state->chipset.card_type >= 0x10;
+ return state->chipset.card_type >= 0x10 && state->chipset.card_type < 0x20;
case 0x96:
return nv04_pgraph_is_nv15p(&state->chipset);
case 0x98:
@@ -185,12 +190,16 @@ bool nv04_pgraph_is_3d_class(struct pgraph_state *state) {
return nv04_pgraph_is_nv17p(&state->chipset);
case 0x85:
return alt;
+ case 0x97:
+ return state->chipset.card_type >= 0x20;
+ case 0x597:
+ return nv04_pgraph_is_nv25p(&state->chipset);
}
return false;
}
bool nv04_pgraph_is_clip3d_class(struct pgraph_state *state) {
- int cls = extr(state->ctx_switch[0], 0, 8);
+ int cls = pgraph_class(state);
bool alt = extr(state->debug[3], 16, 1) && state->chipset.card_type >= 0x10;
if (state->chipset.card_type != 0x10)
return false;
@@ -209,7 +218,7 @@ bool nv04_pgraph_is_clip3d_class(struct pgraph_state *state) {
}
bool nv04_pgraph_is_oclip_class(struct pgraph_state *state) {
- int cls = extr(state->ctx_switch[0], 0, 8);
+ int cls = pgraph_class(state);
bool alt = extr(state->debug[3], 16, 1) && state->chipset.card_type >= 0x10;
switch (cls) {
/* SIFC */
@@ -237,7 +246,7 @@ bool nv04_pgraph_is_oclip_class(struct pgraph_state *state) {
}
bool nv04_pgraph_is_new_render_class(struct pgraph_state *state) {
- int cls = extr(state->ctx_switch[0], 0, 8);
+ int cls = pgraph_class(state);
bool alt = extr(state->debug[3], 16, 1) && state->chipset.card_type >= 0x10;
switch (cls) {
return true;
@@ -309,7 +318,7 @@ int nv04_pgraph_clip_status(struct pgraph_state *state, int32_t coord, int xy) {
int cstat = 0;
int32_t clip_min[2], clip_max[2];
nv04_pgraph_clip_bounds(state, clip_min, clip_max);
- if (nv04_pgraph_is_3d_class(state)) {
+ if (nv04_pgraph_is_3d_class(state) && state->chipset.card_type < 0x20) {
coord = extrs(coord, 4, 12);
} else {
coord = extrs(coord, 0, 18);
@@ -335,7 +344,7 @@ void nv04_pgraph_vtx_fixup(struct pgraph_state *state, int xy, int idx, int32_t
void nv04_pgraph_iclip_fixup(struct pgraph_state *state, int xy, int32_t coord) {
int32_t clip_min[2], clip_max[2];
nv04_pgraph_clip_bounds(state, clip_min, clip_max);
- if (nv04_pgraph_is_3d_class(state)) {
+ if (nv04_pgraph_is_3d_class(state) && state->chipset.card_type < 0x20) {
coord = extrs(coord, 4, 12);
} else {
coord = extrs(coord, 0, 18);
@@ -364,13 +373,13 @@ void nv04_pgraph_uclip_write(struct pgraph_state *state, int which, int xy, int
}
int vidx = state->chipset.card_type < 0x10 ? 13 : 9;
state->vtx_xy[vidx][xy] = coord;
- int cls = extr(state->ctx_switch[0], 0, 8);
+ int cls = pgraph_class(state);
if (cls == 0x53 && state->chipset.chipset == 4 && which == 0)
state->uclip_min[which][xy] = 0;
}
uint32_t nv04_pgraph_formats(struct pgraph_state *state) {
- int cls = extr(state->ctx_switch[0], 0, 8);
+ int cls = pgraph_class(state);
uint32_t src = extr(state->ctx_switch[1], 8, 8);
uint32_t surf = extr(state->surf_format, 0, 4);
bool dither = extr(state->debug[3], 12, 1);