mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 21:27:52 -04:00
9c631e11fe
This solves two main problems: - the looming threat of running out of memory since every thread would consume duplicate (and probably not needed) resources - though I will point out, jak 2's offline tests seem to hardly use any memory even with 400+ files, duplicated across many threads. Where as jak 1 does indeed use tons more memory. So I think there is something going on besides just the source files - condense the output so it's much easier to see what is happening / how close the test is to completing. - one annoying thing about the multiple thread change was errors were typically buried far in the middle of the output, this fixes that - refactors the offline test code in general to be a lot more modular The pretty printing is not enabled by default, run with `-p` or `--pretty-print` if you want to use it https://user-images.githubusercontent.com/13153231/205513212-a65c20d4-ce36-44f6-826a-cd475505dbf9.mp4
464 lines
12 KiB
C++
464 lines
12 KiB
C++
#include "gs.h"
|
|
|
|
#include "common/util/Assert.h"
|
|
|
|
#include "third-party/fmt/core.h"
|
|
#include "third-party/fmt/format.h"
|
|
|
|
std::string reg_descriptor_name(GifTag::RegisterDescriptor reg) {
|
|
switch (reg) {
|
|
case GifTag::RegisterDescriptor::PRIM:
|
|
return "PRIM";
|
|
case GifTag::RegisterDescriptor::RGBAQ:
|
|
return "RGBAQ";
|
|
case GifTag::RegisterDescriptor::ST:
|
|
return "ST";
|
|
case GifTag::RegisterDescriptor::UV:
|
|
return "UV";
|
|
case GifTag::RegisterDescriptor::XYZF2:
|
|
return "XYZF2";
|
|
case GifTag::RegisterDescriptor::XYZ2:
|
|
return "XYZ2";
|
|
case GifTag::RegisterDescriptor::TEX0_1:
|
|
return "TEX0_1";
|
|
case GifTag::RegisterDescriptor::TEX0_2:
|
|
return "TEX0_2";
|
|
case GifTag::RegisterDescriptor::CLAMP_1:
|
|
return "CLAMP_1";
|
|
case GifTag::RegisterDescriptor::CLAMP_2:
|
|
return "CLAMP_2";
|
|
case GifTag::RegisterDescriptor::FOG:
|
|
return "FOG";
|
|
case GifTag::RegisterDescriptor::XYZF3:
|
|
return "XYZF3";
|
|
case GifTag::RegisterDescriptor::XYZ3:
|
|
return "XYZ3";
|
|
case GifTag::RegisterDescriptor::AD:
|
|
return "A+D";
|
|
case GifTag::RegisterDescriptor::NOP:
|
|
return "NOP";
|
|
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
}
|
|
|
|
std::string GifTag::print() const {
|
|
std::string result;
|
|
switch (flg()) {
|
|
case Format::PACKED:
|
|
result += "packed ";
|
|
break;
|
|
case Format::REGLIST:
|
|
result += "reglist ";
|
|
break;
|
|
case Format::IMAGE:
|
|
result += "image ";
|
|
return result;
|
|
case Format::DISABLE:
|
|
result += "disable ";
|
|
return result;
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
|
|
result += fmt::format("nloop: {} ", nloop());
|
|
|
|
if (pre()) {
|
|
result += fmt::format("prim: 0x{:x} ", prim());
|
|
}
|
|
|
|
if (eop()) {
|
|
result += "eop ";
|
|
}
|
|
|
|
result += '\n';
|
|
result += ' ';
|
|
|
|
for (u32 i = 0; i < nreg(); i++) {
|
|
result += reg_descriptor_name(reg(i));
|
|
result += ' ';
|
|
}
|
|
result += "\n";
|
|
return result;
|
|
}
|
|
|
|
std::string register_address_name(u32 reg) {
|
|
return register_address_name(GsRegisterAddress(reg));
|
|
}
|
|
|
|
std::string register_address_name(GsRegisterAddress reg) {
|
|
switch (reg) {
|
|
case GsRegisterAddress::PRIM:
|
|
return "PRIM";
|
|
case GsRegisterAddress::RGBAQ:
|
|
return "RGBAQ";
|
|
case GsRegisterAddress::ST:
|
|
return "ST";
|
|
case GsRegisterAddress::UV:
|
|
return "UV";
|
|
case GsRegisterAddress::XYZF2:
|
|
return "XYZF2";
|
|
case GsRegisterAddress::XYZ2:
|
|
return "XYZ2";
|
|
case GsRegisterAddress::TEX0_1:
|
|
return "TEX0_1";
|
|
case GsRegisterAddress::TEX0_2:
|
|
return "TEX0_2";
|
|
case GsRegisterAddress::CLAMP_1:
|
|
return "CLAMP_1";
|
|
case GsRegisterAddress::CLAMP_2:
|
|
return "CLAMP_2";
|
|
case GsRegisterAddress::FOG:
|
|
return "FOG";
|
|
case GsRegisterAddress::XYZF3:
|
|
return "XYZF3";
|
|
case GsRegisterAddress::XYZ3:
|
|
return "XYZ3";
|
|
case GsRegisterAddress::TEX1_1:
|
|
return "TEX1_1";
|
|
case GsRegisterAddress::TEX1_2:
|
|
return "TEX1_2";
|
|
case GsRegisterAddress::TEX2_1:
|
|
return "TEX2_1";
|
|
case GsRegisterAddress::TEX2_2:
|
|
return "TEX2_2";
|
|
case GsRegisterAddress::XYOFFSET_1:
|
|
return "XYOFFSET_1";
|
|
case GsRegisterAddress::XYOFFSET_2:
|
|
return "XYOFFSET_2";
|
|
case GsRegisterAddress::PRMODECONT:
|
|
return "PRMODECONT";
|
|
case GsRegisterAddress::PRMODE:
|
|
return "PRMODE";
|
|
case GsRegisterAddress::TEXCLUT:
|
|
return "TEXCLUT";
|
|
case GsRegisterAddress::SCANMSK:
|
|
return "SCANMSK";
|
|
case GsRegisterAddress::MIPTBP1_1:
|
|
return "MIPTBP1_1";
|
|
case GsRegisterAddress::MIPTBP1_2:
|
|
return "MIPTBP1_2";
|
|
case GsRegisterAddress::MIPTBP2_1:
|
|
return "MIPTBP2_1";
|
|
case GsRegisterAddress::MIPTBP2_2:
|
|
return "MIPTBP2_2";
|
|
case GsRegisterAddress::TEXA:
|
|
return "TEXA";
|
|
case GsRegisterAddress::FOGCOL:
|
|
return "FOGCOL";
|
|
case GsRegisterAddress::TEXFLUSH:
|
|
return "TEXFLUSH";
|
|
case GsRegisterAddress::SCISSOR_1:
|
|
return "SCISSOR_1";
|
|
case GsRegisterAddress::SCISSOR_2:
|
|
return "SCISSOR_2";
|
|
case GsRegisterAddress::ALPHA_1:
|
|
return "ALPHA_1";
|
|
case GsRegisterAddress::ALPHA_2:
|
|
return "ALPHA_2";
|
|
case GsRegisterAddress::DIMX:
|
|
return "DIMX";
|
|
case GsRegisterAddress::DTHE:
|
|
return "DTHE";
|
|
case GsRegisterAddress::COLCLAMP:
|
|
return "COLCLAMP";
|
|
case GsRegisterAddress::TEST_1:
|
|
return "TEST_1";
|
|
case GsRegisterAddress::TEST_2:
|
|
return "TEST_2";
|
|
case GsRegisterAddress::PABE:
|
|
return "PABE";
|
|
case GsRegisterAddress::FBA_1:
|
|
return "FBA_1";
|
|
case GsRegisterAddress::FBA_2:
|
|
return "FBA_2";
|
|
case GsRegisterAddress::FRAME_1:
|
|
return "FRAME_1";
|
|
case GsRegisterAddress::FRAME_2:
|
|
return "FRAME_2";
|
|
case GsRegisterAddress::ZBUF_1:
|
|
return "ZBUF_1";
|
|
case GsRegisterAddress::ZBUF_2:
|
|
return "ZBUF_2";
|
|
case GsRegisterAddress::BITBLTBUF:
|
|
return "BITBLTBUF";
|
|
case GsRegisterAddress::TRXPOS:
|
|
return "TRXPOS";
|
|
case GsRegisterAddress::TRXREG:
|
|
return "TRXREG";
|
|
case GsRegisterAddress::TRXDIR:
|
|
return "TRXDIR";
|
|
case GsRegisterAddress::HWREG:
|
|
return "HWREG";
|
|
case GsRegisterAddress::SIGNAL:
|
|
return "SIGNAL";
|
|
case GsRegisterAddress::FINISH:
|
|
return "FINISH";
|
|
case GsRegisterAddress::LABEL:
|
|
return "LABEL";
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
}
|
|
|
|
std::string GsTest::print() const {
|
|
std::string result;
|
|
if (alpha_test_enable()) {
|
|
result += "alpha-test: ";
|
|
switch (alpha_test()) {
|
|
case AlphaTest::NEVER:
|
|
result += "NEVER ";
|
|
break;
|
|
case AlphaTest::ALWAYS:
|
|
result += "ALWAYS ";
|
|
break;
|
|
case AlphaTest::LESS:
|
|
result += "LESS ";
|
|
break;
|
|
case AlphaTest::LEQUAL:
|
|
result += "LEQUAL ";
|
|
break;
|
|
case AlphaTest::EQUAL:
|
|
result += "EQUAL ";
|
|
break;
|
|
case AlphaTest::GEQUAL:
|
|
result += "GEQUAL ";
|
|
break;
|
|
case AlphaTest::GREATER:
|
|
result += "GREATER ";
|
|
break;
|
|
case AlphaTest::NOTEQUAL:
|
|
result += "NOTEQUAL ";
|
|
break;
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
result += fmt::format("ref: 0x{:x} alpha-fail: ", aref());
|
|
switch (afail()) {
|
|
case AlphaFail::KEEP:
|
|
result += "KEEP ";
|
|
break;
|
|
case AlphaFail::FB_ONLY:
|
|
result += "FB_ONLY ";
|
|
break;
|
|
case AlphaFail::ZB_ONLY:
|
|
result += "ZB_ONLY ";
|
|
break;
|
|
case AlphaFail::RGB_ONLY:
|
|
result += "RGB_ONLY ";
|
|
break;
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
}
|
|
|
|
if (date()) {
|
|
result += fmt::format("dest-alpha-mode {} ", (int)datm());
|
|
}
|
|
|
|
if (zte()) {
|
|
result += fmt::format("ztest: ");
|
|
switch (ztest()) {
|
|
case ZTest::NEVER:
|
|
result += "NEVER";
|
|
break;
|
|
case ZTest::ALWAYS:
|
|
result += "ALWAYS";
|
|
break;
|
|
case ZTest::GEQUAL:
|
|
result += "GEQUAL";
|
|
break;
|
|
case ZTest::GREATER:
|
|
result += "GREATER";
|
|
break;
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
std::string GsAlpha::print() const {
|
|
std::string result = "(";
|
|
switch (a_mode()) {
|
|
case BlendMode::SOURCE:
|
|
result += "Cs ";
|
|
break;
|
|
case BlendMode::DEST:
|
|
result += "Cd ";
|
|
break;
|
|
case BlendMode::ZERO_OR_FIXED:
|
|
result += "0 ";
|
|
break;
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
|
|
switch (b_mode()) {
|
|
case BlendMode::SOURCE:
|
|
result += "- Cs) * ";
|
|
break;
|
|
case BlendMode::DEST:
|
|
result += "- Cd) * ";
|
|
break;
|
|
case BlendMode::ZERO_OR_FIXED:
|
|
result += "- 0) * ";
|
|
break;
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
|
|
switch (c_mode()) {
|
|
case BlendMode::SOURCE:
|
|
result += "As / 128.0";
|
|
break;
|
|
case BlendMode::DEST:
|
|
result += "Ad / 128.0";
|
|
break;
|
|
case BlendMode::ZERO_OR_FIXED: {
|
|
float div = fix();
|
|
div /= 128.0;
|
|
result += fmt::format("{:.4f}", div);
|
|
} break;
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
|
|
switch (d_mode()) {
|
|
case BlendMode::SOURCE:
|
|
result += " + Cs";
|
|
break;
|
|
case BlendMode::DEST:
|
|
result += " + Cd";
|
|
break;
|
|
case BlendMode::ZERO_OR_FIXED:
|
|
break;
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
std::string GsTex1::print() const {
|
|
return fmt::format("lcm: {} mxl: {} mmag: {} mmin: {} mtba: {} l: {} k: {}\n", lcm(), mxl(),
|
|
mmag(), mmin(), mtba(), l(), k());
|
|
}
|
|
|
|
std::string GsTexa::print() const {
|
|
return fmt::format("ta0: {} aem: {} ta1: {}\n", ta0(), aem(), ta1());
|
|
}
|
|
|
|
std::string GsTex0::print() const {
|
|
return fmt::format(
|
|
"tbp0: {} tbw: {} psm: {} tw: {} th: {} tcc: {} tfx: {} cbp: {} cpsm: {} csm: {}\n", tbp0(),
|
|
tbw(), fmt::underlying(psm()), tw(), th(), tcc(), fmt::underlying(tfx()), cbp(), cpsm(),
|
|
csm());
|
|
}
|
|
|
|
std::string GsPrim::print() const {
|
|
return fmt::format("0x{:x}, kind {}\n", data, fmt::underlying(kind()));
|
|
}
|
|
|
|
std::string GsFrame::print() const {
|
|
return fmt::format("fbp: {} fbw: {} psm: {} fbmsk: {:x}\n", fbp(), fbw(), fmt::underlying(psm()),
|
|
fbmsk());
|
|
}
|
|
|
|
std::string GsXYOffset::print() const {
|
|
return fmt::format("ofx: {} ofy: {}\n", ofx(), ofy());
|
|
}
|
|
|
|
std::string DrawMode::to_string() const {
|
|
std::string result;
|
|
result += fmt::format(" depth-write: {}\n", get_depth_write_enable());
|
|
result += fmt::format(" depth-test: ");
|
|
switch (get_depth_test()) {
|
|
case GsTest::ZTest::NEVER:
|
|
result += "never\n";
|
|
break;
|
|
case GsTest::ZTest::GEQUAL:
|
|
result += "gequal\n";
|
|
break;
|
|
case GsTest::ZTest::ALWAYS:
|
|
result += "always\n";
|
|
break;
|
|
case GsTest::ZTest::GREATER:
|
|
result += "greater\n";
|
|
break;
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
result += fmt::format(" alpha: ");
|
|
switch (get_alpha_blend()) {
|
|
case AlphaBlend::SRC_0_SRC_DST:
|
|
result += "src, 0, src, dst\n";
|
|
break;
|
|
case AlphaBlend::SRC_DST_SRC_DST:
|
|
result += "src, dst, src, dst\n";
|
|
break;
|
|
case AlphaBlend::DISABLED:
|
|
result += "disabled\n";
|
|
break;
|
|
case AlphaBlend::SRC_DST_FIX_DST:
|
|
result += "src, dst, fix, dst\n";
|
|
break;
|
|
case AlphaBlend::SRC_0_DST_DST:
|
|
result += "src, 0, dst, dst\n";
|
|
break;
|
|
case AlphaBlend::SRC_SRC_SRC_SRC:
|
|
result += "src, src, src, src\n";
|
|
break;
|
|
case AlphaBlend::ZERO_SRC_SRC_DST:
|
|
result += "0, src, src, dst\n";
|
|
break;
|
|
case AlphaBlend::SRC_0_FIX_DST:
|
|
result += "src, 0, fix, dst\n";
|
|
break;
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
result += fmt::format(" clamp: s {} t {}\n", get_clamp_s_enable(), get_clamp_t_enable());
|
|
result += fmt::format(" filt: {}\n", get_filt_enable());
|
|
result += fmt::format(" tcc: {}\n", get_tcc_enable());
|
|
result += fmt::format(" aref: {}\n", get_aref());
|
|
result += fmt::format(" ate: {}\n", get_at_enable());
|
|
result += fmt::format(" atst: ");
|
|
switch (get_alpha_test()) {
|
|
case AlphaTest::ALWAYS:
|
|
result += "always\n";
|
|
break;
|
|
case AlphaTest::GEQUAL:
|
|
result += "gequal\n";
|
|
break;
|
|
case AlphaTest::NEVER:
|
|
result += "never\n";
|
|
break;
|
|
default:
|
|
result += "invalid!\n";
|
|
break;
|
|
}
|
|
result += fmt::format(" zte: {}\n", get_zt_enable());
|
|
result += fmt::format(" abe: {}\n", get_ab_enable());
|
|
result += fmt::format(" afail: ");
|
|
switch (get_alpha_fail()) {
|
|
case GsTest::AlphaFail::KEEP:
|
|
result += "keep\n";
|
|
break;
|
|
case GsTest::AlphaFail::FB_ONLY:
|
|
result += "fb-only\n";
|
|
break;
|
|
case GsTest::AlphaFail::RGB_ONLY:
|
|
result += "rgb-only\n";
|
|
break;
|
|
case GsTest::AlphaFail::ZB_ONLY:
|
|
result += "zb-only\n";
|
|
break;
|
|
default:
|
|
ASSERT(false);
|
|
}
|
|
result += fmt::format(" fog: {}\n decal: {}\n", get_fog_enable(), get_decal());
|
|
return result;
|
|
}
|