diff options
author | Marcin Kościelnicki <koriakin@0x04.net> | 2016-12-28 19:46:19 +0000 |
---|---|---|
committer | Marcin Kościelnicki <koriakin@0x04.net> | 2016-12-28 19:46:19 +0000 |
commit | 3f53d5e6c164b9e13fcfeacda69bc4e9e671e03e (patch) | |
tree | 731ad326303da7e2c6eb5665db9c393903a00fac | |
parent | 617ffb77636c9c5dcccf09f6fd5b03b2af9ba66c (diff) |
hwtest/pgraph: Test EmuD3D56 and EmuEmuD3D0 tlv_[xyzw], tlv_color, tlv_fog_* methods.
-rw-r--r-- | hwtest/pgraph_class_celsius.cc | 65 | ||||
-rw-r--r-- | hwtest/pgraph_class_emu_d3d56.cc | 190 | ||||
-rw-r--r-- | include/nvhw/pgraph.h | 8 | ||||
-rw-r--r-- | nvhw/CMakeLists.txt | 4 | ||||
-rw-r--r-- | nvhw/pgraph_celsius.c | 90 |
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; +} |