summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Kościelnicki <koriakin@0x04.net>2016-12-22 21:10:09 +0000
committerMarcin Kościelnicki <koriakin@0x04.net>2016-12-22 21:10:09 +0000
commit0336841057dc4a2fa7c1111fad3e4217b80d8fd7 (patch)
tree30c3d718e819f834b148bb974c4b32803da707b4
parent307feb62387c275b9780d2abdddd16479ee11eef (diff)
hwtest/pgraph: Start grouping method tests by class.
-rw-r--r--hwtest/CMakeLists.txt7
-rw-r--r--hwtest/g80_gr.cc2
-rw-r--r--hwtest/hwtest.cc22
-rw-r--r--hwtest/hwtest.h4
-rw-r--r--hwtest/nv04_pgraph.cc389
-rw-r--r--hwtest/old.h4
-rw-r--r--hwtest/pgraph.cc76
-rw-r--r--hwtest/pgraph.h40
-rw-r--r--hwtest/pgraph_class.h156
-rw-r--r--hwtest/pgraph_class_clip.cc108
-rw-r--r--hwtest/pgraph_class_ctx.cc293
-rw-r--r--hwtest/pgraph_class_d3d0.cc (renamed from hwtest/pgraph_mthd_d3d0.cc)293
-rw-r--r--hwtest/pgraph_class_m2mf.cc (renamed from hwtest/pgraph_mthd_m2mf.cc)102
-rw-r--r--hwtest/pgraph_class_op.cc106
-rw-r--r--hwtest/pgraph_class_surf.cc130
-rw-r--r--hwtest/pgraph_mthd.cc74
-rw-r--r--hwtest/pgraph_mthd.h139
-rw-r--r--hwtest/pgraph_mthd_invalid.cc133
-rw-r--r--hwtest/pgraph_mthd_misc.cc65
-rw-r--r--hwtest/pgraph_mthd_sifm.cc1
-rw-r--r--hwtest/pgraph_mthd_simple.cc297
-rw-r--r--hwtest/pgraph_mthd_surf.cc103
-rw-r--r--hwtest/pgraph_mthd_xy.cc133
-rw-r--r--hwtest/pgraph_rop.cc1
-rw-r--r--include/nvhw/pgraph.h3
-rw-r--r--nvhw/pgraph_d3d_nv3.c49
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: