diff options
author | Marcin KoĆcielnicki <koriakin@0x04.net> | 2016-12-26 23:25:46 +0000 |
---|---|---|
committer | Marcin KoĆcielnicki <koriakin@0x04.net> | 2016-12-26 23:25:46 +0000 |
commit | 90bfc3f6ec512fb9ae4c3ee5a89b3044348d9d30 (patch) | |
tree | 382c8396735391448b26bdf859e664e560c054a2 | |
parent | 254066fd86aba05f55916c14af6f8ff4404ab6ca (diff) |
hwtest/pgraph: Nailed down Celsius methods 0x200:0x300.
-rw-r--r-- | hwtest/pgraph_class_celsius.cc | 298 | ||||
-rw-r--r-- | hwtest/pgraph_mthd.cc | 9 | ||||
-rw-r--r-- | hwtest/pgraph_mthd.h | 3 | ||||
-rw-r--r-- | hwtest/pgraph_state.cc | 5 | ||||
-rw-r--r-- | include/nvhw/pgraph.h | 3 |
5 files changed, 307 insertions, 11 deletions
diff --git a/hwtest/pgraph_class_celsius.cc b/hwtest/pgraph_class_celsius.cc index 9e3baad4..fa8c7db2 100644 --- a/hwtest/pgraph_class_celsius.cc +++ b/hwtest/pgraph_class_celsius.cc @@ -734,6 +734,287 @@ class MthdCelsiusLightModel : public SingleMthdTest { using SingleMthdTest::SingleMthdTest; }; +class MthdCelsiusLightMaterial : public SingleMthdTest { + void adjust_orig_mthd() override { + if (rnd() & 1) { + val &= 0xf; + if (rnd() & 1) { + val |= 1 << (rnd() & 0x1f); + } + if (rnd() & 1) { + val |= 1 << (rnd() & 0x1f); + } + } + } + bool can_warn() override { + return true; + } + void emulate_mthd() override { + if (val & ~0xf) { + warn(1); + } else { + if (!extr(exp.nsource, 1, 1)) { + insrt(exp.celsius_unkf40, 21, 4, val); + } + } + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdCelsiusFogMode : public SingleMthdTest { + void adjust_orig_mthd() override { + if (rnd() & 1) { + val &= 0xffff; + if (rnd() & 1) { + val &= 0xf; + if (rnd() & 1) { + val |= (rnd() & 1 ? 0x800 : 0x2600); + } + } + if (rnd() & 1) { + val |= 1 << (rnd() & 0x1f); + if (rnd() & 1) { + val |= 1 << (rnd() & 0x1f); + } + } + } + if (rnd() & 1) + insrt(exp.notify, 28, 3, 0); + } + bool can_warn() override { + return true; + } + void emulate_mthd() override { + uint32_t err = 0; + uint32_t rv = 0; + if (val == 0x800) { + rv = 1; + } else if (val == 0x801) { + rv = 3; + } else if (val == 0x802) { + rv = 5; + } else if (val == 0x803) { + rv = 7; + } else if (val == 0x2601) { + rv = 0; + } else { + err |= 1; + } + if (extr(exp.celsius_unkf48, 8, 1)) + err |= 4; + if (err) { + warn(err); + } else { + if (!extr(exp.nsource, 1, 1)) { + insrt(exp.celsius_unkf48, 0, 3, rv); + } + } + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdCelsiusFogCoord : public SingleMthdTest { + void adjust_orig_mthd() override { + if (rnd() & 1) { + val &= 0xffff; + if (rnd() & 1) { + val &= 0xf; + } + if (rnd() & 1) { + val |= 1 << (rnd() & 0x1f); + if (rnd() & 1) { + val |= 1 << (rnd() & 0x1f); + } + } + } + if (rnd() & 1) + insrt(exp.notify, 28, 3, 0); + } + bool can_warn() override { + return true; + } + void emulate_mthd() override { + uint32_t err = 0; + if (val > 3) + err |= 1; + if (extr(exp.celsius_unkf48, 8, 1)) + err |= 4; + if (err) { + warn(err); + } else { + if (!extr(exp.nsource, 1, 1)) { + insrt(exp.celsius_unkf40, 16, 2, val); + } + } + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdCelsiusFogEnable : public SingleMthdTest { + void adjust_orig_mthd() override { + if (rnd() & 1) { + val &= 0xffff; + if (rnd() & 1) { + val &= 0xf; + } + if (rnd() & 1) { + val |= 1 << (rnd() & 0x1f); + if (rnd() & 1) { + val |= 1 << (rnd() & 0x1f); + } + } + } + if (rnd() & 1) + insrt(exp.notify, 28, 3, 0); + } + bool can_warn() override { + return true; + } + void emulate_mthd() override { + uint32_t err = 0; + if (val > 1) + err |= 1; + if (extr(exp.celsius_unkf48, 8, 1)) + err |= 4; + if (err) { + warn(err); + } else { + if (!extr(exp.nsource, 1, 1)) { + insrt(exp.celsius_config_b, 8, 1, val); + insrt(exp.celsius_unkf44, 31, 1, val); + } + } + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdCelsiusFogColor : public SingleMthdTest { + void adjust_orig_mthd() override { + if (rnd() & 1) + insrt(exp.notify, 28, 3, 0); + } + bool can_warn() override { + return true; + } + void emulate_mthd() override { + if (extr(exp.celsius_unkf48, 8, 1)) { + warn(4); + } else { + if (!extr(exp.nsource, 1, 1)) { + insrt(exp.celsius_fog_color, 0, 8, extr(val, 16, 8)); + insrt(exp.celsius_fog_color, 8, 8, extr(val, 8, 8)); + insrt(exp.celsius_fog_color, 16, 8, extr(val, 0, 8)); + insrt(exp.celsius_fog_color, 24, 8, extr(val, 24, 8)); + } + } + insrt(exp.valid[1], 13, 1, 1); + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdCelsiusTexColorKey : public SingleMthdTest { + void adjust_orig_mthd() override { + if (rnd() & 1) + insrt(exp.notify, 28, 3, 0); + } + bool can_warn() override { + return true; + } + void emulate_mthd() override { + if (extr(exp.celsius_unkf48, 8, 1)) { + warn(4); + } else { + if (!extr(exp.nsource, 1, 1)) { + exp.celsius_tex_color_key[idx] = val; + } + } + if (idx == 0) + insrt(exp.valid[1], 12, 1, 1); + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdCelsiusClipRectMode : public SingleMthdTest { + void adjust_orig_mthd() override { + if (rnd() & 1) { + val &= 0xf; + if (rnd() & 1) { + val |= 1 << (rnd() & 0x1f); + if (rnd() & 1) { + val |= 1 << (rnd() & 0x1f); + } + } + } + } + bool is_valid_val() override { + return val < 2; + } + void emulate_mthd() override { + if (!extr(exp.nsource, 1, 1)) { + insrt(exp.celsius_unkf48, 4, 1, val); + } + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdCelsiusClipRectHoriz : public SingleMthdTest { + void adjust_orig_mthd() override { + if (rnd() & 1) { + val &= 0xffff; + val *= 0x00010001; + } + if (rnd() & 1) { + val &= 0x0fff0fff; + if (rnd() & 1) { + val |= 1 << (rnd() & 0x1f); + if (rnd() & 1) { + val |= 1 << (rnd() & 0x1f); + } + } + } + } + bool is_valid_val() override { + return !(val & 0xf000f000) && extrs(val, 0, 12) <= extrs(val, 16, 12); + } + void emulate_mthd() override { + if (!extr(exp.nsource, 1, 1)) { + for (int i = idx; i < 8; i++) { + exp.celsius_clip_rect_horiz[i] = val & 0x0fff0fff; + } + } + } + using SingleMthdTest::SingleMthdTest; +}; + +class MthdCelsiusClipRectVert : public SingleMthdTest { + void adjust_orig_mthd() override { + if (rnd() & 1) { + val &= 0xffff; + val *= 0x00010001; + } + if (rnd() & 1) { + val &= 0x0fff0fff; + if (rnd() & 1) { + val |= 1 << (rnd() & 0x1f); + if (rnd() & 1) { + val |= 1 << (rnd() & 0x1f); + } + } + } + } + bool is_valid_val() override { + return !(val & 0xf000f000) && extrs(val, 0, 12) <= extrs(val, 16, 12); + } + void emulate_mthd() override { + if (!extr(exp.nsource, 1, 1)) { + for (int i = idx; i < 8; i++) { + exp.celsius_clip_rect_vert[i] = val & 0x0fff0fff; + } + } + } + using SingleMthdTest::SingleMthdTest; +}; + class MthdDmaZcull : public SingleMthdTest { bool takes_dma() override { return true; } void emulate_mthd() override { @@ -1098,14 +1379,15 @@ std::vector<SingleMthdTest *> Celsius::mthds() { new MthdCelsiusRcFinal1(opt, rnd(), "rc_final_1", 29, cls, 0x28c), new MthdCelsiusConfig(opt, rnd(), "config", 30, cls, 0x290), new MthdCelsiusLightModel(opt, rnd(), "light_model", 31, cls, 0x294), - 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 MthdCelsiusLightMaterial(opt, rnd(), "light_material", -1, cls, 0x298), + new MthdCelsiusFogMode(opt, rnd(), "fog_mode", -1, cls, 0x29c), + new MthdCelsiusFogCoord(opt, rnd(), "fog_coord", -1, cls, 0x2a0), + new MthdCelsiusFogEnable(opt, rnd(), "fog_enable", -1, cls, 0x2a4), + new MthdCelsiusFogColor(opt, rnd(), "fog_color", -1, cls, 0x2a8), + new MthdCelsiusTexColorKey(opt, rnd(), "tex_color_key", -1, cls, 0x2ac, 2), + new MthdCelsiusClipRectMode(opt, rnd(), "clip_rect_mode", -1, cls, 0x2b4), + new MthdCelsiusClipRectHoriz(opt, rnd(), "clip_rect_horiz", -1, cls, 0x2c0, 8), + new MthdCelsiusClipRectVert(opt, rnd(), "clip_rect_vert", -1, cls, 0x2e0, 8), new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x300, 0x3e), // XXX new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x400, 0x70), // XXX new UntestedMthd(opt, rnd(), "meh", -1, cls, 0x600, 0x20), // XXX diff --git a/hwtest/pgraph_mthd.cc b/hwtest/pgraph_mthd.cc index f4b13d4b..de275393 100644 --- a/hwtest/pgraph_mthd.cc +++ b/hwtest/pgraph_mthd.cc @@ -318,7 +318,11 @@ void MthdTest::adjust_orig() { choose_mthd(); adjust_orig_mthd(); if (!special_notify()) { + if (chipset.card_type >= 4 && can_buf_notify()) + insrt(orig.notify, 0, 1, 0); insrt(orig.notify, 16, 1, 0); + if (can_warn()) + insrt(orig.notify, 24, 1, 0); if (chipset.card_type < 3) insrt(orig.notify, 20, 1, 0); } @@ -429,6 +433,11 @@ bool MthdTest::other_fail() { return err; } +void MthdTest::warn(uint32_t err) { + if (!extr(exp.notify, 28, 3)) + insrt(exp.notify, 28, 3, err); +} + void MthdTest::print_fail() { if (chipset.card_type >= 4) { if (takes_dma() || takes_ctxobj()) { diff --git a/hwtest/pgraph_mthd.h b/hwtest/pgraph_mthd.h index 4017b111..a1c0e7ec 100644 --- a/hwtest/pgraph_mthd.h +++ b/hwtest/pgraph_mthd.h @@ -40,6 +40,8 @@ protected: virtual void emulate_mthd_pre() {}; virtual void emulate_mthd() = 0; virtual bool special_notify() { return false; } + virtual bool can_buf_notify() { return false; } + virtual bool can_warn() { return false; } virtual bool is_valid_val() { return true; } virtual bool is_valid_mthd() { return true; } virtual bool takes_dma() { return false; } @@ -47,6 +49,7 @@ protected: virtual void adjust_orig_mthd() { } virtual int gen_nv3_fmt() { return rnd() & 7; } virtual bool fix_alt_cls() { return true; } + void warn(uint32_t err); void adjust_orig() override; void mutate() override; void print_fail() override; diff --git a/hwtest/pgraph_state.cc b/hwtest/pgraph_state.cc index f57b11e1..dbe90501 100644 --- a/hwtest/pgraph_state.cc +++ b/hwtest/pgraph_state.cc @@ -408,8 +408,9 @@ std::vector<std::unique_ptr<Register>> pgraph_celsius_regs(const chipset_info &c REG(0x400edc, 0xffffffff, "CELSIUS_CLEAR_ZETA", celsius_clear_zeta); REG(0x400ee0, 0xffffffff, "CELSIUS_MTHD_UNK3FC", celsius_mthd_unk3fc); } - for (int i = 0; i < 16; i++) { - IREG(0x400f00 + i * 4, 0x0fff0fff, "CELSIUS_UNKF00", celsius_unkf00, i, 16); + for (int i = 0; i < 8; i++) { + IREG(0x400f00 + i * 4, 0x0fff0fff, "CELSIUS_CLIP_RECT_HORIZ", celsius_clip_rect_horiz, i, 8); + IREG(0x400f20 + i * 4, 0x0fff0fff, "CELSIUS_CLIP_RECT_VERT", celsius_clip_rect_vert, i, 8); } REG(0x400f40, 0x3bffffff, "CELSIUS_UNKF40", celsius_unkf40); REG(0x400f44, 0xffffffff, "CELSIUS_UNKF44", celsius_unkf44); diff --git a/include/nvhw/pgraph.h b/include/nvhw/pgraph.h index 8674d826..fe64e93e 100644 --- a/include/nvhw/pgraph.h +++ b/include/nvhw/pgraph.h @@ -213,7 +213,8 @@ struct pgraph_state { uint32_t celsius_config_d; uint32_t celsius_clear_zeta; uint32_t celsius_mthd_unk3fc; - uint32_t celsius_unkf00[16]; + uint32_t celsius_clip_rect_horiz[8]; + uint32_t celsius_clip_rect_vert[8]; uint32_t celsius_unkf40; uint32_t celsius_unkf44; uint32_t celsius_unkf48; |