diff options
author | Marcin KoĆcielnicki <koriakin@0x04.net> | 2016-12-30 20:27:16 +0000 |
---|---|---|
committer | Marcin KoĆcielnicki <koriakin@0x04.net> | 2016-12-30 20:27:16 +0000 |
commit | e14f0d144548fd95529ed719fa173b66d01e644f (patch) | |
tree | a9005276050fb0dc6a301d9ab0ddc02a0af69853 | |
parent | ec493bb6f07fa89d6ea2d58552c99252d5322b4f (diff) |
hwtest/pgraph: Initial Kelvin method support.
-rw-r--r-- | hwtest/CMakeLists.txt | 1 | ||||
-rw-r--r-- | hwtest/pgraph.cc | 21 | ||||
-rw-r--r-- | hwtest/pgraph_class.h | 10 | ||||
-rw-r--r-- | hwtest/pgraph_class_sifm.cc | 2 | ||||
-rw-r--r-- | hwtest/pgraph_class_solid.cc | 21 | ||||
-rw-r--r-- | hwtest/pgraph_class_surf.cc | 51 | ||||
-rw-r--r-- | hwtest/pgraph_mthd.cc | 34 | ||||
-rw-r--r-- | hwtest/pgraph_mthd.h | 4 | ||||
-rw-r--r-- | hwtest/pgraph_mthd_grobj.cc | 35 | ||||
-rw-r--r-- | hwtest/pgraph_mthd_misc.cc | 8 | ||||
-rw-r--r-- | include/nvhw/pgraph.h | 35 | ||||
-rw-r--r-- | nvhw/pgraph_xy4.c | 45 |
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); |