summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Kościelnicki <koriakin@0x04.net>2016-12-28 19:46:19 +0000
committerMarcin Kościelnicki <koriakin@0x04.net>2016-12-28 19:46:19 +0000
commit3f53d5e6c164b9e13fcfeacda69bc4e9e671e03e (patch)
tree731ad326303da7e2c6eb5665db9c393903a00fac
parent617ffb77636c9c5dcccf09f6fd5b03b2af9ba66c (diff)
hwtest/pgraph: Test EmuD3D56 and EmuEmuD3D0 tlv_[xyzw], tlv_color, tlv_fog_* methods.
-rw-r--r--hwtest/pgraph_class_celsius.cc65
-rw-r--r--hwtest/pgraph_class_emu_d3d56.cc190
-rw-r--r--include/nvhw/pgraph.h8
-rw-r--r--nvhw/CMakeLists.txt4
-rw-r--r--nvhw/pgraph_celsius.c90
5 files changed, 273 insertions, 84 deletions
diff --git a/hwtest/pgraph_class_celsius.cc b/hwtest/pgraph_class_celsius.cc
index bb471a6f..8fad85b6 100644
--- a/hwtest/pgraph_class_celsius.cc
+++ b/hwtest/pgraph_class_celsius.cc
@@ -3039,25 +3039,6 @@ public:
: SingleMthdTest(opt, seed, name, trapbit, cls, mthd, num, stride), which(which) {}
};
-static uint32_t pgraph_celsius_convert_light_v(uint32_t val) {
- if ((val & 0x3ffff) < 0x3fe00)
- val += 0x200;
- return val & 0xfffffc00;
-}
-
-static uint32_t pgraph_celsius_convert_light_sx(uint32_t val) {
- if (!extr(val, 23, 8))
- return 0;
- if (extr(val, 23, 8) == 0xff) {
- if (extr(val, 9, 14))
- return 0x7ffffc00;
- return 0x7f800000;
- }
- if ((val & 0x3ffff) < 0x3fe00)
- val += 0x200;
- return val & 0xfffffc00;
-}
-
class MthdCelsiusLightV : public SingleMthdTest {
int which;
void adjust_orig_mthd() override {
@@ -3314,19 +3295,6 @@ public:
: SingleMthdTest(opt, seed, name, trapbit, cls, mthd, num, stride), which(which) {}
};
-static uint32_t pgraph_celsius_ub_to_float(uint8_t val) {
- if (!val)
- return 0;
- if (val == 0xff)
- return 0x3f800000;
- uint32_t res = val * 0x010101;
- uint32_t exp = 0x7e;
- while (!extr(res, 23, 1))
- res <<= 1, exp--;
- insrt(res, 23, 8, exp);
- return res;
-}
-
class MthdCelsiusVtxAttrUByte : public SingleMthdTest {
int which;
void emulate_mthd() override {
@@ -3342,21 +3310,6 @@ public:
: SingleMthdTest(opt, seed, name, trapbit, cls, mthd), which(which) {}
};
-static uint32_t pgraph_celsius_short_to_float(struct pgraph_state *state, int16_t val) {
- if (!val)
- return 0;
- if (state->chipset.chipset == 0x10 && val == -0x8000)
- return 0x80000000;
- bool sign = val < 0;
- uint32_t res = (sign ? -val : val) << 8;
- uint32_t exp = 0x7f + 15;
- while (!extr(res, 23, 1))
- res <<= 1, exp--;
- insrt(res, 23, 8, exp);
- insrt(res, 31, 1, sign);
- return res;
-}
-
class MthdCelsiusVtxAttrShort : public SingleMthdTest {
int which;
void adjust_orig_mthd() override {
@@ -3382,24 +3335,6 @@ public:
: SingleMthdTest(opt, seed, name, trapbit, cls, mthd, num, stride), which(which) {}
};
-static uint32_t pgraph_celsius_nshort_to_float(int16_t val) {
- bool sign = val < 0;
- if (val == -0x8000)
- return 0xbf800000;
- if (val == 0x7fff)
- return 0x3f800000;
- int32_t rv = val << 1 | 1;
- uint32_t res = (sign ? -rv : rv) * 0x10001;
- uint32_t exp = 0x7f - 9;
- while (extr(res, 24, 8))
- res >>= 1, exp++;
- while (!extr(res, 23, 1))
- res <<= 1, exp--;
- insrt(res, 23, 8, exp);
- insrt(res, 31, 1, sign);
- return res;
-}
-
class MthdCelsiusVtxAttrNShort : public SingleMthdTest {
int which;
void adjust_orig_mthd() override {
diff --git a/hwtest/pgraph_class_emu_d3d56.cc b/hwtest/pgraph_class_emu_d3d56.cc
index b521eaff..845d8c10 100644
--- a/hwtest/pgraph_class_emu_d3d56.cc
+++ b/hwtest/pgraph_class_emu_d3d56.cc
@@ -863,6 +863,160 @@ class MthdEmuEmuD3D0Alpha : public SingleMthdTest {
using SingleMthdTest::SingleMthdTest;
};
+class MthdEmuEmuD3D0TlvFogTri : public SingleMthdTest {
+ void emulate_mthd() override {
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_pipe_vtx[8] = pgraph_celsius_ub_to_float(extr(val, 16, 8));
+ exp.celsius_pipe_vtx[9] = pgraph_celsius_ub_to_float(extr(val, 8, 8));
+ exp.celsius_pipe_vtx[10] = pgraph_celsius_ub_to_float(extr(val, 0, 8));
+ exp.celsius_pipe_vtx[11] = pgraph_celsius_ub_to_float(extr(val, 24, 8));
+ }
+ exp.misc24[2] = val & 0xffffff;
+ insrt(exp.valid[1], 0, 7, 1);
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
+class MthdEmuD3D56TlvColor : public SingleMthdTest {
+ void emulate_mthd() override {
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_pipe_vtx[4] = pgraph_celsius_ub_to_float(extr(val, 16, 8));
+ exp.celsius_pipe_vtx[5] = pgraph_celsius_ub_to_float(extr(val, 8, 8));
+ exp.celsius_pipe_vtx[6] = pgraph_celsius_ub_to_float(extr(val, 0, 8));
+ exp.celsius_pipe_vtx[7] = pgraph_celsius_ub_to_float(extr(val, 24, 8));
+ }
+ insrt(exp.valid[1], 1, 1, 1);
+ int vidx = (cls == 0x48 ? extr(exp.misc24[2], 0, 4) : idx);
+ insrt(exp.valid[0], vidx, 1, 0);
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
+class MthdEmuD3D56TlvFogCol1 : public SingleMthdTest {
+ void emulate_mthd() override {
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_pipe_vtx[8] = pgraph_celsius_ub_to_float(extr(val, 16, 8));
+ exp.celsius_pipe_vtx[9] = pgraph_celsius_ub_to_float(extr(val, 8, 8));
+ exp.celsius_pipe_vtx[10] = pgraph_celsius_ub_to_float(extr(val, 0, 8));
+ exp.celsius_pipe_vtx[11] = pgraph_celsius_ub_to_float(extr(val, 24, 8));
+ }
+ insrt(exp.valid[1], 0, 1, 1);
+ insrt(exp.valid[0], idx, 1, 0);
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
+class MthdEmuD3D56TlvX : public SingleMthdTest {
+ void adjust_orig_mthd() override {
+ if (rnd() & 1) {
+ insrt(val, 0, 23, 0);
+ val ^= 1 << (rnd() & 0x1f);
+ }
+ }
+ bool is_valid_val() override {
+ if (cls == 0x48) {
+ int e = extr(val, 23, 8);
+ if (e > 0x7f + 10)
+ return false;
+ }
+ return true;
+ }
+ void emulate_mthd() override {
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_pipe_vtx[0] = val;
+ if (chipset.chipset != 0x10)
+ exp.celsius_pipe_vtx[1] = 0;
+ exp.celsius_pipe_vtx[2] = 0;
+ exp.celsius_pipe_vtx[3] = 0x3f800000;
+ }
+ insrt(exp.valid[1], 5, 1, 1);
+ int vidx = (cls == 0x48 ? extr(exp.misc24[2], 0, 4) : idx);
+ insrt(exp.valid[0], vidx, 1, 0);
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
+class MthdEmuD3D56TlvY : public SingleMthdTest {
+ void adjust_orig_mthd() override {
+ if (rnd() & 1) {
+ insrt(val, 0, 23, 0);
+ val ^= 1 << (rnd() & 0x1f);
+ }
+ }
+ bool is_valid_val() override {
+ if (cls == 0x48) {
+ int e = extr(val, 23, 8);
+ if (e > 0x7f + 10)
+ return false;
+ }
+ return true;
+ }
+ void emulate_mthd() override {
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_pipe_vtx[1] = val;
+ exp.celsius_pipe_vtx[2] = 0;
+ exp.celsius_pipe_vtx[3] = 0x3f800000;
+ }
+ insrt(exp.valid[1], 4, 1, 1);
+ int vidx = (cls == 0x48 ? extr(exp.misc24[2], 0, 4) : idx);
+ insrt(exp.valid[0], vidx, 1, 0);
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
+class MthdEmuD3D56TlvZ : public SingleMthdTest {
+ void adjust_orig_mthd() override {
+ if (rnd() & 1) {
+ insrt(val, 0, 23, 0);
+ val ^= 1 << (rnd() & 0x1f);
+ }
+ }
+ bool is_valid_val() override {
+ if (cls == 0x48) {
+ if (extr(val, 31, 1))
+ return false;
+ int e = extr(val, 23, 8);
+ if (e >= 0x7f)
+ return false;
+ }
+ return true;
+ }
+ void emulate_mthd() override {
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_pipe_vtx[2] = val;
+ }
+ insrt(exp.valid[1], 3, 1, 1);
+ int vidx = (cls == 0x48 ? extr(exp.misc24[2], 0, 4) : idx);
+ insrt(exp.valid[0], vidx, 1, 0);
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
+class MthdEmuD3D56TlvW : public SingleMthdTest {
+ void adjust_orig_mthd() override {
+ if (rnd() & 1) {
+ insrt(val, 0, 23, 0);
+ val ^= 1 << (rnd() & 0x1f);
+ }
+ }
+ bool is_valid_val() override {
+ if (cls == 0x48) {
+ if (extr(val, 31, 1))
+ return false;
+ }
+ return true;
+ }
+ void emulate_mthd() override {
+ if (!extr(exp.nsource, 1, 1)) {
+ exp.celsius_pipe_vtx[3] = val;
+ }
+ insrt(exp.valid[1], 2, 1, 1);
+ int vidx = (cls == 0x48 ? extr(exp.misc24[2], 0, 4) : idx);
+ insrt(exp.valid[0], vidx, 1, 0);
+ }
+ using SingleMthdTest::SingleMthdTest;
+};
+
std::vector<SingleMthdTest *> EmuEmuD3D0::mthds() {
return {
new MthdNop(opt, rnd(), "nop", -1, cls, 0x100),
@@ -880,12 +1034,12 @@ std::vector<SingleMthdTest *> EmuEmuD3D0::mthds() {
new MthdEmuD3D56FogColor(opt, rnd(), "fog_color", 9, cls, 0x310),
new MthdEmuEmuD3D0Config(opt, rnd(), "config", 10, cls, 0x314),
new MthdEmuEmuD3D0Alpha(opt, rnd(), "alpha", 11, cls, 0x318),
- new UntestedMthd(opt, rnd(), "tlv_fog_tri", -1, cls, 0x1000, 0x80, 0x20),
- new UntestedMthd(opt, rnd(), "tlv_color", -1, cls, 0x1004, 0x80, 0x20),
- new UntestedMthd(opt, rnd(), "tlv_x", -1, cls, 0x1008, 0x80, 0x20),
- new UntestedMthd(opt, rnd(), "tlv_y", -1, cls, 0x100c, 0x80, 0x20),
- new UntestedMthd(opt, rnd(), "tlv_z", -1, cls, 0x1010, 0x80, 0x20),
- new UntestedMthd(opt, rnd(), "tlv_rhw", -1, cls, 0x1014, 0x80, 0x20),
+ new MthdEmuEmuD3D0TlvFogTri(opt, rnd(), "tlv_fog_tri", 12, cls, 0x1000, 0x80, 0x20),
+ new MthdEmuD3D56TlvColor(opt, rnd(), "tlv_color", 13, cls, 0x1004, 0x80, 0x20),
+ new MthdEmuD3D56TlvX(opt, rnd(), "tlv_x", 14, cls, 0x1008, 0x80, 0x20),
+ new MthdEmuD3D56TlvY(opt, rnd(), "tlv_y", 15, cls, 0x100c, 0x80, 0x20),
+ new MthdEmuD3D56TlvZ(opt, rnd(), "tlv_z", 16, cls, 0x1010, 0x80, 0x20),
+ new MthdEmuD3D56TlvW(opt, rnd(), "tlv_rhw", 17, cls, 0x1014, 0x80, 0x20),
new UntestedMthd(opt, rnd(), "tlv_u", -1, cls, 0x1018, 0x80, 0x20),
new UntestedMthd(opt, rnd(), "tlv_v", -1, cls, 0x101c, 0x80, 0x20),
};
@@ -907,12 +1061,12 @@ std::vector<SingleMthdTest *> EmuD3D5::mthds() {
new MthdEmuD3D56Blend(opt, rnd(), "blend", 9, cls, 0x310),
new MthdEmuD3D56Config(opt, rnd(), "config", 10, cls, 0x314),
new MthdEmuD3D56FogColor(opt, rnd(), "fog_color", 11, cls, 0x318),
- new UntestedMthd(opt, rnd(), "tlv_x", -1, cls, 0x400, 0x10, 0x20),
- new UntestedMthd(opt, rnd(), "tlv_y", -1, cls, 0x404, 0x10, 0x20),
- new UntestedMthd(opt, rnd(), "tlv_z", -1, cls, 0x408, 0x10, 0x20),
- new UntestedMthd(opt, rnd(), "tlv_rhw", -1, cls, 0x40c, 0x10, 0x20),
- new UntestedMthd(opt, rnd(), "tlv_color", -1, cls, 0x410, 0x10, 0x20),
- new UntestedMthd(opt, rnd(), "tlv_fog_col1", -1, cls, 0x414, 0x10, 0x20),
+ new MthdEmuD3D56TlvX(opt, rnd(), "tlv_x", 12, cls, 0x400, 0x10, 0x20),
+ new MthdEmuD3D56TlvY(opt, rnd(), "tlv_y", 13, cls, 0x404, 0x10, 0x20),
+ new MthdEmuD3D56TlvZ(opt, rnd(), "tlv_z", 14, cls, 0x408, 0x10, 0x20),
+ new MthdEmuD3D56TlvW(opt, rnd(), "tlv_rhw", 15, cls, 0x40c, 0x10, 0x20),
+ new MthdEmuD3D56TlvColor(opt, rnd(), "tlv_color", 16, cls, 0x410, 0x10, 0x20),
+ new MthdEmuD3D56TlvFogCol1(opt, rnd(), "tlv_fog_col1", 17, cls, 0x414, 0x10, 0x20),
new UntestedMthd(opt, rnd(), "unk", -1, cls, 0x418, 0x10, 0x20),
new UntestedMthd(opt, rnd(), "unk", -1, cls, 0x41c, 0x10, 0x20),
new UntestedMthd(opt, rnd(), "draw", -1, cls, 0x600, 0x40),
@@ -944,12 +1098,12 @@ std::vector<SingleMthdTest *> EmuD3D6::mthds() {
new MthdEmuD3D6StencilFunc(opt, rnd(), "stencil_func", 18, cls, 0x340),
new MthdEmuD3D6StencilOp(opt, rnd(), "stencil_op", 19, cls, 0x344),
new MthdEmuD3D56FogColor(opt, rnd(), "fog_color", 20, cls, 0x348),
- new UntestedMthd(opt, rnd(), "tlv_x", -1, cls, 0x400, 8, 0x28),
- new UntestedMthd(opt, rnd(), "tlv_y", -1, cls, 0x404, 8, 0x28),
- new UntestedMthd(opt, rnd(), "tlv_z", -1, cls, 0x408, 8, 0x28),
- new UntestedMthd(opt, rnd(), "tlv_rhw", -1, cls, 0x40c, 8, 0x28),
- new UntestedMthd(opt, rnd(), "tlv_color", -1, cls, 0x410, 8, 0x28),
- new UntestedMthd(opt, rnd(), "tlv_fog_col1", -1, cls, 0x414, 8, 0x28),
+ new MthdEmuD3D56TlvX(opt, rnd(), "tlv_x", 21, cls, 0x400, 8, 0x28),
+ new MthdEmuD3D56TlvY(opt, rnd(), "tlv_y", 22, cls, 0x404, 8, 0x28),
+ new MthdEmuD3D56TlvZ(opt, rnd(), "tlv_z", 23, cls, 0x408, 8, 0x28),
+ new MthdEmuD3D56TlvW(opt, rnd(), "tlv_rhw", 24, cls, 0x40c, 8, 0x28),
+ new MthdEmuD3D56TlvColor(opt, rnd(), "tlv_color", 25, cls, 0x410, 8, 0x28),
+ new MthdEmuD3D56TlvFogCol1(opt, rnd(), "tlv_fog_col1", 26, cls, 0x414, 8, 0x28),
new UntestedMthd(opt, rnd(), "unk", -1, cls, 0x418, 8, 0x28),
new UntestedMthd(opt, rnd(), "unk", -1, cls, 0x41c, 8, 0x28),
new UntestedMthd(opt, rnd(), "unk", -1, cls, 0x420, 8, 0x28),
diff --git a/include/nvhw/pgraph.h b/include/nvhw/pgraph.h
index c970d59f..932fef8f 100644
--- a/include/nvhw/pgraph.h
+++ b/include/nvhw/pgraph.h
@@ -320,6 +320,14 @@ 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);
+/* pgraph_celsius.c */
+uint32_t pgraph_celsius_convert_light_v(uint32_t val);
+uint32_t pgraph_celsius_convert_light_sx(uint32_t val);
+uint32_t pgraph_celsius_ub_to_float(uint8_t val);
+uint32_t pgraph_celsius_short_to_float(struct pgraph_state *state, int16_t val);
+uint32_t pgraph_celsius_nshort_to_float(int16_t val);
+
+
static inline uint32_t pgraph_class(struct pgraph_state *state) {
if (state->chipset.card_type < 3) {
return extr(state->access, 12, 5);
diff --git a/nvhw/CMakeLists.txt b/nvhw/CMakeLists.txt
index 39ff29a5..6e547734 100644
--- a/nvhw/CMakeLists.txt
+++ b/nvhw/CMakeLists.txt
@@ -2,7 +2,9 @@ project(ENVYTOOLS C)
cmake_minimum_required(VERSION 2.6)
add_library(nvhw chipset.c tile.c comp.c mpeg_crypt.c
- pgraph.c pgraph_xy.c pgraph_xy3.c pgraph_xy4.c pgraph_d3d_nv3.c fp.c sfu.c sfu_tab.c)
+ pgraph.c pgraph_xy.c pgraph_xy3.c pgraph_xy4.c pgraph_d3d_nv3.c
+ pgraph_celsius.c
+ fp.c sfu.c sfu_tab.c)
install(TARGETS nvhw
RUNTIME DESTINATION bin
diff --git a/nvhw/pgraph_celsius.c b/nvhw/pgraph_celsius.c
new file mode 100644
index 00000000..2b35640a
--- /dev/null
+++ b/nvhw/pgraph_celsius.c
@@ -0,0 +1,90 @@
+/*
+ * 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 "nvhw/pgraph.h"
+
+uint32_t pgraph_celsius_convert_light_v(uint32_t val) {
+ if ((val & 0x3ffff) < 0x3fe00)
+ val += 0x200;
+ return val & 0xfffffc00;
+}
+
+uint32_t pgraph_celsius_convert_light_sx(uint32_t val) {
+ if (!extr(val, 23, 8))
+ return 0;
+ if (extr(val, 23, 8) == 0xff) {
+ if (extr(val, 9, 14))
+ return 0x7ffffc00;
+ return 0x7f800000;
+ }
+ if ((val & 0x3ffff) < 0x3fe00)
+ val += 0x200;
+ return val & 0xfffffc00;
+}
+
+uint32_t pgraph_celsius_ub_to_float(uint8_t val) {
+ if (!val)
+ return 0;
+ if (val == 0xff)
+ return 0x3f800000;
+ uint32_t res = val * 0x010101;
+ uint32_t exp = 0x7e;
+ while (!extr(res, 23, 1))
+ res <<= 1, exp--;
+ insrt(res, 23, 8, exp);
+ return res;
+}
+
+uint32_t pgraph_celsius_short_to_float(struct pgraph_state *state, int16_t val) {
+ if (!val)
+ return 0;
+ if (state->chipset.chipset == 0x10 && val == -0x8000)
+ return 0x80000000;
+ bool sign = val < 0;
+ uint32_t res = (sign ? -val : val) << 8;
+ uint32_t exp = 0x7f + 15;
+ while (!extr(res, 23, 1))
+ res <<= 1, exp--;
+ insrt(res, 23, 8, exp);
+ insrt(res, 31, 1, sign);
+ return res;
+}
+
+uint32_t pgraph_celsius_nshort_to_float(int16_t val) {
+ bool sign = val < 0;
+ if (val == -0x8000)
+ return 0xbf800000;
+ if (val == 0x7fff)
+ return 0x3f800000;
+ int32_t rv = val << 1 | 1;
+ uint32_t res = (sign ? -rv : rv) * 0x10001;
+ uint32_t exp = 0x7f - 9;
+ while (extr(res, 24, 8))
+ res >>= 1, exp++;
+ while (!extr(res, 23, 1))
+ res <<= 1, exp--;
+ insrt(res, 23, 8, exp);
+ insrt(res, 31, 1, sign);
+ return res;
+}