From 9f59b3f1a80eca0d4c1756016582fe43b681e729 Mon Sep 17 00:00:00 2001 From: TJnotJT Date: Mon, 20 Jan 2025 09:40:36 -0500 Subject: [PATCH] temp-commit --- pcsx2-gsrunner/Main.cpp | 122 +++++++++++++++++- pcsx2/Config.h | 2 + pcsx2/GS/GSState.cpp | 16 ++- .../GS/Renderers/Common/GSVertexTraceFMM.cpp | 43 +++++- pcsx2/GS/Renderers/SW/GSDrawScanline.cpp | 4 + pcsx2/GS/Renderers/SW/GSRasterizer.cpp | 50 ++++++- pcsx2/GS/Renderers/SW/GSRendererSW.cpp | 52 ++++++-- pcsx2/Pcsx2Config.cpp | 2 + pcsx2/debug.h | 3 + 9 files changed, 268 insertions(+), 26 deletions(-) create mode 100644 pcsx2/debug.h diff --git a/pcsx2-gsrunner/Main.cpp b/pcsx2-gsrunner/Main.cpp index d3ad1e818251b..d698f3130d49e 100644 --- a/pcsx2-gsrunner/Main.cpp +++ b/pcsx2-gsrunner/Main.cpp @@ -46,6 +46,35 @@ #include "svnrev.h" +#include "debug.h" + +#if MY_DEBUG || MY_DUMP +#define DEBUG_FILE_STR "hack" +#define DEBUG_DUMP_DIR "C:\\Users\\tchan\\Desktop\\ps2_debug\\" DEBUG_FILE_STR "-dump-all" +#define DEBUG_RANGE_FILE_CALC "C:\\Users\\tchan\\Desktop\\log_files\\pointsRange_" DEBUG_FILE_STR "_calc.txt" +#define DEBUG_RANGE_FILE_SW "C:\\Users\\tchan\\Desktop\\log_files\\pointsRange_" DEBUG_FILE_STR "_sw.txt" +#define DEBUG_LIST_FILE_CALC "C:\\Users\\tchan\\Desktop\\log_files\\pointsList_" DEBUG_FILE_STR "_calc_%d.txt" +#define DEBUG_LIST_FILE_SW "C:\\Users\\tchan\\Desktop\\log_files\\pointsList_" DEBUG_FILE_STR "_sw_%d.txt" +#define DEBUG_ORIG_FILE_CALC "C:\\Users\\tchan\\Desktop\\log_files\\pointsOrig_" DEBUG_FILE_STR "_calc_%d.txt" +#define DEBUG_ORIG_FILE_SW "C:\\Users\\tchan\\Desktop\\log_files\\pointsOrig_" DEBUG_FILE_STR "_sw_%d.txt" + +bool savePoints = false; +bool dumpAll = true; +int dump_frame_0 = 5072; +int dump_frame_1 = 5074; +int s_n_debug = -1; +int s_n_exit = -1; +int primID = 0; +int* primIDSW = 0; +std::map> pointsCalcRange; +std::map> pointsSWRange; +std::vector> pointsCalcDebug; +std::vector> pointsSWDebug; +std::map, std::tuple> pointsCalcDebugOrig; +std::map, std::tuple> pointsSWDebugOrig; +std::string debugDumpDir = DEBUG_DUMP_DIR; +#endif + namespace GSRunner { static void InitializeConsole(); @@ -134,6 +163,20 @@ bool GSRunner::InitializeConfig() si.SetBoolValue("EmuCore/GS", "OsdShowResolution", true); si.SetBoolValue("EmuCore/GS", "OsdShowGSStats", true); +#if MY_DEBUG || MY_DUMP + if (dumpAll) + { + si.SetBoolValue("EmuCore/GS", "dump", true); + si.SetIntValue("EmuCore/GS", "saven", 0); + si.SetIntValue("EmuCore/GS", "savel", -1); + si.SetBoolValue("EmuCore/GS", "save", true); + si.SetBoolValue("EmuCore/GS", "savef", true); + si.SetBoolValue("EmuCore/GS", "savet", true); + si.SetBoolValue("EmuCore/GS", "savez", true); + si.SetStringValue("EmuCore/GS", "HWDumpDirectory", debugDumpDir.c_str()); + si.SetStringValue("EmuCore/GS", "SWDumpDirectory", debugDumpDir.c_str()); + } +#endif // remove memory cards, so we don't have sharing violations for (u32 i = 0; i < 2; i++) { @@ -465,6 +508,7 @@ void GSRunner::InitializeConsole() bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& params) { + std::string dumpdir; // Save from argument -dumpdir for creating sub-directories bool no_more_args = false; for (int i = 1; i < argc; i++) { @@ -485,7 +529,7 @@ bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& pa } else if (CHECK_ARG_PARAM("-dumpdir")) { - s_output_prefix = StringUtil::StripWhitespace(argv[++i]); + dumpdir = s_output_prefix = StringUtil::StripWhitespace(argv[++i]); if (s_output_prefix.empty()) { Console.Error("Invalid dump directory specified."); @@ -500,6 +544,74 @@ bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& pa continue; } + else if (CHECK_ARG_PARAM("-dump")) + { + std::string str(argv[++i]); + + s_settings_interface.SetBoolValue("EmuCore/GS", "dump", true); + s_settings_interface.SetIntValue("EmuCore/GS", "saven", 0); + s_settings_interface.SetIntValue("EmuCore/GS", "savel", -1); + s_settings_interface.SetIntValue("EmuCore/GS", "savenf", 5000); // 5000 is the first frame + s_settings_interface.SetIntValue("EmuCore/GS", "savelf", -1); + + if (str.find("rt") != std::string::npos) + s_settings_interface.SetBoolValue("EmuCore/GS", "save", true); + if (str.find("f") != std::string::npos) + s_settings_interface.SetBoolValue("EmuCore/GS", "savef", true); + if (str.find("tex") != std::string::npos) + s_settings_interface.SetBoolValue("EmuCore/GS", "savet", true); + if (str.find("z") != std::string::npos) + s_settings_interface.SetBoolValue("EmuCore/GS", "savez", true); + continue; + } + else if (CHECK_ARG_PARAM("-dumprange")) + { + std::string str(argv[++i]); + + std::vector split = StringUtil::SplitString(str, ','); + int start = 0; + int num = -1; + if (split.size() > 0) + { + start = StringUtil::FromChars(split[0]).value_or(0); + } + if (split.size() > 1) + { + num = StringUtil::FromChars(split[1]).value_or(-1); + } + s_settings_interface.SetIntValue("EmuCore/GS", "saven", start); + s_settings_interface.SetIntValue("EmuCore/GS", "savel", num); + continue; + } + else if (CHECK_ARG_PARAM("-dumprangef")) + { + std::string str(argv[++i]); + + std::vector split = StringUtil::SplitString(str, ','); + int start = 0; + int num = -1; + if (split.size() > 0) + { + start = StringUtil::FromChars(split[0]).value_or(0); + } + if (split.size() > 1) + { + num = StringUtil::FromChars(split[1]).value_or(-1); + } + s_settings_interface.SetIntValue("EmuCore/GS", "savenf", start + 4999); // 5000 is the first frame + s_settings_interface.SetIntValue("EmuCore/GS", "savelf", num); + continue; + } + else if (CHECK_ARG_PARAM("-dumpdirhw")) + { + s_settings_interface.SetStringValue("EmuCore/GS", "HWDumpDirectory", argv[++i]); + continue; + } + else if (CHECK_ARG_PARAM("-dumpdirsw")) + { + s_settings_interface.SetStringValue("EmuCore/GS", "SWDumpDirectory", argv[++i]); + continue; + } else if (CHECK_ARG_PARAM("-loop")) { s_loop_count = StringUtil::FromChars(argv[++i]).value_or(0); @@ -643,6 +755,14 @@ bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& pa return false; } + if (s_settings_interface.GetBoolValue("EmuCore/GS", "dump") && !dumpdir.empty()) + { + if (s_settings_interface.GetStringValue("EmuCore/GS", "HWDumpDirectory").empty()) + s_settings_interface.SetStringValue("EmuCore/GS", "HWDumpDirectory", dumpdir.c_str()); + if (s_settings_interface.GetStringValue("EmuCore/GS", "SWDumpDirectory").empty()) + s_settings_interface.SetStringValue("EmuCore/GS", "SWDumpDirectory", dumpdir.c_str()); + } + // set up the frame dump directory if (!s_output_prefix.empty()) { diff --git a/pcsx2/Config.h b/pcsx2/Config.h index 5d59e799774b4..0d62eb0bf57ca 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -822,6 +822,8 @@ struct Pcsx2Config int SaveN = 0; int SaveL = 5000; + int SaveNF = 0; + int SaveLF = -1; s8 ExclusiveFullscreenControl = -1; GSScreenshotSize ScreenshotSize = GSScreenshotSize::WindowResolution; diff --git a/pcsx2/GS/GSState.cpp b/pcsx2/GS/GSState.cpp index 83068f15db4be..588965912e336 100644 --- a/pcsx2/GS/GSState.cpp +++ b/pcsx2/GS/GSState.cpp @@ -18,6 +18,8 @@ #include #include +#include "debug.h" + int GSState::s_n = 0; int GSState::s_last_transfer_draw_n = 0; int GSState::s_transfer_n = 0; @@ -443,7 +445,7 @@ void GSState::DumpVertices(const std::string& filename) file << std::fixed << std::setprecision(4); for (u32 i = 0; i < count; ++i) { - file << "\t" << "v" << i << ": "; + file << "\t" << std::dec << "v" << i << ": "; GSVertex v = buffer[m_index.buff[i]]; const float x = (v.XYZ.X - (int)m_context->XYOFFSET.OFX) / 16.0f; @@ -461,7 +463,7 @@ void GSState::DumpVertices(const std::string& filename) file << std::fixed << std::setprecision(6); for (u32 i = 0; i < count; ++i) { - file << "\t" << "v" << i << ": "; + file << "\t" << std::dec << "v" << i << ": "; GSVertex v = buffer[m_index.buff[i]]; file << std::setfill('0') << std::setw(3) << unsigned(v.RGBAQ.R) << DEL; @@ -479,7 +481,7 @@ void GSState::DumpVertices(const std::string& filename) file << "TEXTURE COORDS (" << qualifier << ")" << std::endl;; for (u32 i = 0; i < count; ++i) { - file << "\t" << "v" << i << ": "; + file << "\t" << "v" << std::dec << i << ": "; const GSVertex v = buffer[m_index.buff[i]]; // note @@ -1994,7 +1996,7 @@ void GSState::InitReadFIFO(u8* mem, int len) // Read the image all in one go. m_mem.ReadImageX(m_tr.x, m_tr.y, m_tr.buff, m_tr.total, m_env.BITBLTBUF, m_env.TRXPOS, m_env.TRXREG); - if (GSConfig.DumpGSData && GSConfig.SaveRT && s_n >= GSConfig.SaveN) + if (GSConfig.DumpGSData && GSConfig.SaveRT && s_n >= GSConfig.SaveN && g_perfmon.GetFrame() >= GSConfig.SaveNF) { const std::string s(GetDrawDumpPath( "%05d_read_%05x_%d_%d_%d_%d_%d_%d.bmp", @@ -3831,10 +3833,10 @@ GSState::TextureMinMaxResult GSState::GetTextureMinMax(GIFRegTEX0 TEX0, GIFRegCL u8 uses_border = 0; - if (m_vt.m_max.t.x >= FLT_MAX || m_vt.m_min.t.x <= -FLT_MAX || - m_vt.m_max.t.y >= FLT_MAX || m_vt.m_min.t.y <= -FLT_MAX) + if (m_vt.m_max.t.x >= 2047 || m_vt.m_min.t.x <= -2047 || + m_vt.m_max.t.y >= 2047 || m_vt.m_min.t.y <= -2047) { - // If any of the min/max values are +-FLT_MAX we can't rely on them + // If any of the min/max values are +/-2047 we can't rely on them // so just assume full texture. uses_border = 0xF; } diff --git a/pcsx2/GS/Renderers/Common/GSVertexTraceFMM.cpp b/pcsx2/GS/Renderers/Common/GSVertexTraceFMM.cpp index 2360f8def7742..9c2c59305d783 100644 --- a/pcsx2/GS/Renderers/Common/GSVertexTraceFMM.cpp +++ b/pcsx2/GS/Renderers/Common/GSVertexTraceFMM.cpp @@ -5,6 +5,8 @@ #include "GS/GSState.h" #include +#define USE_HACK_TJTJ 1 + class CURRENT_ISA::GSVertexTraceFMM { static constexpr GSVector4 s_minmax = GSVector4::cxpr(FLT_MAX, -FLT_MAX, 0.f, 0.f); @@ -139,8 +141,20 @@ void GSVertexTraceFMM::FindMinMax(GSVertexTrace& vt, const void* vertex, const u stq0 = st.xyww(primclass == GS_SPRITE_CLASS ? stq1 : stq0); stq1 = st.zwww(stq1); - tmin = tmin.min(stq0.min(stq1)); - tmax = tmax.max(stq0.max(stq1)); + GSVector4 temp_min = stq0.min(stq1); + GSVector4 temp_max = stq0.max(stq1); + if (std::isnan(temp_min.x) || std::isnan(temp_min.y) || std::isnan(temp_max.x) || std::isnan(temp_max.y)) + { + fprintf(stderr, "FOUND NAN %d\n", GSState::s_n); + } +#if USE_HACK_TJTJ + temp_min.x = std::isnan(temp_min.x) ? s_minmax.x : temp_min.x; + temp_min.y = std::isnan(temp_min.y) ? s_minmax.x : temp_min.y; + temp_max.x = std::isnan(temp_max.x) ? s_minmax.y : temp_max.x; + temp_max.y = std::isnan(temp_max.y) ? s_minmax.y : temp_max.y; +#endif + tmin = tmin.min(temp_min); + tmax = tmax.max(temp_max); } else { @@ -246,12 +260,29 @@ void GSVertexTraceFMM::FindMinMax(GSVertexTrace& vt, const void* vertex, const u vt.m_min.t = tmin * s; vt.m_max.t = tmax * s; - + if (vt.m_min.t.x < (-2047.0f) || vt.m_min.t.y < (-2047.0f) || vt.m_max.t.x > (2047.0f) || vt.m_max.t.y > (2047.0f)) + { + fprintf(stderr, "LARGE VALUES %d\n", GSState::s_n); + } +#if USE_HACK_TJTJ // Clamp the min/max values to the min/max valid UV values // This is needed in certain cases where buggy GS input results // in huge floating points values for ST. - vt.m_min.t = vt.m_min.t.min(GSVector4(2047.0f)).max(GSVector4(-2047.0f)).xyxy(vt.m_min.t); - vt.m_max.t = vt.m_max.t.min(GSVector4(2047.0f)).max(GSVector4(-2047.0f)).xyxy(vt.m_max.t); + //vt.m_min.t.x = std::isnan(vt.m_min.t.x) ? -2047.0f : vt.m_min.t.x; + //vt.m_min.t.y = std::isnan(vt.m_min.t.y) ? -2047.0f : vt.m_min.t.y; + //vt.m_max.t.x = std::isnan(vt.m_max.t.x) ? 2047.0f : vt.m_max.t.x; + //vt.m_max.t.y = std::isnan(vt.m_max.t.y) ? 2047.0f : vt.m_max.t.y; + GSVector4 min0 = vt.m_min.t; + GSVector4 max0 = vt.m_max.t; + + vt.m_min.t = vt.m_min.t.min(GSVector4(2047.0f)).max(GSVector4(-2047.0f)).xyzw(vt.m_min.t); + vt.m_max.t = vt.m_max.t.min(GSVector4(2047.0f)).max(GSVector4(-2047.0f)).xyzw(vt.m_max.t); + + if (!(min0 == vt.m_min.t).alltrue() || !(max0 == vt.m_max.t).alltrue()) + { + fprintf(stderr, "LARGE VALUES %d\n", GSState::s_n); + } +#endif } else { @@ -270,3 +301,5 @@ void GSVertexTraceFMM::FindMinMax(GSVertexTrace& vt, const void* vertex, const u vt.m_max.c = GSVector4i::zero(); } } + +#undef USE_HACK_TJTJ \ No newline at end of file diff --git a/pcsx2/GS/Renderers/SW/GSDrawScanline.cpp b/pcsx2/GS/Renderers/SW/GSDrawScanline.cpp index e6fa605090eb8..746d1e47d8229 100644 --- a/pcsx2/GS/Renderers/SW/GSDrawScanline.cpp +++ b/pcsx2/GS/Renderers/SW/GSDrawScanline.cpp @@ -10,8 +10,12 @@ #include +#include "debug.h" + // Comment to disable all dynamic code generation. +#if MY_DEBUG == 0 #define ENABLE_JIT_RASTERIZER +#endif #if MULTI_ISA_COMPILE_ONCE // Lack of a better home diff --git a/pcsx2/GS/Renderers/SW/GSRasterizer.cpp b/pcsx2/GS/Renderers/SW/GSRasterizer.cpp index dda8409316ecd..c3da379e2cd2e 100644 --- a/pcsx2/GS/Renderers/SW/GSRasterizer.cpp +++ b/pcsx2/GS/Renderers/SW/GSRasterizer.cpp @@ -614,9 +614,53 @@ void GSRasterizer::DrawTriangle(const GSVertexSW* vertex, const u16* index) i[1] = index[s_ysort[m1][1]]; i[2] = index[s_ysort[m1][2]]; - const GSVertexSW& v0 = vertex[i[0]]; - const GSVertexSW& v1 = vertex[i[1]]; - const GSVertexSW& v2 = vertex[i[2]]; + GSVertexSW v0 = vertex[i[0]]; + GSVertexSW v1 = vertex[i[1]]; + GSVertexSW v2 = vertex[i[2]]; + + + // Handle possible large/infinite ST coords + if (m_local.gd->sel.fst == 0) + { + //bool nan_s = std::isnan(v0.t.x / v0.t.z) || std::isnan(v1.t.x / v1.t.z) || std::isnan(v2.t.x / v2.t.z); + //bool nan_t = std::isnan(v0.t.y / v0.t.z) || std::isnan(v1.t.y / v1.t.z) || std::isnan(v2.t.y / v2.t.z); + //bool large_s = (v0.t.x / v0.t.z) > 1e30 || (v1.t.x / v1.t.z) > 1e30 || (v2.t.x / v2.t.z) > 1e30; + //bool small_s = (v0.t.x / v0.t.z) < -1e30 || (v1.t.x / v1.t.z) < -1e30 || (v2.t.x / v2.t.z) < -1e30; + //bool large_t = (v0.t.y / v0.t.z) > 1e30 || (v1.t.y / v1.t.z) > 1e30 || (v2.t.y / v2.t.z) > 1e30; + //bool small_t = (v0.t.y / v0.t.z) < -1e30 || (v1.t.y / v1.t.z) < -1e30 || (v2.t.y / v2.t.z) < -1e30; + //if (nan_s || (large_s && small_s)) + //{ + // // Not sure what to do here + //} + //else if (large_s) + //{ + // v0.t.x = 2047.0f * 65536.0f * v0.t.z; + // v1.t.x = 2047.0f * 65536.0f * v1.t.z; + // v2.t.x = 2047.0f * 65536.0f * v2.t.z; + //} + //else if (small_s) + //{ + // v0.t.x = -2047.0f * 65536.0f * v0.t.z; + // v1.t.x = -2047.0f * 65536.0f * v1.t.z; + // v2.t.x = -2047.0f * 65536.0f * v2.t.z; + //} + //if (nan_t || (large_t && small_t)) + //{ + // // Not sure what to do here so just give 0 + //} + //else if (large_t) + //{ + // v0.t.y = 2047.0f * 65536.0f * v0.t.z; + // v1.t.y = 2047.0f * 65536.0f * v1.t.z; + // v2.t.y = 2047.0f * 65536.0f * v2.t.z; + //} + //else if (small_t) + //{ + // v0.t.y = -2047.0f * 65536.0f * v0.t.z; + // v1.t.y = -2047.0f * 65536.0f * v1.t.z; + // v2.t.y = -2047.0f * 65536.0f * v2.t.z; + //} + } y0011 = v0.p.yyyy(v1.p); y1221 = v1.p.yyyy(v2.p).xzzx(); diff --git a/pcsx2/GS/Renderers/SW/GSRendererSW.cpp b/pcsx2/GS/Renderers/SW/GSRendererSW.cpp index 01662d605c4c1..47075db591a45 100644 --- a/pcsx2/GS/Renderers/SW/GSRendererSW.cpp +++ b/pcsx2/GS/Renderers/SW/GSRendererSW.cpp @@ -8,10 +8,16 @@ #include "common/StringUtil.h" +#include "debug.h" + MULTI_ISA_UNSHARED_IMPL; GSRenderer* CURRENT_ISA::makeGSRendererSW(int threads) { +#if MY_DEBUG + threads = 0; +#endif + threads = 0; return new GSRendererSW(threads); } @@ -181,7 +187,7 @@ GSTexture* GSRendererSW::GetOutput(int i, float& scale, int& y_offset) if (GSConfig.DumpGSData) { - if (GSConfig.SaveFrame && s_n >= GSConfig.SaveN) + if (GSConfig.SaveFrame && s_n >= GSConfig.SaveN && g_perfmon.GetFrame() >= GSConfig.SaveNF) { m_texture[index]->Save(GetDrawDumpPath("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), i, (int)curFramebuffer.Block(), psm_str(curFramebuffer.PSM))); } @@ -316,7 +322,7 @@ void GSRendererSW::Draw() { std::string s; - if (s_n >= GSConfig.SaveN) + if (s_n >= GSConfig.SaveN && g_perfmon.GetFrame() >= GSConfig.SaveNF) { // Dump Register state s = GetDrawDumpPath("%05d_context.txt", s_n); @@ -444,7 +450,7 @@ void GSRendererSW::Draw() // It will breaks the few games that really uses 16 bits RT bool texture_shuffle = ((context->FRAME.PSM & 0x2) && ((context->TEX0.PSM & 3) == 2) && (m_vt.m_primclass == GS_SPRITE_CLASS)); - if (GSConfig.SaveTexture && s_n >= GSConfig.SaveN && PRIM->TME) + if (GSConfig.SaveTexture && s_n >= GSConfig.SaveN && g_perfmon.GetFrame() >= GSConfig.SaveNF && PRIM->TME) { if (texture_shuffle) { @@ -457,9 +463,8 @@ void GSRendererSW::Draw() m_mem.SaveBMP(s, m_context->TEX0.TBP0, m_context->TEX0.TBW, m_context->TEX0.PSM, 1 << m_context->TEX0.TW, 1 << m_context->TEX0.TH); } - if (GSConfig.SaveRT && s_n >= GSConfig.SaveN) + if (GSConfig.SaveRT && s_n >= GSConfig.SaveN && g_perfmon.GetFrame() >= GSConfig.SaveNF) { - if (texture_shuffle) { // Dump the RT in 32 bits format. It helps to debug texture shuffle effect @@ -471,7 +476,7 @@ void GSRendererSW::Draw() m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, r.z, r.w); } - if (GSConfig.SaveDepth && s_n >= GSConfig.SaveN) + if (GSConfig.SaveDepth && s_n >= GSConfig.SaveN && g_perfmon.GetFrame() >= GSConfig.SaveNF) { s = GetDrawDumpPath("%05d_f%lld_rz0_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM)); @@ -482,7 +487,7 @@ void GSRendererSW::Draw() Sync(3); - if (GSConfig.SaveRT && s_n >= GSConfig.SaveN) + if (GSConfig.SaveRT && s_n >= GSConfig.SaveN && g_perfmon.GetFrame() >= GSConfig.SaveNF) { if (texture_shuffle) { @@ -495,14 +500,18 @@ void GSRendererSW::Draw() m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, r.z, r.w); } - if (GSConfig.SaveDepth && s_n >= GSConfig.SaveN) + if (GSConfig.SaveDepth && s_n >= GSConfig.SaveN && g_perfmon.GetFrame() >= GSConfig.SaveNF) { s = GetDrawDumpPath("%05d_f%lld_rz1_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM)); m_mem.SaveBMP(s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, r.z, r.w); } - if (GSConfig.SaveL > 0 && (s_n - GSConfig.SaveN) > GSConfig.SaveL) + if (GSConfig.SaveL > 0 && (s_n - GSConfig.SaveN) >= GSConfig.SaveL) + { + GSConfig.DumpGSData = 0; + } + if (GSConfig.SaveLF > 0 && ((int)g_perfmon.GetFrame() - GSConfig.SaveNF) >= GSConfig.SaveLF) { GSConfig.DumpGSData = 0; } @@ -1038,7 +1047,18 @@ bool GSRendererSW::GetScanlineGlobalData(SharedData* data) gd.clut = (u32*)m_vertex_heap.alloc(sizeof(u32) * 256, VECTOR_ALIGNMENT); // FIXME: might address uninitialized data of the texture (0xCD) that is not in 0-15 range for 4-bpp formats + memset(gd.clut, 0, sizeof(u32) * 256); + memcpy(gd.clut, (const u32*)m_mem.m_clut, sizeof(u32) * GSLocalMemory::m_psm[context->TEX0.PSM].pal); + + //if (gd.clut && s_n == 24) + //{ + // for (int i = 0; i < 256; i++) + // { + // fprintf(stderr, "%x\n", ((u32*)gd.clut)[i]); + // } + // printf(""); + //} } gd.sel.wms = context->CLAMP.WMS; @@ -1058,6 +1078,10 @@ bool GSRendererSW::GetScanlineGlobalData(SharedData* data) GIFRegTEX0 TEX0 = m_context->GetSizeFixedTEX0(m_vt.m_min.t.xyxy(m_vt.m_max.t), m_vt.IsLinear(), mipmap); GSVector4i r = GetTextureMinMax(TEX0, context->CLAMP, gd.sel.ltf, true).coverage; + if (s_n == 840) + { + fprintf(stderr, "rect: %d %d %d %d\n", r.x, r.y, r.z, r.w); + } GSTextureCacheSW::Texture* t = m_tc->Lookup(TEX0, env.TEXA); @@ -1547,6 +1571,14 @@ void GSRendererSW::SharedData::UpdateSource() } // TODO + //if (global.clut && s_n == 24) + //{ + // for (int i = 0; i < 256; i++) + // { + // fprintf(stderr, "%x\n", ((u32*)global.clut)[i]); + // } + // printf(""); + //} if (GSConfig.DumpGSData) { @@ -1554,7 +1586,7 @@ void GSRendererSW::SharedData::UpdateSource() std::string s; - if (GSConfig.SaveTexture && g_gs_renderer->s_n >= GSConfig.SaveN) + if (GSConfig.SaveTexture && g_gs_renderer->s_n >= GSConfig.SaveN && g_perfmon.GetFrame() >= GSConfig.SaveNF) { for (size_t i = 0; m_tex[i].t; i++) { diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index 8763f6ab348e4..009aef62cc73e 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -1026,6 +1026,8 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap) SettingsWrapBitfieldEx(PNGCompressionLevel, "png_compression_level"); SettingsWrapBitfieldEx(SaveN, "saven"); SettingsWrapBitfieldEx(SaveL, "savel"); + SettingsWrapBitfieldEx(SaveNF, "savenf"); + SettingsWrapBitfieldEx(SaveLF, "savelf"); SettingsWrapEntryEx(CaptureContainer, "CaptureContainer"); SettingsWrapEntryEx(VideoCaptureCodec, "VideoCaptureCodec"); diff --git a/pcsx2/debug.h b/pcsx2/debug.h new file mode 100644 index 0000000000000..92b2851cdf565 --- /dev/null +++ b/pcsx2/debug.h @@ -0,0 +1,3 @@ +#pragma once +#define MY_DEBUG 0 +#define MY_DUMP 0 \ No newline at end of file