summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Koƛcielnicki <koriakin@0x04.net>2016-12-26 21:59:19 +0000
committerMarcin Koƛcielnicki <koriakin@0x04.net>2016-12-26 21:59:19 +0000
commitfc51424ed7197d0571b8ef9cdbbfa3b18b185199 (patch)
tree4a2e4d24ff5855fd7644116a30c6b7caeaa3378d
parent579edbc9b9e838474a01968b80197dfd2626133e (diff)
hwtest/pgraph: Convert celsius tex mthd tests.
-rw-r--r--hwtest/nv04_pgraph.cc462
-rw-r--r--hwtest/pgraph_class_celsius.cc289
2 files changed, 284 insertions, 467 deletions
diff --git a/hwtest/nv04_pgraph.cc b/hwtest/nv04_pgraph.cc
index bd5722e8..4b0d5915 100644
--- a/hwtest/nv04_pgraph.cc
+++ b/hwtest/nv04_pgraph.cc
@@ -408,460 +408,6 @@ static int test_invalid_mthd_celsius(struct hwtest_ctx *ctx) {
return HWTEST_RES_PASS;
}
-static int test_mthd_celsius_tex_offset(struct hwtest_ctx *ctx) {
- int i;
- for (i = 0; i < 10000; i++) {
- uint32_t val = jrand48(ctx->rand48);
- if (jrand48(ctx->rand48) & 1) {
- val &= ~0x3ff;
- if (jrand48(ctx->rand48) & 1) {
- val |= 1 << (jrand48(ctx->rand48) & 0x1f);
- }
- if (jrand48(ctx->rand48) & 1) {
- val |= 1 << (jrand48(ctx->rand48) & 0x1f);
- }
- }
- uint32_t cls, mthd;
- int idx;
- int trapbit;
- uint32_t mask;
- idx = jrand48(ctx->rand48) & 1;
- cls = get_random_celsius(ctx);
- mthd = 0x218 + idx * 4;
- trapbit = 15;
- mask = 0x7f;
- 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, trapbit);
- if (!extr(exp.intr, 4, 1)) {
- if (extr(exp.debug[3], 20, 1) && (val & mask))
- nv04_pgraph_blowup(&exp, 2);
- if (!exp.intr)
- exp.celsius_tex_offset[idx] = val;
- insrt(exp.valid[1], idx ? 22 : 14, 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_celsius_tex_format(struct hwtest_ctx *ctx) {
- int i;
- for (i = 0; i < 10000; i++) {
- uint32_t val = jrand48(ctx->rand48);
- if (jrand48(ctx->rand48) & 1) {
- if (jrand48(ctx->rand48) & 3)
- insrt(val, 0, 2, 1);
- if (jrand48(ctx->rand48) & 3)
- insrt(val, 3, 2, 1);
- if (jrand48(ctx->rand48) & 3)
- insrt(val, 5, 2, 1);
- if (!(jrand48(ctx->rand48) & 3))
- insrt(val, 7, 5, 0x19 + nrand48(ctx->rand48) % 4);
- if (jrand48(ctx->rand48) & 1)
- insrt(val, 20, 4, extr(val, 16, 4));
- if (jrand48(ctx->rand48) & 3)
- insrt(val, 24, 3, 3);
- if (jrand48(ctx->rand48) & 3)
- insrt(val, 28, 3, 3);
- if (jrand48(ctx->rand48) & 1) {
- if (jrand48(ctx->rand48) & 3)
- insrt(val, 2, 1, 0);
- if (jrand48(ctx->rand48) & 3)
- insrt(val, 12, 4, 1);
- }
- }
- uint32_t cls, mthd;
- int idx;
- int trapbit;
- idx = jrand48(ctx->rand48) & 1;
- cls = get_random_celsius(ctx);
- mthd = 0x220 + idx * 4;
- trapbit = 16;
- 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, trapbit);
- if (!extr(exp.intr, 4, 1)) {
- uint32_t rval = val & 0xffffffd6;
- int omips = extr(val, 12, 4);
- int mips = omips;
- int su = extr(val, 16, 4);
- int sv = extr(val, 20, 4);
- int fmt = extr(val, 7, 5);
- if (mips > su && mips > sv)
- mips = (su > sv ? su : sv) + 1;
- insrt(rval, 12, 4, mips);
- bool bad = false;
- if (!extr(val, 0, 2) || extr(val, 0, 2) == 3)
- bad = true;
- if (extr(val, 2, 1)) {
- if (su != sv)
- bad = true;
- if (su >= 0xa && (fmt == 6 || fmt == 7 || fmt == 0xb || fmt == 0xe || fmt == 0xf))
- bad = true;
- if (su >= 0xb)
- bad = true;
- }
- if (!extr(val, 3, 2) || extr(val, 3, 2) == 3)
- bad = true;
- if (!extr(val, 5, 2) || extr(val, 5, 2) == 3)
- bad = true;
- if (fmt == 0xd)
- bad = true;
- if (fmt >= 0x1d)
- bad = true;
- if (omips > 0xc || omips == 0)
- bad = true;
- if (fmt >= 0x19) {
- if (extr(val, 3, 2) != 1)
- bad = true;
- if (cls != 0x99)
- bad = true;
- }
- if (fmt >= 0x10) {
- if (extr(val, 2, 1))
- bad = true;
- if (extr(val, 24, 3) != 3)
- bad = true;
- if (extr(val, 28, 3) != 3)
- bad = true;
- if (omips != 1)
- bad = true;
- }
- if (su > 0xb || sv > 0xb)
- bad = true;
- if (extr(val, 24, 3) < 1 || extr(val, 24, 3) > 5)
- bad = true;
- if (extr(val, 28, 3) < 1 || extr(val, 28, 3) > 5)
- bad = true;
- if (extr(exp.debug[3], 20, 1) && bad)
- nv04_pgraph_blowup(&exp, 2);
- if (!exp.intr)
- exp.celsius_tex_format[idx] = rval | (exp.celsius_tex_format[idx] & 8);
- insrt(exp.valid[1], idx ? 21 : 15, 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_celsius_tex_control(struct hwtest_ctx *ctx) {
- int i;
- for (i = 0; i < 10000; i++) {
- uint32_t val = jrand48(ctx->rand48);
- uint32_t cls, mthd;
- int idx;
- int trapbit;
- idx = jrand48(ctx->rand48) & 1;
- cls = get_random_celsius(ctx);
- mthd = 0x228 + idx * 4;
- trapbit = 17;
- 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, trapbit);
- if (!extr(exp.intr, 4, 1)) {
- uint32_t rval = val & 0x7fffffff;
- bool bad = false;
- if (extr(val, 31, 1))
- bad = true;
- if (extr(val, 5, 1))
- bad = true;
- if (extr(exp.debug[3], 20, 1) && bad)
- nv04_pgraph_blowup(&exp, 2);
- if (!exp.intr) {
- exp.celsius_tex_control[idx] = rval;
- if (idx == 0) {
- insrt(exp.celsius_unkf44, 0, 1, extr(val, 30, 1));
- } else {
- insrt(exp.celsius_unkf44, 14, 1, extr(val, 30, 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_celsius_tex_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 &= ~0xffff;
- if (jrand48(ctx->rand48) & 1) {
- val |= 1 << (jrand48(ctx->rand48) & 0x1f);
- }
- if (jrand48(ctx->rand48) & 1) {
- val |= 1 << (jrand48(ctx->rand48) & 0x1f);
- }
- }
- uint32_t cls, mthd;
- int idx;
- int trapbit;
- idx = jrand48(ctx->rand48) & 1;
- cls = get_random_celsius(ctx);
- mthd = 0x230 + idx * 4;
- trapbit = 18;
- 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, trapbit);
- if (!extr(exp.intr, 4, 1)) {
- bool bad = false;
- if (extr(val, 0, 16))
- bad = true;
- if (extr(exp.debug[3], 20, 1) && bad)
- nv04_pgraph_blowup(&exp, 2);
- if (!exp.intr) {
- exp.celsius_tex_pitch[idx] = val & 0xffff0000;
- }
- }
- 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_celsius_tex_unk238(struct hwtest_ctx *ctx) {
- int i;
- for (i = 0; i < 10000; i++) {
- uint32_t val = jrand48(ctx->rand48);
- uint32_t cls, mthd;
- int idx;
- int trapbit;
- idx = jrand48(ctx->rand48) & 1;
- cls = get_random_celsius(ctx);
- mthd = 0x238 + idx * 4;
- trapbit = 19;
- 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, trapbit);
- if (!extr(exp.intr, 4, 1)) {
- if (!exp.intr) {
- exp.celsius_tex_unk238[idx] = val;
- }
- }
- 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_celsius_tex_rect(struct hwtest_ctx *ctx) {
- int i;
- for (i = 0; i < 10000; i++) {
- uint32_t val = jrand48(ctx->rand48);
- if (jrand48(ctx->rand48) & 1) {
- if (jrand48(ctx->rand48) & 1) {
- val &= ~0xf000f800;
- }
- if (jrand48(ctx->rand48) & 1) {
- if (jrand48(ctx->rand48) & 1) {
- val &= ~0xffff;
- } else {
- val &= ~0xffff0000;
- }
- }
- if (jrand48(ctx->rand48) & 1) {
- val |= 1 << (jrand48(ctx->rand48) & 0x1f);
- }
- if (jrand48(ctx->rand48) & 1) {
- val |= 1 << (jrand48(ctx->rand48) & 0x1f);
- }
- }
- uint32_t cls, mthd;
- int idx;
- int trapbit;
- idx = jrand48(ctx->rand48) & 1;
- cls = get_random_celsius(ctx);
- mthd = 0x240 + idx * 4;
- trapbit = 20;
- 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, trapbit);
- if (!extr(exp.intr, 4, 1)) {
- bool bad = false;
- if (extr(val, 16, 1))
- bad = true;
- if (!extr(val, 0, 16) || extr(val, 0, 16) >= 0x800)
- bad = true;
- if (!extr(val, 17, 15) || extr(val, 17, 15) >= 0x800)
- bad = true;
- if (extr(exp.debug[3], 20, 1) && bad)
- nv04_pgraph_blowup(&exp, 2);
- if (!exp.intr) {
- exp.celsius_tex_rect[idx] = val & 0x07ff07ff;
- }
- }
- 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_celsius_tex_filter(struct hwtest_ctx *ctx) {
- int i;
- for (i = 0; i < 10000; i++) {
- uint32_t val = jrand48(ctx->rand48);
- if (jrand48(ctx->rand48) & 1) {
- if (jrand48(ctx->rand48) & 3)
- insrt(val, 13, 11, 0);
- if (jrand48(ctx->rand48) & 3)
- insrt(val, 24, 4, 1);
- if (jrand48(ctx->rand48) & 3)
- insrt(val, 28, 4, 1);
- if (jrand48(ctx->rand48) & 1) {
- val ^= 1 << (jrand48(ctx->rand48) & 0x1f);
- }
- if (jrand48(ctx->rand48) & 1) {
- val ^= 1 << (jrand48(ctx->rand48) & 0x1f);
- }
- }
- uint32_t cls, mthd;
- int idx;
- int trapbit;
- idx = jrand48(ctx->rand48) & 1;
- cls = get_random_celsius(ctx);
- mthd = 0x248 + idx * 4;
- trapbit = 21;
- 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, trapbit);
- if (!extr(exp.intr, 4, 1)) {
- uint32_t rval = val & 0x77001fff;
- bool bad = false;
- if (extr(val, 13, 11))
- bad = true;
- if (extr(val, 24, 4) < 1 || extr(val, 24, 4) > 6)
- bad = true;
- if (extr(val, 28, 4) < 1 || extr(val, 28, 4) > 2)
- bad = true;
- if (extr(exp.debug[3], 20, 1) && bad)
- nv04_pgraph_blowup(&exp, 2);
- if (!exp.intr)
- exp.celsius_tex_filter[idx] = rval;
- insrt(exp.valid[1], idx ? 23 : 16, 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_celsius_tex_palette(struct hwtest_ctx *ctx) {
- int i;
- for (i = 0; i < 10000; i++) {
- uint32_t val = jrand48(ctx->rand48);
- if (jrand48(ctx->rand48) & 1) {
- val &= ~0x3c;
- if (jrand48(ctx->rand48) & 1) {
- val |= 1 << (jrand48(ctx->rand48) & 0x1f);
- }
- if (jrand48(ctx->rand48) & 1) {
- val |= 1 << (jrand48(ctx->rand48) & 0x1f);
- }
- }
- uint32_t cls, mthd;
- int idx;
- int trapbit;
- idx = jrand48(ctx->rand48) & 1;
- cls = get_random_celsius(ctx);
- mthd = 0x250 + idx * 4;
- trapbit = 22;
- 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, trapbit);
- if (!extr(exp.intr, 4, 1)) {
- uint32_t rval = val & 0xffffffc1;
- bool bad = false;
- if (val & 0x3e)
- bad = true;
- if (extr(exp.debug[3], 20, 1) && bad)
- nv04_pgraph_blowup(&exp, 2);
- if (!exp.intr) {
- exp.celsius_tex_palette[idx] = rval;
- }
- }
- 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_celsius_rc_in(struct hwtest_ctx *ctx) {
int i;
for (i = 0; i < 10000; i++) {
@@ -1249,14 +795,6 @@ HWTEST_DEF_GROUP(invalid_mthd,
)
HWTEST_DEF_GROUP(celsius_mthd,
- HWTEST_TEST(test_mthd_celsius_tex_offset, 0),
- HWTEST_TEST(test_mthd_celsius_tex_format, 0),
- HWTEST_TEST(test_mthd_celsius_tex_control, 0),
- HWTEST_TEST(test_mthd_celsius_tex_pitch, 0),
- HWTEST_TEST(test_mthd_celsius_tex_unk238, 0),
- HWTEST_TEST(test_mthd_celsius_tex_rect, 0),
- HWTEST_TEST(test_mthd_celsius_tex_filter, 0),
- HWTEST_TEST(test_mthd_celsius_tex_palette, 0),
HWTEST_TEST(test_mthd_celsius_rc_in, 0),
HWTEST_TEST(test_mthd_celsius_rc_factor, 0),
HWTEST_TEST(test_mthd_celsius_rc_out, 0),
diff --git a/hwtest/pgraph_class_celsius.cc b/hwtest/pgraph_class_celsius.cc
index a71cf9d8..0a51684f 100644
--- a/hwtest/pgraph_class_celsius.cc
+++ b/hwtest/pgraph_class_celsius.cc
@@ -87,10 +87,13 @@ class MthdDmaVtx : public SingleMthdTest {
exp.fifo_enable = 0;
}
}
+#if 0
+ // XXX: figure this out
if (dcls == 0x30 && nv04_pgraph_is_nv15p(&chipset)) {
exp.intr |= 0x400;
exp.fifo_enable = 0;
}
+#endif
if (prot_err)
nv04_pgraph_blowup(&exp, 4);
insrt(exp.celsius_dma, 0, 16, rval);
@@ -115,6 +118,263 @@ class MthdDmaState : public SingleMthdTest {
using SingleMthdTest::SingleMthdTest;
};
+class MthdCelsiusTexOffset : public SingleMthdTest {
+ void adjust_orig_mthd() override {
+ val &= ~0x7f;
+ if (rnd() & 1) {
+ val ^= 1 << (rnd() & 0x1f);
+ }
+ }
+ bool is_valid_val() override {
+ return !(val & 0x7f);
+ }
+ void emulate_mthd() override {
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_tex_offset[idx] = val;
+ }
+ insrt(exp.valid[1], idx ? 22 : 14, 1, 1);
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
+class MthdCelsiusTexFormat : public SingleMthdTest {
+ void adjust_orig_mthd() override {
+ if (rnd() & 1) {
+ if (rnd() & 3)
+ insrt(val, 0, 2, 1);
+ if (rnd() & 3)
+ insrt(val, 3, 2, 1);
+ if (rnd() & 3)
+ insrt(val, 5, 2, 1);
+ if (!(rnd() & 3))
+ insrt(val, 7, 5, 0x19 + rnd() % 4);
+ if (rnd() & 1)
+ insrt(val, 20, 4, extr(val, 16, 4));
+ if (rnd() & 3)
+ insrt(val, 24, 3, 3);
+ if (rnd() & 3)
+ insrt(val, 28, 3, 3);
+ if (rnd() & 1) {
+ if (rnd() & 3)
+ insrt(val, 2, 1, 0);
+ if (rnd() & 3)
+ insrt(val, 12, 4, 1);
+ }
+ }
+ }
+ bool is_valid_val() override {
+ int mips = extr(val, 12, 4);
+ int su = extr(val, 16, 4);
+ int sv = extr(val, 20, 4);
+ int fmt = extr(val, 7, 5);
+ if (!extr(val, 0, 2) || extr(val, 0, 2) == 3)
+ return false;
+ if (extr(val, 2, 1)) {
+ if (su != sv)
+ return false;
+ if (su >= 0xa && (fmt == 6 || fmt == 7 || fmt == 0xb || fmt == 0xe || fmt == 0xf))
+ return false;
+ if (su >= 0xb)
+ return false;
+ }
+ if (!extr(val, 3, 2) || extr(val, 3, 2) == 3)
+ return false;
+ if (!extr(val, 5, 2) || extr(val, 5, 2) == 3)
+ return false;
+ if (fmt == 0xd)
+ return false;
+ if (fmt >= 0x1d)
+ return false;
+ if (mips > 0xc || mips == 0)
+ return false;
+ if (fmt >= 0x19) {
+ if (extr(val, 3, 2) != 1)
+ return false;
+ if (cls != 0x99)
+ return false;
+ }
+ if (fmt >= 0x10) {
+ if (extr(val, 2, 1))
+ return false;
+ if (extr(val, 24, 3) != 3)
+ return false;
+ if (extr(val, 28, 3) != 3)
+ return false;
+ if (mips != 1)
+ return false;
+ }
+ if (su > 0xb || sv > 0xb)
+ return false;
+ if (extr(val, 24, 3) < 1 || extr(val, 24, 3) > 5)
+ return false;
+ if (extr(val, 28, 3) < 1 || extr(val, 28, 3) > 5)
+ return false;
+ return true;
+ }
+ void emulate_mthd() override {
+ uint32_t rval = val & 0xffffffd6;
+ int mips = extr(val, 12, 4);
+ int su = extr(val, 16, 4);
+ int sv = extr(val, 20, 4);
+ if (mips > su && mips > sv)
+ mips = (su > sv ? su : sv) + 1;
+ insrt(rval, 12, 4, mips);
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_tex_format[idx] = rval | (exp.celsius_tex_format[idx] & 8);
+ }
+ insrt(exp.valid[1], idx ? 21 : 15, 1, 1);
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
+class MthdCelsiusTexControl : public SingleMthdTest {
+ bool is_valid_val() override {
+ if (extr(val, 31, 1))
+ return false;
+ if (extr(val, 5, 1))
+ return false;
+ return true;
+ }
+ void emulate_mthd() override {
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_tex_control[idx] = val & 0x7fffffff;
+ insrt(exp.celsius_unkf44, idx ? 14 : 0, 1, extr(val, 30, 1));
+ }
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
+class MthdCelsiusTexPitch : public SingleMthdTest {
+ void adjust_orig_mthd() override {
+ if (rnd() & 1) {
+ val &= ~0xffff;
+ if (!(rnd() & 3)) {
+ val &= 0xe00f0000;
+ }
+ if (!(rnd() & 3))
+ val = 0;
+ if (rnd() & 1) {
+ val ^= 1 << (rnd() & 0x1f);
+ val ^= 1 << (rnd() & 0x1f);
+ }
+ }
+ }
+ bool is_valid_val() override {
+ return !(val & 0xffff) && !!(val & 0x3ff80000);
+ }
+ void emulate_mthd() override {
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_tex_pitch[idx] = val & 0xffff0000;
+ }
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
+class MthdCelsiusTexUnk238 : public SingleMthdTest {
+ void emulate_mthd() override {
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_tex_unk238[idx] = val;
+ }
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
+class MthdCelsiusTexRect : public SingleMthdTest {
+ void adjust_orig_mthd() override {
+ if (rnd() & 1) {
+ if (rnd() & 1) {
+ val &= ~0xf000f800;
+ }
+ if (rnd() & 1) {
+ if (rnd() & 1) {
+ val &= ~0xffff;
+ } else {
+ val &= ~0xffff0000;
+ }
+ }
+ if (rnd() & 1) {
+ val |= 1 << (rnd() & 0x1f);
+ }
+ if (rnd() & 1) {
+ val |= 1 << (rnd() & 0x1f);
+ }
+ }
+ }
+ bool is_valid_val() override {
+ if (extr(val, 16, 1))
+ return false;
+ if (!extr(val, 0, 16) || extr(val, 0, 16) >= 0x800)
+ return false;
+ if (!extr(val, 17, 15) || extr(val, 17, 15) >= 0x800)
+ return false;
+ return true;
+ }
+ void emulate_mthd() override {
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_tex_rect[idx] = val & 0x07ff07ff;
+ }
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
+class MthdCelsiusTexFilter : public SingleMthdTest {
+ void adjust_orig_mthd() override {
+ if (rnd() & 1) {
+ if (rnd() & 3)
+ insrt(val, 13, 11, 0);
+ if (rnd() & 3)
+ insrt(val, 24, 4, 1);
+ if (rnd() & 3)
+ insrt(val, 28, 4, 1);
+ if (rnd() & 1) {
+ val ^= 1 << (rnd() & 0x1f);
+ }
+ if (rnd() & 1) {
+ val ^= 1 << (rnd() & 0x1f);
+ }
+ }
+ }
+ bool is_valid_val() override {
+ if (extr(val, 13, 11))
+ return false;
+ if (extr(val, 24, 4) < 1 || extr(val, 24, 4) > 6)
+ return false;
+ if (extr(val, 28, 4) < 1 || extr(val, 28, 4) > 2)
+ return false;
+ return true;
+ }
+ void emulate_mthd() override {
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_tex_filter[idx] = val & 0x77001fff;
+ }
+ insrt(exp.valid[1], idx ? 23 : 16, 1, 1);
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
+class MthdCelsiusTexPalette : public SingleMthdTest {
+ void adjust_orig_mthd() override {
+ if (rnd() & 1) {
+ val &= ~0x3c;
+ if (rnd() & 1) {
+ val |= 1 << (rnd() & 0x1f);
+ }
+ if (rnd() & 1) {
+ val |= 1 << (rnd() & 0x1f);
+ }
+ }
+ }
+ bool is_valid_val() override {
+ return !(val & 0x3e);
+ }
+ void emulate_mthd() override {
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_tex_palette[idx] = val & 0xffffffc1;
+ }
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
class MthdDmaClipid : public SingleMthdTest {
bool takes_dma() override { return true; }
void emulate_mthd() override {
@@ -493,11 +753,30 @@ std::vector<SingleMthdTest *> Celsius::mthds() {
new MthdSurfPitch2(opt, rnd(), "surf_pitch_2", 12, cls, 0x20c, 2, 3, SURF_NV10),
new MthdSurfOffset(opt, rnd(), "color_offset", 13, cls, 0x210, 2, SURF_NV10),
new MthdSurfOffset(opt, rnd(), "zeta_offset", 14, cls, 0x214, 3, SURF_NV10),
- new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x218, 2), // XXX
- new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x220, 8), // XXX
- new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x240, 6), // XXX
- new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x260, 8), // XXX
- new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x280, 0xe), // XXX
+ new MthdCelsiusTexOffset(opt, rnd(), "tex_offset", 15, cls, 0x218, 2),
+ new MthdCelsiusTexFormat(opt, rnd(), "tex_format", 16, cls, 0x220, 2),
+ new MthdCelsiusTexControl(opt, rnd(), "tex_control", 17, cls, 0x228, 2),
+ new MthdCelsiusTexPitch(opt, rnd(), "tex_pitch", 18, cls, 0x230, 2),
+ new MthdCelsiusTexUnk238(opt, rnd(), "tex_unk238", 19, cls, 0x238, 2),
+ new MthdCelsiusTexRect(opt, rnd(), "tex_rect", 20, cls, 0x240, 2),
+ new MthdCelsiusTexFilter(opt, rnd(), "tex_filter", 21, cls, 0x248, 2),
+ new MthdCelsiusTexPalette(opt, rnd(), "tex_palette", 22, cls, 0x250, 2),
+ new UntestedMthd(opt, rnd(), "meh", 23, cls, 0x260, 2), // XXX
+ new UntestedMthd(opt, rnd(), "meh", 24, cls, 0x268, 2), // XXX
+ new UntestedMthd(opt, rnd(), "meh", 25, cls, 0x270, 2), // XXX
+ new UntestedMthd(opt, rnd(), "meh", 26, cls, 0x278, 2), // XXX
+ new UntestedMthd(opt, rnd(), "meh", 27, cls, 0x280, 2), // XXX
+ new UntestedMthd(opt, rnd(), "meh", 28, cls, 0x288), // XXX
+ new UntestedMthd(opt, rnd(), "meh", 29, cls, 0x28c), // XXX
+ new UntestedMthd(opt, rnd(), "meh", 30, cls, 0x290), // XXX
+ new UntestedMthd(opt, rnd(), "meh", 31, cls, 0x294), // XXX
+ new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x298), // XXX
+ new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x29c), // XXX
+ new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x2a0), // XXX
+ new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x2a4), // XXX
+ new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x2a8), // XXX
+ new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x2ac, 2), // XXX
+ new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x2b4), // XXX
new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x2c0, 0x10), // XXX
new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x300, 0x3e), // XXX
new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x400, 0x70), // XXX