diff options
author | Marcin Kościelnicki <koriakin@0x04.net> | 2016-12-22 21:10:09 +0000 |
---|---|---|
committer | Marcin Kościelnicki <koriakin@0x04.net> | 2016-12-22 21:10:09 +0000 |
commit | 0336841057dc4a2fa7c1111fad3e4217b80d8fd7 (patch) | |
tree | 30c3d718e819f834b148bb974c4b32803da707b4 | |
parent | 307feb62387c275b9780d2abdddd16479ee11eef (diff) |
hwtest/pgraph: Start grouping method tests by class.
26 files changed, 1415 insertions, 1315 deletions
diff --git a/hwtest/CMakeLists.txt b/hwtest/CMakeLists.txt index 9e0d1b8c..0a8a9135 100644 --- a/hwtest/CMakeLists.txt +++ b/hwtest/CMakeLists.txt @@ -13,9 +13,12 @@ if (NOT DISABLE_HWTEST) add_executable(hwtest hwtest.cc pgraph.cc pgraph_state.cc pgraph_scan.cc pgraph_state_tests.cc - pgraph_mthd.cc pgraph_mthd_simple.cc pgraph_mthd_surf.cc - pgraph_mthd_m2mf.cc pgraph_mthd_sifm.cc pgraph_mthd_d3d0.cc + pgraph_mthd.cc pgraph_mthd_simple.cc + pgraph_mthd_sifm.cc pgraph_mthd_xy.cc pgraph_mthd_invalid.cc pgraph_mthd_misc.cc + pgraph_class_op.cc pgraph_class_ctx.cc + pgraph_class_clip.cc pgraph_class_surf.cc + pgraph_class_m2mf.cc pgraph_class_d3d0.cc pgraph_rop.cc nv04_pgraph.cc vram.cc nv10_tile.cc nv50_ptherm.cc nv84_ptherm.cc diff --git a/hwtest/g80_gr.cc b/hwtest/g80_gr.cc index 7fec468f..b56bbb38 100644 --- a/hwtest/g80_gr.cc +++ b/hwtest/g80_gr.cc @@ -319,7 +319,7 @@ public: return HWTEST_RES_NA; return HWTEST_RES_PASS; } - std::vector<std::pair<const char *, Test *>> subtests() override { + Subtests subtests() override { return { {"isa_int", new hwtest::OldTestGroup(opt, rnd(), &g80_int_group)}, {"isa_fp", new hwtest::OldTestGroup(opt, rnd(), &g80_fp_group)}, diff --git a/hwtest/hwtest.cc b/hwtest/hwtest.cc index 4ed337b7..ac483df4 100644 --- a/hwtest/hwtest.cc +++ b/hwtest/hwtest.cc @@ -52,7 +52,7 @@ int hwtest::RepeatTest::run() { namespace { -int hwtest_run_group(hwtest::TestOptions &opt, const char *gname, hwtest::Test *group, int indent, const char *filter, bool boring = false) { +int hwtest_run_group(hwtest::TestOptions &opt, std::string gname, hwtest::Test *group, int indent, const char *filter, bool boring = false) { static const char *const tabn[] = { [HWTEST_RES_NA] = "n/a", [HWTEST_RES_PASS] = "passed", @@ -75,17 +75,17 @@ int hwtest_run_group(hwtest::TestOptions &opt, const char *gname, hwtest::Test * bool sboring = group->subtests_boring(); auto subtests = group->subtests(); if (pres != HWTEST_RES_PASS || !subtests.size()) { - if (gname && (!boring || pres > HWTEST_RES_PASS)) { + if (gname != "" && (!boring || pres > HWTEST_RES_PASS)) { for (int j = 0; j < indent; j++) printf(" "); - printf("%s: %s\n", gname, tab[pres]); + printf("%s: %s\n", gname.c_str(), tab[pres]); } return pres; } - if (gname && !boring) { + if (gname != "" && !boring) { for (int j = 0; j < indent; j++) printf(" "); - printf("%s...\n", gname); + printf("%s...\n", gname.c_str()); indent++; } int worst = 0; @@ -104,7 +104,7 @@ int hwtest_run_group(hwtest::TestOptions &opt, const char *gname, hwtest::Test * for (auto &sub : subtests) { auto &name = sub.first; auto &test = sub.second; - if (filter && (strlen(name) != flen || strncmp(name, filter, flen))) + if (filter && name != std::string(filter, 0, flen)) continue; found = true; int res = hwtest_run_group(opt, name, test, indent, fnext, sboring); @@ -116,18 +116,18 @@ int hwtest_run_group(hwtest::TestOptions &opt, const char *gname, hwtest::Test * printf("No tests found for %s!\n", filter); return HWTEST_RES_NA; } - if (gname && (!boring || worst > HWTEST_RES_PASS)) { + if (gname != "" && (!boring || worst > HWTEST_RES_PASS)) { indent--; for (int j = 0; j < indent; j++) printf(" "); - printf("%s: %s\n", gname, tab[worst]); + printf("%s: %s\n", gname.c_str(), tab[worst]); } return worst; } class RootTest : public hwtest::Test { public: - std::vector<std::pair<const char *, Test *>> subtests() override { + Subtests subtests() override { return { {"pgraph", pgraph_tests(opt, rnd())}, {"nv04_pgraph", new hwtest::OldTestGroup(opt, rnd(), &nv04_pgraph_group)}, @@ -200,9 +200,9 @@ int main(int argc, char **argv) { int worst = 0; if (optind == argc) { printf("Running all tests...\n"); - worst = hwtest_run_group(opt, nullptr, root, 0, nullptr); + worst = hwtest_run_group(opt, "", root, 0, nullptr); } else while (optind < argc) { - int res = hwtest_run_group(opt, nullptr, root, 0, argv[optind++]); + int res = hwtest_run_group(opt, "", root, 0, argv[optind++]); if (res > worst) worst = res; } diff --git a/hwtest/hwtest.h b/hwtest/hwtest.h index 9809b109..cf410ace 100644 --- a/hwtest/hwtest.h +++ b/hwtest/hwtest.h @@ -29,6 +29,7 @@ #include "nvhw/chipset.h" #include <stdint.h> #include <vector> +#include <string> #include <utility> #include <random> @@ -55,7 +56,7 @@ namespace hwtest { int cnum; struct chipset_info chipset; public: - typedef std::vector<std::pair<const char *, Test *>> Subtests; + typedef std::vector<std::pair<std::string, Test *>> Subtests; virtual ~Test() {} virtual int run() { return HWTEST_RES_PASS; @@ -69,7 +70,6 @@ namespace hwtest { virtual bool subtests_boring() { return false; } - protected: Test(TestOptions &opt, uint32_t seed); }; diff --git a/hwtest/nv04_pgraph.cc b/hwtest/nv04_pgraph.cc index 9e4adcda..b84bafb1 100644 --- a/hwtest/nv04_pgraph.cc +++ b/hwtest/nv04_pgraph.cc @@ -524,102 +524,8 @@ static int test_invalid_class(struct hwtest_ctx *ctx) { return HWTEST_RES_PASS; } -static int test_invalid_mthd_op(struct hwtest_ctx *ctx) { - if (ctx->chipset.chipset != 4) - return HWTEST_RES_NA; - for (int cls : {0x10, 0x11, 0x13, 0x15, 0x64, 0x65, 0x66, 0x67}) { - for (int mthd = 0; mthd < 0x2000; mthd += 4) { - if (mthd == 0) - continue; - if (mthd == 0x100) - continue; - if (mthd == 0x104) - continue; - if (mthd == 0x140 && ctx->chipset.card_type >= 0x10) - continue; - if (mthd == 0x180) - continue; - if (mthd == 0x200 || mthd == 0x204) - continue; - if (mthd == 0x208 && (cls == 0x11 || cls == 0x13 || cls == 0x66 || cls == 0x67)) - continue; - for (int i = 0; i < 10; i++) { - uint32_t val = jrand48(ctx->rand48); - uint32_t addr = (jrand48(ctx->rand48) & 0xe000) | mthd; - struct pgraph_state orig, exp, real; - nv04_pgraph_gen_state(ctx, &orig); - orig.notify &= ~0x10000; - uint32_t grobj[4]; - nv04_pgraph_prep_mthd(ctx, grobj, &orig, cls, addr, val); - nv04_pgraph_load_state(ctx, &orig); - exp = orig; - nv04_pgraph_mthd(&exp, grobj); - nv04_pgraph_blowup(&exp, 0x0040); - nv04_pgraph_dump_state(ctx, &real); - if (nv04_pgraph_cmp_state(&orig, &exp, &real)) { - printf("Iter %d mthd %02x.%04x %08x\n", i, cls, addr, val); - return HWTEST_RES_FAIL; - } - } - } - } - return HWTEST_RES_PASS; -} - -static int test_invalid_mthd_ctx(struct hwtest_ctx *ctx) { - for (int cls : {0x12, 0x72, 0x43, 0x19, 0x17, 0x57, 0x18, 0x44}) { - for (int mthd = 0; mthd < 0x2000; mthd += 4) { - if (mthd == 0) - continue; - if (mthd == 0x100) - continue; - if (mthd == 0x104) - continue; - if (mthd == 0x140 && ctx->chipset.card_type >= 0x10) - continue; - if (mthd == 0x180) - continue; - if (mthd == 0x200) - continue; - if ((cls == 0x12 || cls == 0x72 || cls == 0x43) && mthd == 0x300) - continue; - if (cls == 0x19 && (mthd == 0x300 || mthd == 0x304)) - continue; - if ((cls == 0x17 || cls == 0x57) && (mthd == 0x300 || mthd == 0x304)) - continue; - if ((cls == 0x18 || cls == 0x44) && (mthd == 0x300 || mthd == 0x304 || mthd == 0x308 || (mthd & 0x1ff0) == 0x310)) - continue; - if (cls == 0x44 && (mthd == 0x30c || - (mthd & 0x1fc0) == 0x400 || - (mthd & 0x1f80) == 0x500 || - (mthd & 0x1f80) == 0x600 || - (mthd & 0x1f00) == 0x700)) - continue; - for (int i = 0; i < 10; i++) { - uint32_t val = jrand48(ctx->rand48); - uint32_t addr = (jrand48(ctx->rand48) & 0xe000) | mthd; - struct pgraph_state orig, exp, real; - nv04_pgraph_gen_state(ctx, &orig); - orig.notify &= ~0x10000; - uint32_t grobj[4]; - nv04_pgraph_prep_mthd(ctx, grobj, &orig, cls, addr, val); - nv04_pgraph_load_state(ctx, &orig); - exp = orig; - nv04_pgraph_mthd(&exp, grobj); - nv04_pgraph_blowup(&exp, 0x0040); - nv04_pgraph_dump_state(ctx, &real); - if (nv04_pgraph_cmp_state(&orig, &exp, &real)) { - printf("Iter %d mthd %02x.%04x %08x\n", i, cls, addr, val); - return HWTEST_RES_FAIL; - } - } - } - } - return HWTEST_RES_PASS; -} - static int test_invalid_mthd_surf(struct hwtest_ctx *ctx) { - for (int cls : {0x42, 0x62, 0x82, 0x52, 0x9e, 0x53, 0x93, 0x58, 0x59, 0x5a, 0x5b}) { + for (int cls : {0x42, 0x62, 0x82, 0x52, 0x9e, 0x53, 0x93}) { if ((cls == 0x62 || cls == 0x82 || cls == 0x93) && ctx->chipset.card_type < 0x10) continue; if (cls == 0x9e && !nv04_pgraph_is_nv15p(&ctx->chipset)) @@ -651,8 +557,6 @@ static int test_invalid_mthd_surf(struct hwtest_ctx *ctx) { continue; if ((cls == 0x53 || cls == 0x93) && (mthd == 0x2f8 || mthd == 0x2fc) && ctx->chipset.chipset >= 5) continue; - if ((cls & 0xfc) == 0x58 && ((mthd & 0x1ff8) == 0x200 || mthd == 0x300 || mthd == 0x308 || mthd == 0x30c)) - continue; for (int i = 0; i < 10; i++) { uint32_t val = jrand48(ctx->rand48); uint32_t addr = (jrand48(ctx->rand48) & 0xe000) | mthd; @@ -718,44 +622,6 @@ static int test_invalid_mthd_dvd(struct hwtest_ctx *ctx) { return HWTEST_RES_PASS; } -static int test_invalid_mthd_m2mf(struct hwtest_ctx *ctx) { - for (int cls : {0x39}) { - for (int mthd = 0; mthd < 0x2000; mthd += 4) { - if (mthd == 0) - continue; - if (mthd == 0x100) - continue; - if (mthd == 0x104) - continue; - if (mthd == 0x140 && ctx->chipset.card_type >= 0x10) - continue; - if (mthd >= 0x180 && mthd <= 0x188) - continue; - if (mthd >= 0x30c && mthd <= 0x328) - continue; - for (int i = 0; i < 10; i++) { - uint32_t val = jrand48(ctx->rand48); - uint32_t addr = (jrand48(ctx->rand48) & 0xe000) | mthd; - struct pgraph_state orig, exp, real; - nv04_pgraph_gen_state(ctx, &orig); - orig.notify &= ~0x10000; - uint32_t grobj[4]; - nv04_pgraph_prep_mthd(ctx, grobj, &orig, cls, addr, val); - nv04_pgraph_load_state(ctx, &orig); - exp = orig; - nv04_pgraph_mthd(&exp, grobj); - nv04_pgraph_blowup(&exp, 0x0040); - nv04_pgraph_dump_state(ctx, &real); - if (nv04_pgraph_cmp_state(&orig, &exp, &real)) { - printf("Iter %d mthd %02x.%04x %08x\n", i, cls, addr, val); - return HWTEST_RES_FAIL; - } - } - } - } - return HWTEST_RES_PASS; -} - static int test_invalid_mthd_lin(struct hwtest_ctx *ctx) { for (int cls : {0x1c, 0x5c}) { for (int mthd = 0; mthd < 0x2000; mthd += 4) { @@ -1764,87 +1630,7 @@ static int test_mthd_missing(struct hwtest_ctx *ctx) { uint32_t cls; uint32_t mthd; switch (nrand48(ctx->rand48) % 50) { - case 0: default: - cls = 0x10; - mthd = 0x200 + (nrand48(ctx->rand48) % 2) * 4; - if (ctx->chipset.chipset != 4) - continue; - break; - case 1: - cls = 0x11; - mthd = 0x200 + (nrand48(ctx->rand48) % 3) * 4; - if (ctx->chipset.chipset != 4) - continue; - break; - case 2: - cls = 0x13; - mthd = 0x200 + (nrand48(ctx->rand48) % 3) * 4; - if (ctx->chipset.chipset != 4) - continue; - break; - case 3: - cls = 0x15; - mthd = 0x200 + (nrand48(ctx->rand48) % 2) * 4; - if (ctx->chipset.chipset != 4) - continue; - break; - case 4: - cls = 0x64; - mthd = 0x200 + (nrand48(ctx->rand48) % 2) * 4; - if (ctx->chipset.chipset != 4) - continue; - break; - case 5: - cls = 0x65; - mthd = 0x200 + (nrand48(ctx->rand48) % 2) * 4; - if (ctx->chipset.chipset != 4) - continue; - break; - case 6: - cls = 0x66; - mthd = 0x200 + (nrand48(ctx->rand48) % 3) * 4; - if (ctx->chipset.chipset != 4) - continue; - break; - case 7: - cls = 0x67; - mthd = 0x200 + (nrand48(ctx->rand48) % 3) * 4; - if (ctx->chipset.chipset != 4) - continue; - break; - case 8: - cls = 0x12; - mthd = 0x200; - break; - case 9: - cls = 0x72; - mthd = 0x200; - break; - case 10: - cls = 0x43; - mthd = 0x200; - break; - case 11: - cls = 0x17; - mthd = 0x200; - break; - case 12: - cls = 0x57; - mthd = 0x200; - break; - case 13: - cls = 0x18; - mthd = 0x200; - break; - case 14: - cls = 0x44; - mthd = 0x200; - break; - case 15: - cls = 0x19; - mthd = 0x200; - break; case 16: cls = get_random_surf2d(ctx); mthd = 0x200 | (jrand48(ctx->rand48) & 0xfc); @@ -1972,31 +1758,7 @@ static int test_mthd_surf_offset(struct hwtest_ctx *ctx) { bool isnv10 = false; int trapbit; switch (nrand48(ctx->rand48) % 12) { - case 0: default: - cls = 0x58; - mthd = 0x30c; - idx = 0; - trapbit = 5; - break; - case 1: - cls = 0x59; - mthd = 0x30c; - idx = 1; - trapbit = 5; - break; - case 2: - cls = 0x5a; - mthd = 0x30c; - idx = 2; - trapbit = 5; - break; - case 3: - cls = 0x5b; - mthd = 0x30c; - idx = 3; - trapbit = 5; - break; case 4: cls = get_random_surf2d(ctx); mthd = 0x308; @@ -2093,75 +1855,6 @@ static int test_mthd_surf_offset(struct hwtest_ctx *ctx) { return HWTEST_RES_PASS; } -static int test_mthd_surf_pitch(struct hwtest_ctx *ctx) { - int i; - for (i = 0; i < 10000; i++) { - uint32_t val = jrand48(ctx->rand48); - if (jrand48(ctx->rand48) & 1) { - val &= ~0xffff000f; - if (jrand48(ctx->rand48) & 1) { - val |= 1 << (jrand48(ctx->rand48) & 0x1f); - } - } - if (jrand48(ctx->rand48) & 1) { - val &= ~0xffff; - if (jrand48(ctx->rand48) & 1) { - val |= 1 << (jrand48(ctx->rand48) & 0x1f); - } - } - uint32_t cls; - uint32_t mthd; - int idx; - switch (nrand48(ctx->rand48) % 4) { - case 0: - default: - cls = 0x58; - mthd = 0x308; - idx = 0; - break; - case 1: - cls = 0x59; - mthd = 0x308; - idx = 1; - break; - case 2: - cls = 0x5a; - mthd = 0x308; - idx = 2; - break; - case 3: - cls = 0x5b; - mthd = 0x308; - idx = 3; - break; - } - uint32_t addr = (jrand48(ctx->rand48) & 0xe000) | mthd; - struct pgraph_state orig, exp, real; - nv04_pgraph_gen_state(ctx, &orig); - orig.notify &= ~0x10000; - uint32_t grobj[4]; - nv04_pgraph_prep_mthd(ctx, grobj, &orig, cls, addr, val); - nv04_pgraph_load_state(ctx, &orig); - exp = orig; - nv04_pgraph_mthd(&exp, grobj, 4); - if (!extr(exp.intr, 4, 1)) { - exp.surf_pitch[idx] = val & pgraph_pitch_mask(&ctx->chipset); - exp.valid[0] |= 4; - bool bad = !!(val & ~0x1ff0) || !(val & 0x1ff0); - if (extr(exp.debug[3], 20, 1) && bad) { - nv04_pgraph_blowup(&exp, 0x2); - } - insrt(exp.ctx_valid, 8+idx, 1, !extr(exp.nsource, 1, 1)); - } - nv04_pgraph_dump_state(ctx, &real); - if (nv04_pgraph_cmp_state(&orig, &exp, &real)) { - printf("Iter %d mthd %02x.%04x %08x\n", i, cls, addr, val); - return HWTEST_RES_FAIL; - } - } - return HWTEST_RES_PASS; -} - static int test_mthd_surf_pitch_2(struct hwtest_ctx *ctx) { int i; for (i = 0; i < 10000; i++) { @@ -2263,77 +1956,6 @@ static int test_mthd_surf_pitch_2(struct hwtest_ctx *ctx) { return HWTEST_RES_PASS; } -static int test_mthd_surf_nv3_format(struct hwtest_ctx *ctx) { - int i; - for (i = 0; i < 10000; i++) { - uint32_t val = jrand48(ctx->rand48); - if (jrand48(ctx->rand48) & 1) { - val &= 0x01010003; - if (jrand48(ctx->rand48) & 1) { - val |= 1 << (jrand48(ctx->rand48) & 0x1f); - } - } - uint32_t cls; - uint32_t mthd; - int idx; - switch (nrand48(ctx->rand48) % 4) { - case 0: - default: - cls = 0x58; - mthd = 0x300; - idx = 0; - break; - case 1: - cls = 0x59; - mthd = 0x300; - idx = 1; - break; - case 2: - cls = 0x5a; - mthd = 0x300; - idx = 2; - break; - case 3: - cls = 0x5b; - mthd = 0x300; - idx = 3; - break; - } - uint32_t addr = (jrand48(ctx->rand48) & 0xe000) | mthd; - struct pgraph_state orig, exp, real; - nv04_pgraph_gen_state(ctx, &orig); - orig.notify &= ~0x10000; - uint32_t grobj[4]; - nv04_pgraph_prep_mthd(ctx, grobj, &orig, cls, addr, val); - nv04_pgraph_load_state(ctx, &orig); - exp = orig; - nv04_pgraph_mthd(&exp, grobj, 3); - if (!extr(exp.intr, 4, 1)) { - int fmt = 0; - if (val == 1) { - fmt = 7; - } else if (val == 0x01010000) { - fmt = 1; - } else if (val == 0x01000000) { - fmt = 2; - } else if (val == 0x01010001) { - fmt = 6; - } else { - if (extr(exp.debug[3], 20, 1)) { - nv04_pgraph_blowup(&exp, 0x2); - } - } - insrt(exp.surf_format, idx*4, 4, fmt); - } - nv04_pgraph_dump_state(ctx, &real); - if (nv04_pgraph_cmp_state(&orig, &exp, &real)) { - printf("Iter %d mthd %02x.%04x %08x\n", i, cls, addr, val); - return HWTEST_RES_FAIL; - } - } - return HWTEST_RES_PASS; -} - static int test_mthd_surf_2d_format(struct hwtest_ctx *ctx) { int i; for (i = 0; i < 10000; i++) { @@ -2818,11 +2440,6 @@ static int test_mthd_clip(struct hwtest_ctx *ctx) { int trapbit = -1; switch (nrand48(ctx->rand48) % 12) { default: - cls = 0x19; - mthd = 0x300 + idx * 4; - which = 0; - trapbit = 2 + idx; - break; case 1: cls = get_random_sifc(ctx); mthd = 0x310 + idx * 4; @@ -9364,11 +8981,9 @@ namespace { HWTEST_DEF_GROUP(invalid_mthd, HWTEST_TEST(test_invalid_class, 0), - HWTEST_TEST(test_invalid_mthd_op, 0), HWTEST_TEST(test_invalid_mthd_ctx, 0), HWTEST_TEST(test_invalid_mthd_surf, 0), HWTEST_TEST(test_invalid_mthd_dvd, 0), - HWTEST_TEST(test_invalid_mthd_m2mf, 0), HWTEST_TEST(test_invalid_mthd_lin, 0), HWTEST_TEST(test_invalid_mthd_tri, 0), HWTEST_TEST(test_invalid_mthd_rect, 0), @@ -9394,9 +9009,7 @@ HWTEST_DEF_GROUP(simple_mthd, HWTEST_TEST(test_mthd_pm_trigger, 0), HWTEST_TEST(test_mthd_missing, 0), HWTEST_TEST(test_mthd_surf_offset, 0), - HWTEST_TEST(test_mthd_surf_pitch, 0), HWTEST_TEST(test_mthd_surf_pitch_2, 0), - HWTEST_TEST(test_mthd_surf_nv3_format, 0), HWTEST_TEST(test_mthd_surf_2d_format, 0), HWTEST_TEST(test_mthd_surf_swz_format, 0), HWTEST_TEST(test_mthd_surf_dvd_format, 0), diff --git a/hwtest/old.h b/hwtest/old.h index 1fa136e6..bbce5188 100644 --- a/hwtest/old.h +++ b/hwtest/old.h @@ -82,8 +82,8 @@ namespace hwtest { ctx.rand48[2] = rnd(); return group->prep(&ctx); } - virtual std::vector<std::pair<const char *, Test *>> subtests() { - std::vector<std::pair<const char *, Test *>> res; + Subtests subtests() override { + Subtests res; for (int i = 0; i < group->testsnum; i++) { auto &test = group->tests[i]; res.push_back({ diff --git a/hwtest/pgraph.cc b/hwtest/pgraph.cc index 6851d765..0fd9ea07 100644 --- a/hwtest/pgraph.cc +++ b/hwtest/pgraph.cc @@ -24,12 +24,82 @@ #include "hwtest.h" #include "pgraph.h" +#include "pgraph_class.h" #include "nva.h" namespace { using namespace hwtest::pgraph; +class PGraphClassTests : public hwtest::Test { +public: + bool supported() override { + return chipset.card_type < 0x20; + } + std::vector<Class *> classes() { + if (chipset.card_type < 3) { + return { + new Beta(opt, rnd(), 0x01, "beta"), + new Rop(opt, rnd(), 0x02, "rop"), + new Chroma(opt, rnd(), 0x03, "chroma"), + new Plane(opt, rnd(), 0x04, "plane"), + new Clip(opt, rnd(), 0x05, "clip"), + new Pattern(opt, rnd(), 0x06, "pattern"), + }; + } else if (chipset.card_type < 4) { + return { + new Beta(opt, rnd(), 0x01, "beta"), + new Rop(opt, rnd(), 0x02, "rop"), + new Chroma(opt, rnd(), 0x03, "chroma"), + new Plane(opt, rnd(), 0x04, "plane"), + new Clip(opt, rnd(), 0x05, "clip"), + new Pattern(opt, rnd(), 0x06, "pattern"), + new M2mf(opt, rnd(), 0x0d, "m2mf"), + new D3D0(opt, rnd(), 0x17, "d3d0"), + new ZPoint(opt, rnd(), 0x18, "zpoint"), + new Surf(opt, rnd(), 0x1c, "surf"), + }; + } else { + std::vector<Class *> res = { + new Beta(opt, rnd(), 0x12, "beta"), + new Beta4(opt, rnd(), 0x72, "beta4"), + new Rop(opt, rnd(), 0x43, "rop"), + new Chroma(opt, rnd(), 0x17, "chroma_nv1"), + new Chroma(opt, rnd(), 0x57, "chroma_nv4"), + new Pattern(opt, rnd(), 0x18, "pattern_nv1"), + new CPattern(opt, rnd(), 0x44, "pattern_nv4"), + new Clip(opt, rnd(), 0x19, "clip"), + new M2mf(opt, rnd(), 0x39, "m2mf"), + new Surf(opt, rnd(), 0x58, "surf_dst"), + new Surf(opt, rnd(), 0x59, "surf_src"), + new Surf(opt, rnd(), 0x5a, "surf_color"), + new Surf(opt, rnd(), 0x5b, "surf_zeta"), + }; + if (chipset.chipset < 5) { + res.insert(res.end(), { + new OpClip(opt, rnd(), 0x10, "op_clip"), + new OpBlendAnd(opt, rnd(), 0x11, "op_blend_and"), + new OpRopAnd(opt, rnd(), 0x13, "op_rop_and"), + new OpChroma(opt, rnd(), 0x15, "op_chroma"), + new OpSrccopyAnd(opt, rnd(), 0x64, "op_srccopy_and"), + new OpSrccopy(opt, rnd(), 0x65, "op_srccopy"), + new OpSrccopyPremult(opt, rnd(), 0x66, "op_srccopy_premult"), + new OpBlendPremult(opt, rnd(), 0x67, "op_blend_premult"), + }); + } + return res; + } + } + Subtests subtests() override { + Subtests res; + for (auto *cls : classes()) { + res.push_back({cls->name, new ClassTest(opt, rnd(), cls)}); + } + return res; + } + using Test::Test; +}; + class PGraphTests : public hwtest::Test { public: bool supported() override { @@ -44,16 +114,14 @@ public: nva_wr32(cnum, 0x200, 0xffffffff); return HWTEST_RES_PASS; } - std::vector<std::pair<const char *, Test *>> subtests() override { + Subtests subtests() override { return { {"scan", new PGraphScanTests(opt, rnd())}, {"state", new PGraphStateTests(opt, rnd())}, + {"class", new PGraphClassTests(opt, rnd())}, {"mthd_misc", new PGraphMthdMiscTests(opt, rnd())}, {"mthd_simple", new PGraphMthdSimpleTests(opt, rnd())}, - {"mthd_surf", new PGraphMthdSurfTests(opt, rnd())}, - {"mthd_m2mf", new PGraphMthdM2mfTests(opt, rnd())}, {"mthd_sifm", new PGraphMthdSifmTests(opt, rnd())}, - {"mthd_d3d0", new PGraphMthdD3D0Tests(opt, rnd())}, {"mthd_xy", new PGraphMthdXyTests(opt, rnd())}, {"mthd_invalid", new PGraphMthdInvalidTests(opt, rnd())}, {"rop", new PGraphRopTests(opt, rnd())}, diff --git a/hwtest/pgraph.h b/hwtest/pgraph.h index c8e9c684..8a66d1f5 100644 --- a/hwtest/pgraph.h +++ b/hwtest/pgraph.h @@ -127,25 +127,6 @@ public: StateTest(TestOptions &opt, uint32_t seed) : RepeatTest(opt, seed) {} }; -class MthdTest : public StateTest { -protected: - uint32_t cls, mthd, subc, val; - int trapbit; - uint32_t grobj[4], gctx; - virtual void choose_mthd() = 0; - virtual void emulate_mthd_pre() {}; - virtual void emulate_mthd() = 0; - virtual bool special_notify() { return false; } - virtual bool is_valid_val() { return true; } - virtual void adjust_orig_mthd() { } - virtual int gen_nv3_fmt() { return rnd() & 7; } - virtual bool fix_alt_cls() { return true; } - void adjust_orig() override; - void mutate() override; - void print_fail() override; - MthdTest(hwtest::TestOptions &opt, uint32_t seed) : StateTest(opt, seed), trapbit(-1) {} -}; - class PGraphScanTests : public Test { bool supported() override; Subtests subtests() override; @@ -181,20 +162,6 @@ public: PGraphMthdSimpleTests(TestOptions &opt, uint32_t seed) : Test(opt, seed) {} }; -class PGraphMthdSurfTests : public Test { - bool supported() override; - Subtests subtests() override; -public: - PGraphMthdSurfTests(TestOptions &opt, uint32_t seed) : Test(opt, seed) {} -}; - -class PGraphMthdM2mfTests : public Test { - bool supported() override; - Subtests subtests() override; -public: - PGraphMthdM2mfTests(TestOptions &opt, uint32_t seed) : Test(opt, seed) {} -}; - class PGraphMthdSifmTests : public Test { bool supported() override; Subtests subtests() override; @@ -202,13 +169,6 @@ public: PGraphMthdSifmTests(TestOptions &opt, uint32_t seed) : Test(opt, seed) {} }; -class PGraphMthdD3D0Tests : public Test { - bool supported() override; - Subtests subtests() override; -public: - PGraphMthdD3D0Tests(TestOptions &opt, uint32_t seed) : Test(opt, seed) {} -}; - class PGraphMthdXyTests : public Test { bool supported() override; Subtests subtests() override; diff --git a/hwtest/pgraph_class.h b/hwtest/pgraph_class.h new file mode 100644 index 00000000..f6f9d61f --- /dev/null +++ b/hwtest/pgraph_class.h @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2016 Marcin Kościelnicki <koriakin@0x04.net> + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef HWTEST_PGRAPH_CLASS_H +#define HWTEST_PGRAPH_CLASS_H + +#include "pgraph.h" +#include "pgraph_mthd.h" + +namespace hwtest { +namespace pgraph { + +class Class { +protected: + TestOptions opt; + std::mt19937 rnd; +public: + uint32_t cls; + std::string name; + virtual std::vector<SingleMthdTest *> mthds() = 0; + Class(hwtest::TestOptions &opt, uint32_t seed, uint32_t cls, const std::string &name) : opt(opt), rnd(seed), cls(cls), name(name) {} +}; + +class ClassTest : public Test { + Class *cls; + Subtests subtests() override; +public: + ClassTest(TestOptions &opt, uint32_t seed, Class *cls) + : Test(opt, seed), cls(cls) {} +}; + +class Beta : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class Beta4 : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class Rop : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class Chroma : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class Plane : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class Clip : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class Pattern : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class CPattern : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class Surf : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class M2mf : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class ZPoint : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class D3D0 : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class OpClip : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class OpBlendAnd : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class OpRopAnd : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class OpChroma : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class OpSrccopyAnd : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class OpSrccopy : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class OpSrccopyPremult : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +class OpBlendPremult : public Class { + std::vector<SingleMthdTest *> mthds() override; + using Class::Class; +}; + +} +} + +#endif diff --git a/hwtest/pgraph_class_clip.cc b/hwtest/pgraph_class_clip.cc new file mode 100644 index 00000000..77a8ca56 --- /dev/null +++ b/hwtest/pgraph_class_clip.cc @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2016 Marcin Kościelnicki <koriakin@0x04.net> + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "pgraph.h" +#include "pgraph_mthd.h" +#include "pgraph_class.h" +#include "nva.h" + +namespace hwtest { +namespace pgraph { + +class MthdClipXy : public SingleMthdTest { + int repeats() override { return 10000; }; + void adjust_orig_mthd() override { + if (!(rnd() & 3)) { + val &= ~0xffff; + } + if (!(rnd() & 3)) { + val &= ~0xffff0000; + } + if (rnd() & 1) { + val ^= 1 << (rnd() & 0x1f); + } + } + void emulate_mthd() override { + if (chipset.card_type < 3) { + nv01_pgraph_set_clip(&exp, 0, val); + } else if (chipset.card_type < 4) { + nv03_pgraph_set_clip(&exp, 0, 0, val, extr(orig.xy_misc_1[0], 0, 1)); + } else { + nv04_pgraph_set_clip(&exp, 0, 0, val); + } + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdClipRect : public SingleMthdTest { + int repeats() override { return 10000; }; + void adjust_orig_mthd() override { + if (!(rnd() & 3)) { + val &= ~0xffff; + } + if (!(rnd() & 3)) { + val &= ~0xffff0000; + } + if (rnd() & 1) { + val ^= 1 << (rnd() & 0x1f); + } + } + void emulate_mthd() override { + if (chipset.card_type < 3) { + if (pgraph_class(&exp) == 0x10) { + int n = extr(exp.valid[0], 24, 1); + insrt(exp.valid[0], 24, 1, 0); + insrt(exp.valid[0], 28, 1, !n); + exp.xy_misc_1[0] &= 0x03000331; + 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); + pgraph_prep_draw(&exp, false, false); + } else { + nv01_pgraph_set_clip(&exp, 1, val); + } + } else if (chipset.card_type < 4) { + nv03_pgraph_set_clip(&exp, 0, 1, val, extr(orig.xy_misc_1[0], 0, 1)); + } else { + nv04_pgraph_set_clip(&exp, 0, 1, val); + } + } + using SingleMthdTest::SingleMthdTest; +}; + +std::vector<SingleMthdTest *> Clip::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdPmTrigger(opt, rnd(), "pm_trigger", -1, cls, 0x140), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200), + new MthdClipXy(opt, rnd(), "clip_xy", 2, cls, 0x300), + new MthdClipRect(opt, rnd(), "clip_rect", 3, cls, 0x304), + }; +} + +} +} diff --git a/hwtest/pgraph_class_ctx.cc b/hwtest/pgraph_class_ctx.cc new file mode 100644 index 00000000..b45708df --- /dev/null +++ b/hwtest/pgraph_class_ctx.cc @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2016 Marcin Kościelnicki <koriakin@0x04.net> + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "pgraph.h" +#include "pgraph_mthd.h" +#include "pgraph_class.h" +#include "nva.h" + +namespace hwtest { +namespace pgraph { + +class MthdBeta : public SingleMthdTest { + void emulate_mthd() override { + exp.beta = val; + if (exp.beta & 0x80000000) + exp.beta = 0; + exp.beta &= 0x7f800000; + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdBeta4 : public SingleMthdTest { + void emulate_mthd() override { + exp.beta4 = val; + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdRop : public SingleMthdTest { + void adjust_orig_mthd() override { + if (rnd() & 1) { + val &= 0xff; + val ^= 1 << (rnd() & 0x1f); + } + } + bool is_valid_val() override { + return chipset.card_type >= 3 || !(val & ~0xff); + } + void emulate_mthd() override { + exp.rop = val & 0xff; + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdChroma : public SingleMthdTest { + void emulate_mthd() override { + if (chipset.card_type < 4) { + exp.chroma = pgraph_to_a1r10g10b10(pgraph_expand_color(&exp, val)); + } else { + if (cls == 0x17) + nv04_pgraph_set_chroma_nv01(&exp, val); + else + exp.chroma = val; + } + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdPlane : public SingleMthdTest { + void emulate_mthd() override { + if (chipset.card_type < 3) { + exp.plane = pgraph_to_a1r10g10b10(pgraph_expand_color(&exp, val)); + } + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdPatternShape : public SingleMthdTest { + void adjust_orig_mthd() override { + if (rnd() & 1) + val &= 0xf; + } + bool is_valid_val() override { + return val <= 2; + } + void emulate_mthd() override { + insrt(exp.pattern_config, 0, 2, val); + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdPatternSelect : public SingleMthdTest { + void adjust_orig_mthd() override { + if (rnd() & 1) + val &= 0xf; + } + bool is_valid_val() override { + return val == 1 || val == 2; + } + void emulate_mthd() override { + insrt(exp.pattern_config, 4, 1, extr(val, 1, 1)); + insrt(exp.ctx_valid, 22, 1, !extr(exp.nsource, 1, 1)); + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdPatternBitmapColor : public SingleMthdTest { + int which; + void emulate_mthd() override { + if (chipset.card_type < 4) { + struct pgraph_color c = pgraph_expand_color(&exp, val); + exp.pattern_mono_rgb[which] = c.r << 20 | c.g << 10 | c.b; + exp.pattern_mono_a[which] = c.a; + } else if (cls == 0x18) { + nv04_pgraph_set_pattern_mono_color_nv01(&exp, which, val); + } else { + exp.pattern_mono_color[which] = val; + } + } +public: + MthdPatternBitmapColor(hwtest::TestOptions &opt, uint32_t seed, const std::string &name, int trapbit, uint32_t cls, uint32_t mthd, int which) + : SingleMthdTest(opt, seed, name, trapbit, cls, mthd), which(which) {} +}; + +class MthdPatternBitmap : public SingleMthdTest { + int which; + void emulate_mthd() override { + uint32_t rval = nv04_pgraph_bswap(&exp, val); + if (chipset.card_type == 3) { + // yup, orig. hw bug. + exp.pattern_mono_bitmap[which] = pgraph_expand_mono(&orig, rval); + } else { + exp.pattern_mono_bitmap[which] = pgraph_expand_mono(&exp, rval); + } + if (chipset.card_type >= 4 && cls == 0x18) { + uint32_t fmt = extr(exp.ctx_switch[1], 0, 2); + if (fmt != 1 && fmt != 2) { + pgraph_state_error(&exp); + } + insrt(exp.ctx_valid, 26+which, 1, !extr(exp.nsource, 1, 1)); + } + } +public: + MthdPatternBitmap(hwtest::TestOptions &opt, uint32_t seed, const std::string &name, int trapbit, uint32_t cls, uint32_t mthd, int which) + : SingleMthdTest(opt, seed, name, trapbit, cls, mthd), which(which) {} +}; + +class MthdPatternColorY8 : public SingleMthdTest { + void emulate_mthd() override { + uint32_t rval = nv04_pgraph_bswap(&exp, val); + for (int i = 0; i < 4; i++) + exp.pattern_color[idx*4+i] = extr(rval, 8*i, 8) * 0x010101; + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdPatternColorR5G6B5 : public SingleMthdTest { + void emulate_mthd() override { + uint32_t rval = nv04_pgraph_hswap(&exp, val); + for (int i = 0; i < 2; i++) { + uint8_t b = extr(rval, i * 16 + 0, 5) * 0x21 >> 2; + uint8_t g = extr(rval, i * 16 + 5, 6) * 0x41 >> 4; + uint8_t r = extr(rval, i * 16 + 11, 5) * 0x21 >> 2; + exp.pattern_color[idx*2+i] = b | g << 8 | r << 16; + } + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdPatternColorR5G5B5 : public SingleMthdTest { + void emulate_mthd() override { + uint32_t rval = nv04_pgraph_hswap(&exp, val); + for (int i = 0; i < 2; i++) { + uint8_t b = extr(rval, i * 16 + 0, 5) * 0x21 >> 2; + uint8_t g = extr(rval, i * 16 + 5, 5) * 0x21 >> 2; + uint8_t r = extr(rval, i * 16 + 10, 5) * 0x21 >> 2; + exp.pattern_color[idx*2+i] = b | g << 8 | r << 16; + } + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdPatternColorR8G8B8 : public SingleMthdTest { + void emulate_mthd() override { + exp.pattern_color[idx] = extr(val, 0, 24); + } + using SingleMthdTest::SingleMthdTest; +}; + +std::vector<SingleMthdTest *> Beta::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdPmTrigger(opt, rnd(), "pm_trigger", -1, cls, 0x140), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200), + new MthdBeta(opt, rnd(), "beta", 2, cls, 0x300), + }; +} + +std::vector<SingleMthdTest *> Beta4::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdPmTrigger(opt, rnd(), "pm_trigger", -1, cls, 0x140), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200), + new MthdBeta4(opt, rnd(), "beta4", 2, cls, 0x300), + }; +} + +std::vector<SingleMthdTest *> Rop::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdPmTrigger(opt, rnd(), "pm_trigger", -1, cls, 0x140), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200), + new MthdRop(opt, rnd(), "rop", 2, cls, 0x300), + }; +} + +std::vector<SingleMthdTest *> Chroma::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdPmTrigger(opt, rnd(), "pm_trigger", -1, cls, 0x140), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new UntestedMthd(opt, rnd(), "format", 2, cls, 0x300), // XXX + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200), + new MthdChroma(opt, rnd(), "chroma", 3, cls, 0x304), + }; +} + +std::vector<SingleMthdTest *> Plane::mthds() { + return { + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdPlane(opt, rnd(), "plane", 3, cls, 0x304), + }; +} + +std::vector<SingleMthdTest *> Pattern::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdPmTrigger(opt, rnd(), "pm_trigger", -1, cls, 0x140), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200), + new UntestedMthd(opt, rnd(), "format", 2, cls, 0x300), // XXX + new UntestedMthd(opt, rnd(), "bitmap_format", 3, cls, 0x304), // XXX + new MthdPatternShape(opt, rnd(), "pattern_shape", 4, cls, 0x308), + new MthdPatternBitmapColor(opt, rnd(), "pattern_bitmap_color_0", 5, cls, 0x310, 0), + new MthdPatternBitmapColor(opt, rnd(), "pattern_bitmap_color_1", 6, cls, 0x314, 1), + new MthdPatternBitmap(opt, rnd(), "pattern_bitmap_0", 7, cls, 0x318, 0), + new MthdPatternBitmap(opt, rnd(), "pattern_bitmap_1", 8, cls, 0x31c, 1), + }; +} + +std::vector<SingleMthdTest *> CPattern::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdPmTrigger(opt, rnd(), "pm_trigger", -1, cls, 0x140), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200), + new UntestedMthd(opt, rnd(), "format", 2, cls, 0x300), // XXX + new UntestedMthd(opt, rnd(), "bitmap_format", 3, cls, 0x304), // XXX + new MthdPatternShape(opt, rnd(), "pattern_shape", 4, cls, 0x308), + new MthdPatternSelect(opt, rnd(), "pattern_select", 5, cls, 0x30c), + new MthdPatternBitmapColor(opt, rnd(), "pattern_bitmap_color_0", 6, cls, 0x310, 0), + new MthdPatternBitmapColor(opt, rnd(), "pattern_bitmap_color_1", 7, cls, 0x314, 1), + new MthdPatternBitmap(opt, rnd(), "pattern_bitmap_0", 8, cls, 0x318, 0), + new MthdPatternBitmap(opt, rnd(), "pattern_bitmap_1", 9, cls, 0x31c, 1), + new MthdPatternColorY8(opt, rnd(), "pattern_color_y8", 10, cls, 0x400, 0x10), + new MthdPatternColorR5G6B5(opt, rnd(), "pattern_color_r5g6b5", 12, cls, 0x500, 0x20), + new MthdPatternColorR5G5B5(opt, rnd(), "pattern_color_r5g5b5", 11, cls, 0x600, 0x20), + new MthdPatternColorR8G8B8(opt, rnd(), "pattern_color_r8g8b8", 13, cls, 0x700, 0x40), + }; +} + +} +} diff --git a/hwtest/pgraph_mthd_d3d0.cc b/hwtest/pgraph_class_d3d0.cc index 9836a10f..7ef9b677 100644 --- a/hwtest/pgraph_mthd_d3d0.cc +++ b/hwtest/pgraph_class_d3d0.cc @@ -23,6 +23,8 @@ */ #include "pgraph.h" +#include "pgraph_mthd.h" +#include "pgraph_class.h" #include "nva.h" namespace hwtest { @@ -30,23 +32,16 @@ namespace pgraph { namespace { -class MthdD3D0TexOffsetTest : public MthdTest { - void choose_mthd() override { - cls = 0x17; - mthd = 0x304; - } +class MthdD3D0TexOffset : public SingleMthdTest { void emulate_mthd() override { exp.dma_offset[0] = val; insrt(exp.valid[0], 23, 1, 1); } -public: - MthdD3D0TexOffsetTest(TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdD3D0TexFormatTest : public MthdTest { - void choose_mthd() override { - cls = 0x17; - mthd = 0x308; +class MthdD3D0TexFormat : public SingleMthdTest { + void adjust_orig_mthd() override { if (rnd() & 1) { val &= 0xff31ffff; val ^= 1 << (rnd() & 0x1f); @@ -65,60 +60,40 @@ class MthdD3D0TexFormatTest : public MthdTest { exp.misc32[0] = val; insrt(exp.valid[0], 24, 1, 1); } -public: - MthdD3D0TexFormatTest(TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdD3D0TexFilterTest : public MthdTest { - void choose_mthd() override { - cls = 0x17; - mthd = 0x30c; - } +class MthdD3D0TexFilter : public SingleMthdTest { void emulate_mthd() override { exp.misc32[1] = val; insrt(exp.valid[0], 25, 1, 1); } -public: - MthdD3D0TexFilterTest(TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdD3D0FogColorTest : public MthdTest { - void choose_mthd() override { - cls = 0x17; - mthd = 0x310; - } +class MthdD3D0FogColor : public SingleMthdTest { void emulate_mthd() override { exp.misc24[0] = val & 0xffffff; insrt(exp.valid[0], 27, 1, 1); } -public: - MthdD3D0FogColorTest(TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdD3D0ConfigTest : public MthdTest { - bool is_zpoint; - void choose_mthd() override { - is_zpoint = rnd() & 1; - if (is_zpoint) { - cls = 0x18; - mthd = 0x304; - if (rnd() & 1) { +class MthdD3D0Config : public SingleMthdTest { + void adjust_orig_mthd() override { + if (rnd() & 1) { + if (cls == 0x18) { val &= 0xf77f0000; - val ^= 1 << (rnd() & 0x1f); - } - } else { - cls = 0x17; - mthd = 0x314; - if (rnd() & 1) { + } else { val &= 0xf77fbdf3; - val ^= 1 << (rnd() & 0x1f); } + val ^= 1 << (rnd() & 0x1f); } } bool is_valid_val() override { if (val & ~0xf77fbdf3) return false; - if (is_zpoint) { + if (cls == 0x18) { if (val & 0xffff) return false; } else { @@ -141,14 +116,11 @@ class MthdD3D0ConfigTest : public MthdTest { exp.d3d0_config = val & 0xf77fbdf3; insrt(exp.valid[0], 26, 1, 1); } -public: - MthdD3D0ConfigTest(TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdD3D0AlphaTest : public MthdTest { - void choose_mthd() override { - cls = 0x17; - mthd = 0x318; +class MthdD3D0Alpha : public SingleMthdTest { + void adjust_orig_mthd() override { if (rnd() & 1) { val &= 0xfff; val ^= 1 << (rnd() & 0x1f); @@ -166,149 +138,80 @@ class MthdD3D0AlphaTest : public MthdTest { void emulate_mthd() override { exp.d3d0_alpha = val & 0xfff; } -public: - MthdD3D0AlphaTest(TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdD3D0TlvFogTriTest : public MthdTest { - void choose_mthd() override { - int idx = rnd() & 0x7f; - cls = 0x17; - mthd = 0x1000 + idx * 0x20; - } +class MthdD3D0TlvFogTri : public SingleMthdTest { void emulate_mthd() override { exp.d3d0_tlv_fog_tri_col1 = val; insrt(exp.valid[0], 16, 7, 1); } -public: - MthdD3D0TlvFogTriTest(TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdD3D0TlvColorTest : public MthdTest { - void choose_mthd() override { - int idx = rnd() & 0x7f; - cls = 0x17; - mthd = 0x1004 + idx * 0x20; - } +class MthdD3D0TlvColor : public SingleMthdTest { void emulate_mthd() override { insrt(exp.d3d0_tlv_color, 0, 24, extr(val, 0, 24)); insrt(exp.d3d0_tlv_color, 24, 7, extr(val, 25, 7)); insrt(exp.valid[0], 17, 1, 1); insrt(exp.valid[0], extr(exp.d3d0_tlv_fog_tri_col1, 0, 4), 1, 0); } -public: - MthdD3D0TlvColorTest(TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdD3D0TlvXyTest : public MthdTest { - bool xy; - void choose_mthd() override { - int idx = rnd() & 0x7f; - xy = rnd() & 1; - cls = 0x17; - mthd = 0x1008 + xy * 4 + idx * 0x20; - } +class MthdD3D0TlvX : public SingleMthdTest { void emulate_mthd() override { - int e = extr(val, 23, 8); - bool s = extr(val, 31, 1); - uint32_t tv = extr(val, 0, 23) | 1 << 23; - if (e > 0x7f+10) { - tv = 0x7fff + s; - } else if (e < 0x7f-4) { - tv = 0; - } else { - tv >>= 0x7f + 10 - e + 24 - 15; - if (s) - tv = -tv; - } - insrt(exp.d3d0_tlv_xy, 16*xy, 16, tv); - insrt(exp.valid[0], 21 - xy, 1, 1); + uint16_t tv = nv03_pgraph_convert_xy(val); + insrt(exp.d3d0_tlv_xy, 0, 16, tv); + insrt(exp.valid[0], 21, 1, 1); insrt(exp.valid[0], extr(exp.d3d0_tlv_fog_tri_col1, 0, 4), 1, 0); } -public: - MthdD3D0TlvXyTest(TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdD3D0TlvZTest : public MthdTest { - void choose_mthd() override { - int idx = rnd() & 0x7f; - cls = 0x17; - mthd = 0x1010 + idx * 0x20; +class MthdD3D0TlvY : public SingleMthdTest { + void emulate_mthd() override { + uint16_t tv = nv03_pgraph_convert_xy(val); + insrt(exp.d3d0_tlv_xy, 16, 16, tv); + insrt(exp.valid[0], 20, 1, 1); + insrt(exp.valid[0], extr(exp.d3d0_tlv_fog_tri_col1, 0, 4), 1, 0); } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdD3D0TlvZ : public SingleMthdTest { void emulate_mthd() override { - int e = extr(val, 23, 8); - bool s = extr(val, 31, 1); - uint32_t tv = extr(val, 0, 23) | 1 << 23; - if (s) { - tv = 0; - } else if (e > 0x7f-1) { - tv = 0xffffff; - } else if (e < 0x7f-24) { - tv = 0; - } else { - tv >>= 0x7f-1 - e; - } - tv = ~tv; + uint32_t tv = nv03_pgraph_convert_z(val); exp.d3d0_tlv_z = extr(tv, 0, 16); insrt(exp.d3d0_tlv_rhw, 25, 7, extr(tv, 16, 7)); insrt(exp.d3d0_tlv_color, 31, 1, extr(tv, 23, 1)); insrt(exp.valid[0], 19, 1, 1); insrt(exp.valid[0], extr(exp.d3d0_tlv_fog_tri_col1, 0, 4), 1, 0); } -public: - MthdD3D0TlvZTest(TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdD3D0TlvRhwTest : public MthdTest { - void choose_mthd() override { - int idx = rnd() & 0x7f; - cls = 0x17; - mthd = 0x1014 + idx * 0x20; - } +class MthdD3D0TlvRhw : public SingleMthdTest { void emulate_mthd() override { insrt(exp.d3d0_tlv_rhw, 0, 25, extr(val, 6, 25)); insrt(exp.valid[0], 18, 1, 1); insrt(exp.valid[0], extr(exp.d3d0_tlv_fog_tri_col1, 0, 4), 1, 0); } -public: - MthdD3D0TlvRhwTest(TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdD3D0TlvUTest : public MthdTest { - void choose_mthd() override { - int idx = rnd() & 0x7f; - cls = 0x17; - mthd = 0x1018 + idx * 0x20; - } +class MthdD3D0TlvU : public SingleMthdTest { void emulate_mthd() override { - int e = extr(val, 23, 8); - bool s = extr(val, 31, 1); - uint32_t tv = extr(val, 0, 23) | 1 << 23; int sz = extr(exp.misc32[0], 28, 4); - e -= (11 - sz); - if (e > 0x7f-1) { - tv = 0x7fff + s; - } else if (e < 0x7f-15) { - tv = 0; - } else { - tv >>= 0x7f - 1 - e + 24 - 15; - if (s) - tv = -tv; - } + uint16_t tv = nv03_pgraph_convert_uv(val, sz); insrt(exp.d3d0_tlv_uv, 0, 16, tv); insrt(exp.valid[0], 22, 1, 1); insrt(exp.valid[0], extr(exp.d3d0_tlv_fog_tri_col1, 0, 4), 1, 0); } -public: - MthdD3D0TlvUTest(TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdD3D0TlvVTest : public MthdTest { - void choose_mthd() override { - int idx = rnd() & 0x7f; - cls = 0x17; - mthd = 0x101c + idx * 0x20; - } +class MthdD3D0TlvV : public SingleMthdTest { void adjust_orig_mthd() override { // XXX: disable this some day and test the actual DMA if (rnd() & 1) { @@ -318,20 +221,8 @@ class MthdD3D0TlvVTest : public MthdTest { } } void emulate_mthd() override { - int e = extr(val, 23, 8); - bool s = extr(val, 31, 1); - uint32_t tv = extr(val, 0, 23) | 1 << 23; int sz = extr(exp.misc32[0], 28, 4); - e -= (11 - sz); - if (e > 0x7f-1) { - tv = 0x7fff + s; - } else if (e < 0x7f-15) { - tv = 0; - } else { - tv >>= 0x7f - 1 - e + 24 - 15; - if (s) - tv = -tv; - } + uint16_t tv = nv03_pgraph_convert_uv(val, sz); insrt(exp.d3d0_tlv_uv, 16, 16, tv); int vtxid = extr(exp.d3d0_tlv_fog_tri_col1, 0, 4); exp.misc24[1] = extr(exp.d3d0_tlv_fog_tri_col1, 0, 24); @@ -350,31 +241,79 @@ class MthdD3D0TlvVTest : public MthdTest { } pgraph_prep_draw(&exp, false, false); } -public: - MthdD3D0TlvVTest(TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; +}; + +class MthdZPointZeta : public SingleMthdTest { + int repeats() override { return 10000; }; + void adjust_orig_mthd() override { + if (rnd() & 3) + insrt(orig.cliprect_ctrl, 8, 1, 0); + if (rnd() & 3) + insrt(orig.debug[2], 28, 1, 0); + if (rnd() & 3) { + insrt(orig.xy_misc_4[0], 4, 4, 0); + insrt(orig.xy_misc_4[1], 4, 4, 0); + } + if (rnd() & 3) { + orig.valid[0] = 0x0fffffff; + if (rnd() & 1) { + orig.valid[0] &= ~0xf0f; + } + orig.valid[0] ^= 1 << (rnd() & 0x1f); + orig.valid[0] ^= 1 << (rnd() & 0x1f); + } + if (rnd() & 1) { + insrt(orig.ctx_switch[0], 24, 5, 0x17); + insrt(orig.ctx_switch[0], 13, 2, 0); + int j; + for (j = 0; j < 8; j++) { + insrt(orig.ctx_cache[j][0], 24, 5, 0x17); + insrt(orig.ctx_cache[j][0], 13, 2, 0); + } + } + orig.debug[2] &= 0xffdfffff; + orig.debug[3] &= 0xfffeffff; + orig.debug[3] &= 0xfffdffff; + } + void emulate_mthd() override { + insrt(exp.misc32[1], 16, 16, extr(val, 16, 16)); + pgraph_prep_draw(&exp, false, false); + nv03_pgraph_vtx_add(&exp, 0, 0, exp.vtx_xy[0][0], 1, 0, false, false); + } + using SingleMthdTest::SingleMthdTest; }; } -bool PGraphMthdD3D0Tests::supported() { - return chipset.card_type >= 3 && chipset.card_type < 4; +std::vector<SingleMthdTest *> ZPoint::mthds() { + return { + new MthdNotify(opt, rnd(), "notify", -1, cls, 0x104), + new MthdD3D0Config(opt, rnd(), "config", -1, cls, 0x304), + new MthdD3D0Alpha(opt, rnd(), "alpha", -1, cls, 0x308), + new UntestedMthd(opt, rnd(), "xy", -1, cls, 0x7fc), // XXX + new MthdSolidColor(opt, rnd(), "color", -1, cls, 0x800, 0x100, 8), + new MthdZPointZeta(opt, rnd(), "zeta", -1, cls, 0x804, 0x100, 8), + }; } -Test::Subtests PGraphMthdD3D0Tests::subtests() { +std::vector<SingleMthdTest *> D3D0::mthds() { return { - {"tex_offset", new MthdD3D0TexOffsetTest(opt, rnd())}, - {"tex_format", new MthdD3D0TexFormatTest(opt, rnd())}, - {"tex_filter", new MthdD3D0TexFilterTest(opt, rnd())}, - {"fog_color", new MthdD3D0FogColorTest(opt, rnd())}, - {"config", new MthdD3D0ConfigTest(opt, rnd())}, - {"alpha", new MthdD3D0AlphaTest(opt, rnd())}, - {"tlv_fog_tri", new MthdD3D0TlvFogTriTest(opt, rnd())}, - {"tlv_color", new MthdD3D0TlvColorTest(opt, rnd())}, - {"tlv_xy", new MthdD3D0TlvXyTest(opt, rnd())}, - {"tlv_z", new MthdD3D0TlvZTest(opt, rnd())}, - {"tlv_rhw", new MthdD3D0TlvRhwTest(opt, rnd())}, - {"tlv_u", new MthdD3D0TlvUTest(opt, rnd())}, - {"tlv_v", new MthdD3D0TlvVTest(opt, rnd())}, + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdD3D0TexOffset(opt, rnd(), "tex_offset", -1, cls, 0x304), + new MthdD3D0TexFormat(opt, rnd(), "tex_format", -1, cls, 0x308), + new MthdD3D0TexFilter(opt, rnd(), "tex_filter", -1, cls, 0x30c), + new MthdD3D0FogColor(opt, rnd(), "fog_color", -1, cls, 0x310), + new MthdD3D0Config(opt, rnd(), "config", -1, cls, 0x314), + new MthdD3D0Alpha(opt, rnd(), "alpha", -1, cls, 0x318), + new MthdD3D0TlvFogTri(opt, rnd(), "tlv_fog_tri", -1, cls, 0x1000, 0x80, 0x20), + new MthdD3D0TlvColor(opt, rnd(), "tlv_color", -1, cls, 0x1004, 0x80, 0x20), + new MthdD3D0TlvX(opt, rnd(), "tlv_x", -1, cls, 0x1008, 0x80, 0x20), + new MthdD3D0TlvY(opt, rnd(), "tlv_y", -1, cls, 0x100c, 0x80, 0x20), + new MthdD3D0TlvZ(opt, rnd(), "tlv_z", -1, cls, 0x1010, 0x80, 0x20), + new MthdD3D0TlvRhw(opt, rnd(), "tlv_rhw", -1, cls, 0x1014, 0x80, 0x20), + new MthdD3D0TlvU(opt, rnd(), "tlv_u", -1, cls, 0x1018, 0x80, 0x20), + new MthdD3D0TlvV(opt, rnd(), "tlv_v", -1, cls, 0x101c, 0x80, 0x20), }; } diff --git a/hwtest/pgraph_mthd_m2mf.cc b/hwtest/pgraph_class_m2mf.cc index 68b02ac1..da75897a 100644 --- a/hwtest/pgraph_mthd_m2mf.cc +++ b/hwtest/pgraph_class_m2mf.cc @@ -23,6 +23,8 @@ */ #include "pgraph.h" +#include "pgraph_mthd.h" +#include "pgraph_class.h" #include "nva.h" namespace hwtest { @@ -30,49 +32,34 @@ namespace pgraph { namespace { -class MthdM2mfOffsetTest : public MthdTest { - int idx; - void choose_mthd() override { - idx = rnd() & 1; - cls = chipset.card_type < 4 ? 0x0d : 0x39;; - mthd = 0x30c + idx * 4; - trapbit = 4 + idx; - } +class MthdM2mfOffset : public SingleMthdTest { + int which; void emulate_mthd() override { - exp.dma_offset[idx] = val; - insrt(exp.valid[0], idx, 1, 1); + exp.dma_offset[which] = val; + insrt(exp.valid[0], which, 1, 1); } public: - MthdM2mfOffsetTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + MthdM2mfOffset(hwtest::TestOptions &opt, uint32_t seed, const std::string &name, int trapbit, uint32_t cls, uint32_t mthd, int which) + : SingleMthdTest(opt, seed, name, trapbit, cls, mthd), which(which) {} }; -class MthdM2mfPitchTest : public MthdTest { - int idx; - void choose_mthd() override { - idx = rnd() & 1; - cls = chipset.card_type < 4 ? 0x0d : 0x39;; - mthd = 0x314 + idx * 4; - trapbit = 6 + idx; - } +class MthdM2mfPitch : public SingleMthdTest { + int which; bool is_valid_val() override { return !(val & ~0x7fff); } void emulate_mthd_pre() override { - insrt(exp.dma_pitch, 16 * idx, 16, val); + insrt(exp.dma_pitch, 16 * which, 16, val); } void emulate_mthd() override { - insrt(exp.valid[0], idx + 2, 1, 1); + insrt(exp.valid[0], which + 2, 1, 1); } public: - MthdM2mfPitchTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + MthdM2mfPitch(hwtest::TestOptions &opt, uint32_t seed, const std::string &name, int trapbit, uint32_t cls, uint32_t mthd, int which) + : SingleMthdTest(opt, seed, name, trapbit, cls, mthd), which(which) {} }; -class MthdM2mfLineLengthTest : public MthdTest { - void choose_mthd() override { - cls = chipset.card_type < 4 ? 0x0d : 0x39;; - mthd = 0x31c; - trapbit = 8; - } +class MthdM2mfLineLength : public SingleMthdTest { void adjust_orig_mthd() override { if (rnd() & 1) { val &= 0xffffff; @@ -89,16 +76,10 @@ class MthdM2mfLineLengthTest : public MthdTest { exp.dma_length = val & 0x3fffff; insrt(exp.valid[0], 4, 1, 1); } -public: - MthdM2mfLineLengthTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdM2mfLineCountTest : public MthdTest { - void choose_mthd() override { - cls = chipset.card_type < 4 ? 0x0d : 0x39;; - mthd = 0x320; - trapbit = 9; - } +class MthdM2mfLineCount : public SingleMthdTest { void adjust_orig_mthd() override { if (rnd() & 1) { val &= 0xfff; @@ -115,16 +96,10 @@ class MthdM2mfLineCountTest : public MthdTest { insrt(exp.dma_misc, 0, 16, val & 0x7ff); insrt(exp.valid[0], 5, 1, 1); } -public: - MthdM2mfLineCountTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdM2mfFormatTest : public MthdTest { - void choose_mthd() override { - cls = chipset.card_type < 4 ? 0x0d : 0x39;; - mthd = 0x324; - trapbit = 10; - } +class MthdM2mfFormat : public SingleMthdTest { void adjust_orig_mthd() override { if (rnd() & 1) { val &= ~0xf8; @@ -151,16 +126,10 @@ class MthdM2mfFormatTest : public MthdTest { } insrt(exp.valid[0], 6, 1, 1); } -public: - MthdM2mfFormatTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; -class MthdM2mfTriggerTest : public MthdTest { - void choose_mthd() override { - cls = chipset.card_type < 4 ? 0x0d : 0x39;; - mthd = 0x328; - trapbit = 11; - } +class MthdM2mfTrigger : public SingleMthdTest { void adjust_orig_mthd() override { // XXX: disable this some day and test the actual DMA insrt(orig.valid[0], rnd() % 7, 1, 0); @@ -192,24 +161,27 @@ class MthdM2mfTriggerTest : public MthdTest { pgraph_state_error(&exp); } } -public: - MthdM2mfTriggerTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} + using SingleMthdTest::SingleMthdTest; }; } -bool PGraphMthdM2mfTests::supported() { - return chipset.card_type >= 3 && chipset.card_type < 0x20; -} - -Test::Subtests PGraphMthdM2mfTests::subtests() { +std::vector<SingleMthdTest *> M2mf::mthds() { return { - {"offset", new MthdM2mfOffsetTest(opt, rnd())}, - {"pitch", new MthdM2mfPitchTest(opt, rnd())}, - {"line_length", new MthdM2mfLineLengthTest(opt, rnd())}, - {"line_count", new MthdM2mfLineCountTest(opt, rnd())}, - {"format", new MthdM2mfFormatTest(opt, rnd())}, - {"trigger", new MthdM2mfTriggerTest(opt, rnd())}, + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdPmTrigger(opt, rnd(), "pm_trigger", -1, cls, 0x140), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new UntestedMthd(opt, rnd(), "dma_a", 2, cls, 0x184), // XXX + new UntestedMthd(opt, rnd(), "dma_b", 3, cls, 0x188), // XXX + new MthdM2mfOffset(opt, rnd(), "offset_in", 4, cls, 0x30c, 0), + new MthdM2mfOffset(opt, rnd(), "offset_out", 5, cls, 0x310, 1), + new MthdM2mfPitch(opt, rnd(), "pitch_in", 6, cls, 0x314, 0), + new MthdM2mfPitch(opt, rnd(), "pitch_out", 7, cls, 0x318, 1), + new MthdM2mfLineLength(opt, rnd(), "line_length", 8, cls, 0x31c), + new MthdM2mfLineCount(opt, rnd(), "line_count", 9, cls, 0x320), + new MthdM2mfFormat(opt, rnd(), "format", 10, cls, 0x324), + new MthdM2mfTrigger(opt, rnd(), "trigger", 11, cls, 0x328), }; } diff --git a/hwtest/pgraph_class_op.cc b/hwtest/pgraph_class_op.cc new file mode 100644 index 00000000..6faf88ef --- /dev/null +++ b/hwtest/pgraph_class_op.cc @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2016 Marcin Kościelnicki <koriakin@0x04.net> + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "pgraph.h" +#include "pgraph_mthd.h" +#include "pgraph_class.h" +#include "nva.h" + +namespace hwtest { +namespace pgraph { + +std::vector<SingleMthdTest *> OpClip::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200, 2), + }; +} + +std::vector<SingleMthdTest *> OpBlendAnd::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200, 3), + }; +} + +std::vector<SingleMthdTest *> OpRopAnd::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200, 3), + }; +} + +std::vector<SingleMthdTest *> OpChroma::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200, 2), + }; +} + +std::vector<SingleMthdTest *> OpSrccopyAnd::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200, 2), + }; +} + +std::vector<SingleMthdTest *> OpSrccopy::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200, 2), + }; +} + +std::vector<SingleMthdTest *> OpSrccopyPremult::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200, 3), + }; +} + +std::vector<SingleMthdTest *> OpBlendPremult::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200, 3), + }; +} + +} +} diff --git a/hwtest/pgraph_class_surf.cc b/hwtest/pgraph_class_surf.cc new file mode 100644 index 00000000..9baf4696 --- /dev/null +++ b/hwtest/pgraph_class_surf.cc @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2016 Marcin Kościelnicki <koriakin@0x04.net> + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "pgraph.h" +#include "pgraph_mthd.h" +#include "pgraph_class.h" +#include "nva.h" + +namespace hwtest { +namespace pgraph { + +namespace { + +class MthdSurfFormat : public SingleMthdTest { + void adjust_orig_mthd() override { + if (rnd() & 1) { + val &= 0x01010003; + val ^= 1 << (rnd() & 0x1f); + } + } + bool is_valid_val() override { + return val == 1 || val == 0x01000000 || val == 0x01010000 || val == 0x01010001; + } + void emulate_mthd() override { + if (chipset.card_type < 4) { + int which = extr(exp.ctx_switch[0], 16, 2); + int f = 1; + if (extr(val, 0, 1)) + f = 0; + if (!extr(val, 16, 1)) + f = 2; + if (!extr(val, 24, 1)) + f = 3; + insrt(exp.surf_format, 4*which, 3, f | 4); + } else { + int which = cls & 3; + int fmt = 0; + if (val == 1) { + fmt = 7; + } else if (val == 0x01010000) { + fmt = 1; + } else if (val == 0x01000000) { + fmt = 2; + } else if (val == 0x01010001) { + fmt = 6; + } + insrt(exp.surf_format, which*4, 4, fmt); + } + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdSurfPitch : public SingleMthdTest { + bool is_valid_val() override { + if (chipset.card_type < 4) + return true; + return val && !(val & ~0x1ff0); + } + void emulate_mthd() override { + int which; + if (chipset.card_type < 4) { + which = extr(exp.ctx_switch[0], 16, 2); + } else { + which = cls & 3; + insrt(exp.valid[0], 2, 1, 1); + insrt(exp.ctx_valid, 8+which, 1, !extr(exp.nsource, 1, 1)); + } + exp.surf_pitch[which] = val & pgraph_pitch_mask(&chipset); + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdSurfOffset : public SingleMthdTest { + bool is_valid_val() override { + if (chipset.card_type < 4) + return true; + return !(val & 0xf); + } + void emulate_mthd() override { + int which; + if (chipset.card_type < 4) { + which = extr(exp.ctx_switch[0], 16, 2); + } else { + which = cls & 3; + insrt(exp.valid[0], 3, 1, 1); + } + exp.surf_offset[which] = val & pgraph_offset_mask(&chipset); + } + using SingleMthdTest::SingleMthdTest; +}; + +} + +std::vector<SingleMthdTest *> Surf::mthds() { + return { + new MthdNop(opt, rnd(), "nop", -1, cls, 0x100), + new MthdNotify(opt, rnd(), "notify", 0, cls, 0x104), + new MthdPmTrigger(opt, rnd(), "pm_trigger", -1, cls, 0x140), + new MthdDmaNotify(opt, rnd(), "dma_notify", 1, cls, 0x180), + new UntestedMthd(opt, rnd(), "dma_surf", 2, cls, 0x184), // XXX + new MthdMissing(opt, rnd(), "missing", -1, cls, 0x200, 2), + new MthdSurfFormat(opt, rnd(), "format", 3, cls, 0x300), + new MthdSurfPitch(opt, rnd(), "pitch", 4, cls, 0x308), + new MthdSurfOffset(opt, rnd(), "offset", 5, cls, 0x30c), + }; +} + +} +} diff --git a/hwtest/pgraph_mthd.cc b/hwtest/pgraph_mthd.cc index 754b874b..7cbc000e 100644 --- a/hwtest/pgraph_mthd.cc +++ b/hwtest/pgraph_mthd.cc @@ -23,6 +23,8 @@ */ #include "pgraph.h" +#include "pgraph_mthd.h" +#include "pgraph_class.h" #include "nva.h" namespace hwtest { @@ -331,5 +333,77 @@ void MthdTest::print_fail() { printf("Mthd %02x.%04x <- %08x\n", cls, mthd, val); } +namespace { + +class MthdInvalid : public SingleMthdTest { + bool special_notify() override { + return chipset.card_type == 3; + } + int repeats() override { + return 1; + } + void emulate_mthd() override { + if (chipset.card_type < 4) { + if (!extr(exp.invalid, 16, 1)) { + exp.intr |= 1; + exp.invalid |= 1; + if (chipset.card_type < 3) { + exp.access &= ~0x101; + } else { + exp.fifo_enable = 0; + if (!extr(exp.invalid, 4, 1)) { + if (extr(exp.notify, 16, 1) && extr(exp.notify, 20, 4)) { + exp.intr |= 1 << 28; + } + } + } + } + } else { + nv04_pgraph_blowup(&exp, 0x40); + } + } + using SingleMthdTest::SingleMthdTest; +}; + +class ClassInvalidTests : public Test { + std::vector<bool> valid; + uint32_t cls; + bool subtests_boring() override { + return true; + } + Subtests subtests() override { + Subtests res; + uint32_t mthds = chipset.card_type < 3 ? 0x10000 : 0x2000; + for (uint32_t mthd = 0; mthd < mthds; mthd += 4) { + if (mthd != 0 && !valid[mthd]) { + char buf[5]; + snprintf(buf, sizeof buf, "%04x", mthd); + res.push_back({buf, new MthdInvalid(opt, rnd(), buf, -1, cls, mthd)}); + } + } + return res; + } +public: + ClassInvalidTests(TestOptions &opt, uint32_t seed, const std::vector<bool> &valid, uint32_t cls) : Test(opt, seed), valid(valid), cls(cls) {} +}; + +} + +Test::Subtests ClassTest::subtests() { + Subtests res; + std::vector<bool> valid(0x10000); + valid[0] = true; + for (auto *test : cls->mthds()) { + res.push_back({test->name, test}); + if (test->supported()) { + for (unsigned i = 0; i < test->s_num; i++) { + valid[test->s_mthd + test->s_stride * i] = true; + } + } + } + res.push_back({"invalid", new ClassInvalidTests(opt, rnd(), valid, cls->cls)}); + return res; +} + } } diff --git a/hwtest/pgraph_mthd.h b/hwtest/pgraph_mthd.h new file mode 100644 index 00000000..d70076e3 --- /dev/null +++ b/hwtest/pgraph_mthd.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2016 Marcin Kościelnicki <koriakin@0x04.net> + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef HWTEST_PGRAPH_MTHD_H +#define HWTEST_PGRAPH_MTHD_H + +#include "pgraph.h" + +namespace hwtest { +namespace pgraph { + +class MthdTest : public StateTest { +protected: + uint32_t cls, mthd, subc, val; + int trapbit; + uint32_t grobj[4], gctx; + virtual void choose_mthd() = 0; + virtual void emulate_mthd_pre() {}; + virtual void emulate_mthd() = 0; + virtual bool special_notify() { return false; } + virtual bool is_valid_val() { return true; } + virtual void adjust_orig_mthd() { } + virtual int gen_nv3_fmt() { return rnd() & 7; } + virtual bool fix_alt_cls() { return true; } + void adjust_orig() override; + void mutate() override; + void print_fail() override; + MthdTest(hwtest::TestOptions &opt, uint32_t seed) : StateTest(opt, seed), trapbit(-1) {} +}; + +class SingleMthdTest : public MthdTest { +protected: + int idx; +private: + void choose_mthd() override { + cls = s_cls; + idx = rnd() % s_num; + mthd = s_mthd + idx * s_stride; + trapbit = s_trapbit; + } +public: + uint32_t s_cls, s_mthd, s_stride, s_num; + int s_trapbit; + std::string name; + SingleMthdTest(hwtest::TestOptions &opt, uint32_t seed, const std::string &name, int trapbit, uint32_t cls, uint32_t mthd, uint32_t num = 1, uint32_t stride = 4) + : MthdTest(opt, seed), s_cls(cls), s_mthd(mthd), s_stride(stride), s_num(num), s_trapbit(trapbit), name(name) {} +}; + +class MthdNop : public SingleMthdTest { + bool supported() override { + return chipset.card_type >= 4; + } + void emulate_mthd() override { + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdMissing : 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; +}; + +class MthdPmTrigger : public SingleMthdTest { + bool supported() override { + return chipset.card_type >= 0x10; + } + void emulate_mthd() override { + if (!extr(exp.debug[3], 15, 1)) { + nv04_pgraph_blowup(&exp, 0x40); + } + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdNotify : public SingleMthdTest { + bool special_notify() override { return true; } + void adjust_orig_mthd() override; + bool is_valid_val() override; + void emulate_mthd() override; + using SingleMthdTest::SingleMthdTest; +}; + +class MthdDmaNotify : public SingleMthdTest { + bool supported() override { + return chipset.card_type >= 4; + } + int run() override { + return HWTEST_RES_NA; + } + void emulate_mthd() override { + // XXX + } + using SingleMthdTest::SingleMthdTest; +}; + +class UntestedMthd : public SingleMthdTest { + int run() override { + return HWTEST_RES_NA; + } + void emulate_mthd() override { } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdSolidColor : public SingleMthdTest { + void emulate_mthd() override; + using SingleMthdTest::SingleMthdTest; +}; + +} +} + +#endif diff --git a/hwtest/pgraph_mthd_invalid.cc b/hwtest/pgraph_mthd_invalid.cc index 05bbdfcc..7eb4d84e 100644 --- a/hwtest/pgraph_mthd_invalid.cc +++ b/hwtest/pgraph_mthd_invalid.cc @@ -23,6 +23,7 @@ */ #include "pgraph.h" +#include "pgraph_mthd.h" #include "nva.h" #include <string.h> @@ -86,66 +87,6 @@ protected: ClsMthdInvalidTests(hwtest::TestOptions &opt, uint32_t seed) : Test(opt, seed) {} }; -class BetaMthdInvalidTests : public ClsMthdInvalidTests { - int cls() override { return 0x01; } - bool is_valid(uint32_t mthd) override { - return mthd == 0x104 || mthd == 0x300; - } -public: - BetaMthdInvalidTests(hwtest::TestOptions &opt, uint32_t seed) : ClsMthdInvalidTests(opt, seed) {} -}; - -class RopMthdInvalidTests : public ClsMthdInvalidTests { - int cls() override { return 0x02; } - bool is_valid(uint32_t mthd) override { - return mthd == 0x104 || mthd == 0x300; - } -public: - RopMthdInvalidTests(hwtest::TestOptions &opt, uint32_t seed) : ClsMthdInvalidTests(opt, seed) {} -}; - -class ChromaMthdInvalidTests : public ClsMthdInvalidTests { - int cls() override { return 0x03; } - bool is_valid(uint32_t mthd) override { - return mthd == 0x104 || mthd == 0x304; - } -public: - ChromaMthdInvalidTests(hwtest::TestOptions &opt, uint32_t seed) : ClsMthdInvalidTests(opt, seed) {} -}; - -class PlaneMthdInvalidTests : public ClsMthdInvalidTests { - int cls() override { return 0x04; } - bool is_valid(uint32_t mthd) override { - return mthd == 0x104 || mthd == 0x304; - } -public: - PlaneMthdInvalidTests(hwtest::TestOptions &opt, uint32_t seed) : ClsMthdInvalidTests(opt, seed) {} -}; - -class ClipMthdInvalidTests : public ClsMthdInvalidTests { - int cls() override { return 0x05; } - bool is_valid(uint32_t mthd) override { - return mthd == 0x104 || mthd == 0x300 || mthd == 0x304; - } -public: - ClipMthdInvalidTests(hwtest::TestOptions &opt, uint32_t seed) : ClsMthdInvalidTests(opt, seed) {} -}; - -class PatternMthdInvalidTests : public ClsMthdInvalidTests { - int cls() override { return 0x06; } - bool is_valid(uint32_t mthd) override { - if (mthd == 0x104) - return true; - if (mthd == 0x308) - return true; - if (mthd >= 0x310 && mthd <= 0x31c) - return true; - return false; - } -public: - PatternMthdInvalidTests(hwtest::TestOptions &opt, uint32_t seed) : ClsMthdInvalidTests(opt, seed) {} -}; - class PointMthdInvalidTests : public ClsMthdInvalidTests { int cls() override { return 0x08; } bool is_valid(uint32_t mthd) override { @@ -397,19 +338,6 @@ public: GdiMthdInvalidTests(hwtest::TestOptions &opt, uint32_t seed) : ClsMthdInvalidTests(opt, seed) {} }; -class M2mfMthdInvalidTests : public ClsMthdInvalidTests { - int cls() override { return 0x0d; } - bool is_valid(uint32_t mthd) override { - if (mthd == 0x104) - return true; - if (mthd >= 0x30c && mthd < 0x32c) - return true; - return false; - } -public: - M2mfMthdInvalidTests(hwtest::TestOptions &opt, uint32_t seed) : ClsMthdInvalidTests(opt, seed) {} -}; - class SifmMthdInvalidTests : public ClsMthdInvalidTests { int cls() override { return 0x0e; } bool is_valid(uint32_t mthd) override { @@ -440,49 +368,6 @@ public: SifcMthdInvalidTests(hwtest::TestOptions &opt, uint32_t seed) : ClsMthdInvalidTests(opt, seed) {} }; -class D3D0MthdInvalidTests : public ClsMthdInvalidTests { - int cls() override { return 0x17; } - bool is_valid(uint32_t mthd) override { - if (mthd == 0x104) - return true; - if (mthd >= 0x304 && mthd < 0x31c) - return true; - if (mthd >= 0x1000 && mthd < 0x2000) - return true; - return false; - } -public: - D3D0MthdInvalidTests(hwtest::TestOptions &opt, uint32_t seed) : ClsMthdInvalidTests(opt, seed) {} -}; - -class ZPointMthdInvalidTests : public ClsMthdInvalidTests { - int cls() override { return 0x18; } - bool is_valid(uint32_t mthd) override { - if (mthd == 0x104) - return true; - if (mthd >= 0x304 && mthd < 0x30c) - return true; - if (mthd >= 0x7fc && mthd < 0x1000) - return true; - return false; - } -public: - ZPointMthdInvalidTests(hwtest::TestOptions &opt, uint32_t seed) : ClsMthdInvalidTests(opt, seed) {} -}; - -class SurfMthdInvalidTests : public ClsMthdInvalidTests { - int cls() override { return 0x1c; } - bool is_valid(uint32_t mthd) override { - if (mthd == 0x104) - return true; - if (mthd == 0x300 || mthd == 0x308 || mthd == 0x30c) - return true; - return false; - } -public: - SurfMthdInvalidTests(hwtest::TestOptions &opt, uint32_t seed) : ClsMthdInvalidTests(opt, seed) {} -}; - class InvalidMthdInvalidTests : public ClsMthdInvalidTests { int cls_; int cls() override { return cls_; } @@ -500,12 +385,6 @@ bool PGraphMthdInvalidTests::supported() { Test::Subtests PGraphMthdInvalidTests::subtests() { if (chipset.card_type < 3) { return { - {"beta", new BetaMthdInvalidTests(opt, rnd())}, - {"rop", new RopMthdInvalidTests(opt, rnd())}, - {"chroma", new ChromaMthdInvalidTests(opt, rnd())}, - {"plane", new PlaneMthdInvalidTests(opt, rnd())}, - {"clip", new ClipMthdInvalidTests(opt, rnd())}, - {"pattern", new PatternMthdInvalidTests(opt, rnd())}, {"point", new PointMthdInvalidTests(opt, rnd())}, {"line", new LineMthdInvalidTests(opt, rnd())}, {"lin", new LinMthdInvalidTests(opt, rnd())}, @@ -524,19 +403,12 @@ Test::Subtests PGraphMthdInvalidTests::subtests() { } else { return { {"invalid00", new InvalidMthdInvalidTests(opt, rnd(), 0x00)}, - {"beta", new BetaMthdInvalidTests(opt, rnd())}, - {"rop", new RopMthdInvalidTests(opt, rnd())}, - {"chroma", new ChromaMthdInvalidTests(opt, rnd())}, - {"plane", new PlaneMthdInvalidTests(opt, rnd())}, - {"clip", new ClipMthdInvalidTests(opt, rnd())}, - {"pattern", new PatternMthdInvalidTests(opt, rnd())}, {"rect", new RectMthdInvalidTests(opt, rnd())}, {"point", new PointMthdInvalidTests(opt, rnd())}, {"line", new LineMthdInvalidTests(opt, rnd())}, {"lin", new LinMthdInvalidTests(opt, rnd())}, {"tri", new TriMthdInvalidTests(opt, rnd())}, {"gdi", new GdiMthdInvalidTests(opt, rnd())}, - {"m2mf", new M2mfMthdInvalidTests(opt, rnd())}, {"sifm", new SifmMthdInvalidTests(opt, rnd())}, {"invalid0f", new InvalidMthdInvalidTests(opt, rnd(), 0x0f)}, {"blit", new BlitMthdInvalidTests(opt, rnd())}, @@ -546,12 +418,9 @@ Test::Subtests PGraphMthdInvalidTests::subtests() { {"itm", new ItmMthdInvalidTests(opt, rnd())}, {"sifc", new SifcMthdInvalidTests(opt, rnd())}, {"invalid16", new InvalidMthdInvalidTests(opt, rnd(), 0x16)}, - {"d3d0", new D3D0MthdInvalidTests(opt, rnd())}, - {"zpoint", new ZPointMthdInvalidTests(opt, rnd())}, {"invalid19", new InvalidMthdInvalidTests(opt, rnd(), 0x19)}, {"invalid1a", new InvalidMthdInvalidTests(opt, rnd(), 0x1a)}, {"invalid1b", new InvalidMthdInvalidTests(opt, rnd(), 0x1b)}, - {"surf", new SurfMthdInvalidTests(opt, rnd())}, {"invalid1d", new InvalidMthdInvalidTests(opt, rnd(), 0x1d)}, {"invalid1e", new InvalidMthdInvalidTests(opt, rnd(), 0x1e)}, {"invalid1f", new InvalidMthdInvalidTests(opt, rnd(), 0x1f)}, diff --git a/hwtest/pgraph_mthd_misc.cc b/hwtest/pgraph_mthd_misc.cc index 6d7c0dd6..af2b4574 100644 --- a/hwtest/pgraph_mthd_misc.cc +++ b/hwtest/pgraph_mthd_misc.cc @@ -23,6 +23,7 @@ */ #include "pgraph.h" +#include "pgraph_mthd.h" #include "nva.h" namespace hwtest { @@ -167,6 +168,70 @@ public: } +void MthdNotify::adjust_orig_mthd() { + if (!(rnd() & 3)) { + if (chipset.card_type < 4) { + insrt(orig.notify, 0, 16, 0); + } else { + insrt(orig.ctx_switch[1], 16, 16, 0); + } + } +} + +bool MthdNotify::is_valid_val() { + if (chipset.card_type < 3) { + if ((cls & 0xf) == 0xd || (cls & 0xf) == 0xe) + return true; + return val == 0; + } else if (chipset.card_type < 4) { + return val < 0x10; + } else { + return val < 2; + } +} + +void MthdNotify::emulate_mthd() { + if (chipset.card_type < 3) { + if (exp.notify & 0x100000 && !exp.invalid) + exp.intr |= 0x10000000; + if (!(exp.ctx_switch[0] & 0x100)) + exp.invalid |= 0x100; + if (exp.notify & 0x110000) + exp.invalid |= 0x1000; + if (exp.invalid) { + exp.intr |= 1; + exp.access &= ~0x101; + } else { + exp.notify |= 0x10000; + } + } else if (chipset.card_type < 4) { + if (!extr(exp.invalid, 16, 1)) { + if (extr(exp.notify, 16, 1)) { + exp.intr |= 1; + exp.invalid |= 0x1000; + exp.fifo_enable = 0; + } + } + if (!extr(exp.invalid, 16, 1) && !extr(exp.invalid, 4, 1)) { + insrt(exp.notify, 16, 1, 1); + insrt(exp.notify, 20, 4, val); + } + } else { + int rval = val & 1; + if (chipset.card_type >= 0x10) + rval = val & 3; + if (extr(exp.notify, 16, 1)) + nv04_pgraph_blowup(&exp, 0x1000); + if (!extr(exp.ctx_switch[1], 16, 16)) + pgraph_state_error(&exp); + if (!extr(exp.nsource, 1, 1)) { + insrt(exp.notify, 16, 1, rval < 2); + insrt(exp.notify, 20, 1, rval & 1); + } + } +} + + bool PGraphMthdMiscTests::supported() { return chipset.card_type < 4; } diff --git a/hwtest/pgraph_mthd_sifm.cc b/hwtest/pgraph_mthd_sifm.cc index fc3792bc..13585731 100644 --- a/hwtest/pgraph_mthd_sifm.cc +++ b/hwtest/pgraph_mthd_sifm.cc @@ -23,6 +23,7 @@ */ #include "pgraph.h" +#include "pgraph_mthd.h" #include "nva.h" namespace hwtest { diff --git a/hwtest/pgraph_mthd_simple.cc b/hwtest/pgraph_mthd_simple.cc index 1b27af13..756d43ce 100644 --- a/hwtest/pgraph_mthd_simple.cc +++ b/hwtest/pgraph_mthd_simple.cc @@ -23,284 +23,19 @@ */ #include "pgraph.h" +#include "pgraph_mthd.h" #include "nva.h" namespace hwtest { namespace pgraph { -namespace { - -class MthdBetaTest : public MthdTest { - void choose_mthd() override { - if (chipset.card_type < 4) - cls = 0x01; - else - cls = 0x12; - mthd = 0x300; - trapbit = 2; - } - void emulate_mthd() override { - exp.beta = val; - if (exp.beta & 0x80000000) - exp.beta = 0; - exp.beta &= 0x7f800000; - } -public: - MthdBetaTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; - -class MthdBeta4Test : public MthdTest { - bool supported() override { return chipset.card_type >= 4; } - void choose_mthd() override { - cls = 0x72; - mthd = 0x300; - trapbit = 2; - } - void emulate_mthd() override { - exp.beta4 = val; - } -public: - MthdBeta4Test(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; - -class MthdRopTest : public MthdTest { - void choose_mthd() override { - if (chipset.card_type < 4) - cls = 0x02; - else - cls = 0x43; - mthd = 0x300; - trapbit = 2; - } - void adjust_orig_mthd() override { - if (rnd() & 1) { - val &= 0xff; - val ^= 1 << (rnd() & 0x1f); - } - } - bool is_valid_val() override { - return chipset.card_type >= 3 || !(val & ~0xff); - } - void emulate_mthd() override { - exp.rop = val & 0xff; - } -public: - MthdRopTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; - -class MthdChromaPlaneTest : public MthdTest { - void choose_mthd() override { - if (chipset.card_type < 4) { - if (rnd() & 1) - cls = 0x03; - else - cls = 0x04; - } else { - if (rnd() & 1) - cls = 0x17; - else - cls = 0x57; - } - mthd = 0x304; - trapbit = 3; - } - void emulate_mthd() override { - if (chipset.card_type < 4) { - uint32_t color = pgraph_to_a1r10g10b10(pgraph_expand_color(&exp, val)); - if (cls == 0x04) - exp.plane = color; - else - exp.chroma = color; - } else { - if (cls == 0x17) - nv04_pgraph_set_chroma_nv01(&exp, val); - else - exp.chroma = val; - } - } -public: - MthdChromaPlaneTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; - -class MthdPatternShapeTest : public MthdTest { - void choose_mthd() override { - if (chipset.card_type < 4) - cls = 0x06; - else - cls = (rnd() & 1) ? 0x18 : 0x44; - mthd = 0x308; - trapbit = 4; - } - void adjust_orig_mthd() override { - if (rnd() & 1) - val &= 0xf; - } - bool is_valid_val() override { - return val <= 2; - } - void emulate_mthd() override { - insrt(exp.pattern_config, 0, 2, val); - } -public: - MthdPatternShapeTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; - -class MthdPatternSelectTest : public MthdTest { - bool supported() override { return chipset.card_type >= 4; } - void choose_mthd() override { - cls = 0x44; - mthd = 0x30c; - trapbit = 5; - } - void adjust_orig_mthd() override { - if (rnd() & 1) - val &= 0xf; - } - bool is_valid_val() override { - return val == 1 || val == 2; - } - void emulate_mthd() override { - insrt(exp.pattern_config, 4, 1, extr(val, 1, 1)); - insrt(exp.ctx_valid, 22, 1, !extr(exp.nsource, 1, 1)); - } -public: - MthdPatternSelectTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; - -class MthdPatternMonoColorTest : public MthdTest { - int idx; - void choose_mthd() override { - if (chipset.card_type < 4) - cls = 0x06; - else - cls = (rnd() & 1) ? 0x18 : 0x44; - idx = rnd() & 1; - mthd = 0x310 + idx * 4; - trapbit = (cls == 0x18 ? 5 : 6) + idx; - } - void emulate_mthd() override { - if (chipset.card_type < 4) { - struct pgraph_color c = pgraph_expand_color(&exp, val); - exp.pattern_mono_rgb[idx] = c.r << 20 | c.g << 10 | c.b; - exp.pattern_mono_a[idx] = c.a; - } else if (cls == 0x18) { - nv04_pgraph_set_pattern_mono_color_nv01(&exp, idx, val); - } else { - exp.pattern_mono_color[idx] = val; - } - } -public: - MthdPatternMonoColorTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; - -class MthdPatternMonoBitmapTest : public MthdTest { - int idx; - void choose_mthd() override { - if (chipset.card_type < 4) - cls = 0x06; - else - cls = (rnd() & 1) ? 0x18 : 0x44; - idx = rnd() & 1; - mthd = 0x318 + idx * 4; - trapbit = (cls == 0x18 ? 7 : 8) + idx; - } - void emulate_mthd() override { - uint32_t rval = nv04_pgraph_bswap(&exp, val); - if (chipset.card_type == 3) { - // yup, orig. hw bug. - exp.pattern_mono_bitmap[idx] = pgraph_expand_mono(&orig, rval); - } else { - exp.pattern_mono_bitmap[idx] = pgraph_expand_mono(&exp, rval); - } - if (chipset.card_type >= 4 && cls == 0x18) { - uint32_t fmt = extr(exp.ctx_switch[1], 0, 2); - if (fmt != 1 && fmt != 2) { - pgraph_state_error(&exp); - } - insrt(exp.ctx_valid, 26+idx, 1, !extr(exp.nsource, 1, 1)); - } - } -public: - MthdPatternMonoBitmapTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; - -class MthdPatternColorY8Test : public MthdTest { - int idx; - bool supported() override { return chipset.card_type >= 4; } - void choose_mthd() override { - cls = 0x44; - idx = rnd() & 0xf; - mthd = 0x400 + idx * 4; - trapbit = 10; - } - void emulate_mthd() override { - uint32_t rval = nv04_pgraph_bswap(&exp, val); - for (int i = 0; i < 4; i++) - exp.pattern_color[idx*4+i] = extr(rval, 8*i, 8) * 0x010101; - } -public: - MthdPatternColorY8Test(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; - -class MthdPatternColorR5G6B5Test : public MthdTest { - int idx; - bool supported() override { return chipset.card_type >= 4; } - void choose_mthd() override { - cls = 0x44; - idx = rnd() & 0x1f; - mthd = 0x500 + idx * 4; - trapbit = 12; - } - void emulate_mthd() override { - uint32_t rval = nv04_pgraph_hswap(&exp, val); - for (int i = 0; i < 2; i++) { - uint8_t b = extr(rval, i * 16 + 0, 5) * 0x21 >> 2; - uint8_t g = extr(rval, i * 16 + 5, 6) * 0x41 >> 4; - uint8_t r = extr(rval, i * 16 + 11, 5) * 0x21 >> 2; - exp.pattern_color[idx*2+i] = b | g << 8 | r << 16; - } - } -public: - MthdPatternColorR5G6B5Test(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; - -class MthdPatternColorR5G5B5Test : public MthdTest { - int idx; - bool supported() override { return chipset.card_type >= 4; } - void choose_mthd() override { - cls = 0x44; - idx = rnd() & 0x1f; - mthd = 0x600 + idx * 4; - trapbit = 11; - } - void emulate_mthd() override { - uint32_t rval = nv04_pgraph_hswap(&exp, val); - for (int i = 0; i < 2; i++) { - uint8_t b = extr(rval, i * 16 + 0, 5) * 0x21 >> 2; - uint8_t g = extr(rval, i * 16 + 5, 5) * 0x21 >> 2; - uint8_t r = extr(rval, i * 16 + 10, 5) * 0x21 >> 2; - exp.pattern_color[idx*2+i] = b | g << 8 | r << 16; - } - } -public: - MthdPatternColorR5G5B5Test(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; +void MthdSolidColor::emulate_mthd() { + exp.misc32[0] = val; + if (chipset.card_type >= 3) + insrt(exp.valid[0], 16, 1, 1); +} -class MthdPatternColorR8G8B8Test : public MthdTest { - int idx; - bool supported() override { return chipset.card_type >= 4; } - void choose_mthd() override { - cls = 0x44; - idx = rnd() & 0x3f; - mthd = 0x700 + idx * 4; - trapbit = 13; - } - void emulate_mthd() override { - exp.pattern_color[idx] = extr(val, 0, 24); - } -public: - MthdPatternColorR8G8B8Test(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; +namespace { class MthdSolidColorTest : public MthdTest { void choose_mthd() override { @@ -330,7 +65,7 @@ class MthdSolidColorTest : public MthdTest { abort(); } } else if (chipset.card_type < 4) { - switch (rnd() % 8) { + switch (rnd() % 7) { case 0: mthd = 0x304; cls = 7 + rnd()%5; @@ -359,10 +94,6 @@ class MthdSolidColorTest : public MthdTest { mthd = 0x7fc; cls = 0xc; break; - case 7: - mthd = 0x800 | (rnd()&0x7f8); - cls = 0x18; - break; default: abort(); } @@ -648,18 +379,6 @@ bool PGraphMthdSimpleTests::supported() { Test::Subtests PGraphMthdSimpleTests::subtests() { return { - {"beta", new MthdBetaTest(opt, rnd())}, - {"beta4", new MthdBeta4Test(opt, rnd())}, - {"rop", new MthdRopTest(opt, rnd())}, - {"chroma_plane", new MthdChromaPlaneTest(opt, rnd())}, - {"pattern_shape", new MthdPatternShapeTest(opt, rnd())}, - {"pattern_select", new MthdPatternSelectTest(opt, rnd())}, - {"pattern_mono_color", new MthdPatternMonoColorTest(opt, rnd())}, - {"pattern_mono_bitmap", new MthdPatternMonoBitmapTest(opt, rnd())}, - {"pattern_color_y8", new MthdPatternColorY8Test(opt, rnd())}, - {"pattern_color_r5g6b5", new MthdPatternColorR5G6B5Test(opt, rnd())}, - {"pattern_color_r5g5b5", new MthdPatternColorR5G5B5Test(opt, rnd())}, - {"pattern_color_r8g8b8", new MthdPatternColorR8G8B8Test(opt, rnd())}, {"solid_color", new MthdSolidColorTest(opt, rnd())}, {"bitmap_color", new MthdBitmapColorTest(opt, rnd())}, {"subdivide", new MthdSubdivideTest(opt, rnd())}, diff --git a/hwtest/pgraph_mthd_surf.cc b/hwtest/pgraph_mthd_surf.cc deleted file mode 100644 index 93eb8698..00000000 --- a/hwtest/pgraph_mthd_surf.cc +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2016 Marcin Kościelnicki <koriakin@0x04.net> - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "pgraph.h" -#include "nva.h" - -namespace hwtest { -namespace pgraph { - -namespace { - -class MthdSurfFormatTest : public MthdTest { - void choose_mthd() override { - cls = 0x1c; - mthd = 0x300; - } - void adjust_orig_mthd() override { - if (rnd() & 1) { - val &= 0x01010003; - val ^= 1 << (rnd() & 0x1f); - } - } - bool is_valid_val() override { - return val == 1 || val == 0x01000000 || val == 0x01010000 || val == 0x01010001; - } - void emulate_mthd() override { - int s = extr(exp.ctx_switch[0], 16, 2); - int f = 1; - if (extr(val, 0, 1)) - f = 0; - if (!extr(val, 16, 1)) - f = 2; - if (!extr(val, 24, 1)) - f = 3; - insrt(exp.surf_format, 4*s, 3, f | 4); - } -public: - MthdSurfFormatTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; - -class MthdSurfPitchTest : public MthdTest { - void choose_mthd() override { - cls = 0x1c; - mthd = 0x308; - } - void emulate_mthd() override { - int s = extr(exp.ctx_switch[0], 16, 2); - exp.surf_pitch[s] = val & 0x1ff0; - } -public: - MthdSurfPitchTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; - -class MthdSurfOffsetTest : public MthdTest { - void choose_mthd() override { - cls = 0x1c; - mthd = 0x30c; - } - void emulate_mthd() override { - int s = extr(exp.ctx_switch[0], 16, 2); - exp.surf_offset[s] = val & pgraph_offset_mask(&chipset); - } -public: - MthdSurfOffsetTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; - -} - -bool PGraphMthdSurfTests::supported() { - return chipset.card_type >= 3 && chipset.card_type < 4; -} - -Test::Subtests PGraphMthdSurfTests::subtests() { - return { - {"format", new MthdSurfFormatTest(opt, rnd())}, - {"pitch", new MthdSurfPitchTest(opt, rnd())}, - {"offset", new MthdSurfOffsetTest(opt, rnd())}, - }; -} - -} -} diff --git a/hwtest/pgraph_mthd_xy.cc b/hwtest/pgraph_mthd_xy.cc index 953e2995..b357789f 100644 --- a/hwtest/pgraph_mthd_xy.cc +++ b/hwtest/pgraph_mthd_xy.cc @@ -23,6 +23,7 @@ */ #include "pgraph.h" +#include "pgraph_mthd.h" #include "nva.h" namespace hwtest { @@ -33,60 +34,42 @@ namespace { class MthdClipTest : public MthdTest { int idx; int which; + bool supported() { return chipset.card_type >= 3; } int repeats() override { return 10000; }; - void adjust_orig_mthd() override { - if (chipset.card_type < 3) { - /* XXX: submitting on BLIT causes an actual blit */ - if (idx && extr(orig.access, 12, 5) == 0x10) - insrt(orig.access, 12, 5, 0); - } - } void choose_mthd() override { idx = rnd() & 1; - if (chipset.card_type < 3) { - cls = 0x05; - mthd = 0x300 + idx * 4;; - which = 0; - } else { - switch (rnd() % 7) { - case 0: - cls = 0x05; - mthd = 0x300 + idx * 4; - which = 0; - break; - case 1: - cls = 0x0c; - mthd = 0x7f4 + idx * 4; - which = 3; - break; - case 2: - cls = 0x0c; - mthd = 0xbec + idx * 4; - which = 3; - break; - case 3: - cls = 0x0c; - mthd = 0xfe8 + idx * 4; - which = 3; - break; - case 4: - cls = 0x0c; - mthd = 0x13e4 + idx * 4; - which = 3; - break; - case 5: - cls = 0x0e; - mthd = 0x0308 + idx * 4; - which = 1; - break; - case 6: - cls = 0x15; - mthd = 0x0310 + idx * 4; - which = 2; - break; - default: - abort(); - } + switch (rnd() % 7) { + default: + case 1: + cls = 0x0c; + mthd = 0x7f4 + idx * 4; + which = 3; + break; + case 2: + cls = 0x0c; + mthd = 0xbec + idx * 4; + which = 3; + break; + case 3: + cls = 0x0c; + mthd = 0xfe8 + idx * 4; + which = 3; + break; + case 4: + cls = 0x0c; + mthd = 0x13e4 + idx * 4; + which = 3; + break; + case 5: + cls = 0x0e; + mthd = 0x0308 + idx * 4; + which = 1; + break; + case 6: + cls = 0x15; + mthd = 0x0310 + idx * 4; + which = 2; + break; } if (!(rnd() & 3)) { val &= ~0xffff; @@ -1556,53 +1539,6 @@ public: MthdIfcDataTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} }; -class MthdZPointZetaTest : public MthdTest { - int repeats() override { return 10000; }; - bool supported() override { return chipset.card_type == 3; } - void adjust_orig_mthd() override { - if (rnd() & 3) - insrt(orig.cliprect_ctrl, 8, 1, 0); - if (rnd() & 3) - insrt(orig.debug[2], 28, 1, 0); - if (rnd() & 3) { - insrt(orig.xy_misc_4[0], 4, 4, 0); - insrt(orig.xy_misc_4[1], 4, 4, 0); - } - if (rnd() & 3) { - orig.valid[0] = 0x0fffffff; - if (rnd() & 1) { - orig.valid[0] &= ~0xf0f; - } - orig.valid[0] ^= 1 << (rnd() & 0x1f); - orig.valid[0] ^= 1 << (rnd() & 0x1f); - } - if (rnd() & 1) { - insrt(orig.ctx_switch[0], 24, 5, 0x17); - insrt(orig.ctx_switch[0], 13, 2, 0); - int j; - for (j = 0; j < 8; j++) { - insrt(orig.ctx_cache[j][0], 24, 5, 0x17); - insrt(orig.ctx_cache[j][0], 13, 2, 0); - } - } - orig.debug[2] &= 0xffdfffff; - orig.debug[3] &= 0xfffeffff; - orig.debug[3] &= 0xfffdffff; - } - void choose_mthd() override { - cls = 0x18; - int idx = rnd() & 0xff; - mthd = 0x804 + idx * 8; - } - void emulate_mthd() override { - insrt(exp.misc32[1], 16, 16, extr(val, 16, 16)); - pgraph_prep_draw(&exp, false, false); - nv03_pgraph_vtx_add(&exp, 0, 0, exp.vtx_xy[0][0], 1, 0, false, false); - } -public: - MthdZPointZetaTest(hwtest::TestOptions &opt, uint32_t seed) : MthdTest(opt, seed) {} -}; - class MthdSifcDiffTest : public MthdTest { bool xy; int repeats() override { return 10000; }; @@ -1685,7 +1621,6 @@ Test::Subtests PGraphMthdXyTests::subtests() { {"rect", new MthdRectTest(opt, rnd())}, {"ixm_offset", new MthdIxmOffsetTest(opt, rnd())}, {"ifc_data", new MthdIfcDataTest(opt, rnd())}, - {"zpoint_zeta", new MthdZPointZetaTest(opt, rnd())}, {"sifc_diff", new MthdSifcDiffTest(opt, rnd())}, {"sifc_vtx", new MthdSifcVtxTest(opt, rnd())}, }; diff --git a/hwtest/pgraph_rop.cc b/hwtest/pgraph_rop.cc index 825d3419..f7b6b758 100644 --- a/hwtest/pgraph_rop.cc +++ b/hwtest/pgraph_rop.cc @@ -23,6 +23,7 @@ */ #include "pgraph.h" +#include "pgraph_mthd.h" #include "nva.h" namespace { diff --git a/include/nvhw/pgraph.h b/include/nvhw/pgraph.h index 99b86a0c..cca943b8 100644 --- a/include/nvhw/pgraph.h +++ b/include/nvhw/pgraph.h @@ -303,6 +303,9 @@ uint32_t nv04_pgraph_hswap(struct pgraph_state *state, uint32_t val); void nv04_pgraph_vtx_add(struct pgraph_state *state, int xy, int idx, uint32_t a, uint32_t b, uint32_t c, bool nostat); /* pgraph_d3d_nv3.c */ +uint16_t nv03_pgraph_convert_xy(uint32_t val); +uint32_t nv03_pgraph_convert_z(uint32_t val); +uint16_t nv03_pgraph_convert_uv(uint32_t val, int sz); 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); diff --git a/nvhw/pgraph_d3d_nv3.c b/nvhw/pgraph_d3d_nv3.c index 819a89a4..df103837 100644 --- a/nvhw/pgraph_d3d_nv3.c +++ b/nvhw/pgraph_d3d_nv3.c @@ -25,6 +25,55 @@ #include "nvhw/pgraph.h" #include "util.h" +uint16_t nv03_pgraph_convert_xy(uint32_t val) { + int e = extr(val, 23, 8); + bool s = extr(val, 31, 1); + uint32_t tv = extr(val, 0, 23) | 1 << 23; + if (e > 0x7f+10) { + tv = 0x7fff + s; + } else if (e < 0x7f-4) { + tv = 0; + } else { + tv >>= 0x7f + 10 - e + 24 - 15; + if (s) + tv = -tv; + } + return tv; +} + +uint32_t nv03_pgraph_convert_z(uint32_t val) { + int e = extr(val, 23, 8); + bool s = extr(val, 31, 1); + uint32_t tv = extr(val, 0, 23) | 1 << 23; + if (s) { + tv = 0; + } else if (e > 0x7f-1) { + tv = 0xffffff; + } else if (e < 0x7f-24) { + tv = 0; + } else { + tv >>= 0x7f-1 - e; + } + return ~tv & 0xffffff; +} + +uint16_t nv03_pgraph_convert_uv(uint32_t val, int sz) { + int e = extr(val, 23, 8); + bool s = extr(val, 31, 1); + uint32_t tv = extr(val, 0, 23) | 1 << 23; + e -= (11 - sz); + if (e > 0x7f-1) { + tv = 0x7fff + s; + } else if (e < 0x7f-15) { + tv = 0; + } else { + tv >>= 0x7f - 1 - e + 24 - 15; + if (s) + tv = -tv; + } + return tv; +} + bool nv03_pgraph_d3d_cmp(int func, uint32_t a, uint32_t b) { switch (func) { case 1: |