summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Koƛcielnicki <koriakin@0x04.net>2016-12-26 23:25:46 +0000
committerMarcin Koƛcielnicki <koriakin@0x04.net>2016-12-26 23:25:46 +0000
commit90bfc3f6ec512fb9ae4c3ee5a89b3044348d9d30 (patch)
tree382c8396735391448b26bdf859e664e560c054a2
parent254066fd86aba05f55916c14af6f8ff4404ab6ca (diff)
hwtest/pgraph: Nailed down Celsius methods 0x200:0x300.
-rw-r--r--hwtest/pgraph_class_celsius.cc298
-rw-r--r--hwtest/pgraph_mthd.cc9
-rw-r--r--hwtest/pgraph_mthd.h3
-rw-r--r--hwtest/pgraph_state.cc5
-rw-r--r--include/nvhw/pgraph.h3
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;