Skip to content

Commit

Permalink
Tools: Add additional options for dumping in GS runner. Other formatt…
Browse files Browse the repository at this point in the history
…ing fixes.
  • Loading branch information
TJnotJT committed Jan 24, 2025
1 parent df7646f commit e9e649a
Show file tree
Hide file tree
Showing 12 changed files with 197 additions and 105 deletions.
105 changes: 103 additions & 2 deletions pcsx2-gsrunner/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ void Host::BeginPresentFrame()
GSJoinSnapshotThreads();

// queue dumping of this frame
std::string dump_path(fmt::format("{}_frame{}.png", s_output_prefix, s_dump_frame_number));
std::string dump_path(fmt::format("{}_frame{:05}.png", s_output_prefix, s_dump_frame_number));
GSQueueSnapshot(dump_path);
}

Expand Down Expand Up @@ -443,6 +443,14 @@ static void PrintCommandLineHelp(const char* progname)
std::fprintf(stderr, " -help: Displays this information and exits.\n");
std::fprintf(stderr, " -version: Displays version information and exits.\n");
std::fprintf(stderr, " -dumpdir <dir>: Frame dump directory (will be dumped as filename_frameN.png).\n");
std::fprintf(stderr, " -dump [rt|tex|z|f|a|i]: Enabling dunmping of render target, texture, z buffer, frame, "
"alphas, and info (context, vertices), respectively, per draw. Generates lots of data.\n");
std::fprintf(stderr, " -dumprange N[,L,B]: Start dumping from draw N (base 0), stops after L draws, and only "
"those draws that are multiples of B (intersection of -dumprange and -dumrangef used)."
"Defaults to N=0,L=-1,B=1 (all draws). Only used if -dump used.\n");
std::fprintf(stderr, " -dumprangef NF[,LF,BF]: Start dumping from frame NF (base 0), stops after LF frames, "
"and only those frames that are multiples of BF (intersection of -dumprange and -dumrangef used).\n"
"Defaults to NF=0,LF=-1,BF=1 (all frames). Only used if -dump is used.\n");
std::fprintf(stderr, " -loop <count>: Loops dump playback N times. Defaults to 1. 0 will loop infinitely.\n");
std::fprintf(stderr, " -renderer <renderer>: Sets the graphics renderer. Defaults to Auto.\n");
std::fprintf(stderr, " -window: Forces a window to be displayed.\n");
Expand All @@ -465,6 +473,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++)
{
Expand All @@ -485,7 +494,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.");
Expand All @@ -500,6 +509,86 @@ 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);

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);
if (str.find("a") != std::string::npos)
s_settings_interface.SetBoolValue("EmuCore/GS", "savea", true);
if (str.find("i") != std::string::npos)
s_settings_interface.SetBoolValue("EmuCore/GS", "savei", true);
continue;
}
else if (CHECK_ARG_PARAM("-dumprange"))
{
std::string str(argv[++i]);

std::vector<std::string_view> split = StringUtil::SplitString(str, ',');
int start = 0;
int num = -1;
int by = 1;
if (split.size() > 0)
{
start = StringUtil::FromChars<int>(split[0]).value_or(0);
}
if (split.size() > 1)
{
num = StringUtil::FromChars<int>(split[1]).value_or(-1);
}
if (split.size() > 2)
{
by = std::max(1, StringUtil::FromChars<int>(split[2]).value_or(1));
}
s_settings_interface.SetIntValue("EmuCore/GS", "saven", start);
s_settings_interface.SetIntValue("EmuCore/GS", "savel", num);
s_settings_interface.SetIntValue("EmuCore/GS", "saveb", by);
continue;
}
else if (CHECK_ARG_PARAM("-dumprangef"))
{
std::string str(argv[++i]);

std::vector<std::string_view> split = StringUtil::SplitString(str, ',');
int start = 0;
int num = -1;
int by = 1;
if (split.size() > 0)
{
start = StringUtil::FromChars<int>(split[0]).value_or(0);
}
if (split.size() > 1)
{
num = StringUtil::FromChars<int>(split[1]).value_or(-1);
}
if (split.size() > 2)
{
by = std::max(1, StringUtil::FromChars<int>(split[2]).value_or(1));
}
s_settings_interface.SetIntValue("EmuCore/GS", "savenf", start);
s_settings_interface.SetIntValue("EmuCore/GS", "savelf", num);
s_settings_interface.SetIntValue("EmuCore/GS", "savebf", by);
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<s32>(argv[++i]).value_or(0);
Expand Down Expand Up @@ -643,6 +732,18 @@ 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());

// Disable saving frames with SaveSnapshotToMemory()
// Instead we save more "raw" snapshots when using -dump.
s_output_prefix = "";
}

// set up the frame dump directory
if (!s_output_prefix.empty())
{
Expand Down
9 changes: 9 additions & 0 deletions pcsx2/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,8 @@ struct Pcsx2Config
SaveFrame : 1,
SaveTexture : 1,
SaveDepth : 1,
SaveAlpha : 1,
SaveInfo : 1,
DumpReplaceableTextures : 1,
DumpReplaceableMipmaps : 1,
DumpTexturesWithFMVActive : 1,
Expand Down Expand Up @@ -822,6 +824,10 @@ struct Pcsx2Config

int SaveN = 0;
int SaveL = 5000;
int SaveB = 1;
int SaveNF = 0;
int SaveLF = -1;
int SaveBF = 1;

s8 ExclusiveFullscreenControl = -1;
GSScreenshotSize ScreenshotSize = GSScreenshotSize::WindowResolution;
Expand Down Expand Up @@ -865,6 +871,9 @@ struct Pcsx2Config

bool operator==(const GSOptions& right) const;
bool operator!=(const GSOptions& right) const;

// Should we dump this draw/frame?
bool ShouldDump(int draw, int frame) const;
};

struct SPU2Options
Expand Down
7 changes: 3 additions & 4 deletions pcsx2/GS/GSDrawingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,16 +203,15 @@ void GSDrawingContext::Dump(const std::string& filename)
"\tTBW:%u\n"
"\tPSM:0x%x\n"
"\tTW:%u\n"
"\tTH:%u\n"
"\tTCC:%u\n"
"\tTFX:%u\n"
"\tCBP:0x%x\n"
"\tCPSM:0x%x\n"
"\tCSM:%u\n"
"\tCSA:%u\n"
"\tCLD:%u\n"
"\tTH:%u\n",
TEX0.TBP0, TEX0.TBW, TEX0.PSM, TEX0.TW, TEX0.TCC, TEX0.TFX, TEX0.CBP, TEX0.CPSM, TEX0.CSM, TEX0.CSA, TEX0.CLD,
static_cast<uint32_t>(TEX0.TH));
"\tCLD:%u\n\n",
TEX0.TBP0, TEX0.TBW, TEX0.PSM, TEX0.TW, static_cast<uint32_t>(TEX0.TH), TEX0.TCC, TEX0.TFX, TEX0.CBP, TEX0.CPSM, TEX0.CSM, TEX0.CSA, TEX0.CLD);

fprintf(fp,
"TEX1\n"
Expand Down
1 change: 0 additions & 1 deletion pcsx2/GS/GSDrawingEnvironment.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ class alignas(32) GSDrawingEnvironment

fprintf(fp, "SCANMSK\n"
"\tMSK:%u\n\n"
"\n"
, SCANMSK.MSK);

fprintf(fp, "TEXA\n"
Expand Down
6 changes: 1 addition & 5 deletions pcsx2/GS/GSLocalMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -662,11 +662,7 @@ void GSLocalMemory::SaveBMP(const std::string& fn, u32 bp, u32 bw, u32 psm, int
}
}

#ifdef PCSX2_DEVBUILD
GSPng::Save(GSPng::RGB_A_PNG, fn, static_cast<u8*>(bits), w, h, pitch, GSConfig.PNGCompressionLevel, false);
#else
GSPng::Save(GSPng::RGB_PNG, fn, static_cast<u8*>(bits), w, h, pitch, GSConfig.PNGCompressionLevel, false);
#endif
GSPng::Save((IsDevBuild || GSConfig.SaveAlpha) ? GSPng::RGB_A_PNG : GSPng::RGB_PNG, fn, static_cast<u8*>(bits), w, h, pitch, GSConfig.PNGCompressionLevel, false);

_aligned_free(bits);
}
Expand Down
10 changes: 5 additions & 5 deletions pcsx2/GS/GSState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,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;
Expand All @@ -461,7 +461,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;
Expand All @@ -479,7 +479,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
Expand Down Expand Up @@ -1994,7 +1994,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.SaveRT && GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
{
const std::string s(GetDrawDumpPath(
"%05d_read_%05x_%d_%d_%d_%d_%d_%d.bmp",
Expand Down Expand Up @@ -2742,7 +2742,7 @@ int GSState::Defrost(const freezeData* fd)
m_mem.m_clut.Reset();
(PRIM->CTXT == 0) ? ApplyTEX0<0>(m_context->TEX0) : ApplyTEX0<1>(m_context->TEX0);

g_perfmon.SetFrame(5000);
g_perfmon.SetFrame(0);

ResetPCRTC();

Expand Down
4 changes: 2 additions & 2 deletions pcsx2/GS/Renderers/Common/GSRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -546,9 +546,9 @@ void GSRenderer::EndPresentFrame()

void GSRenderer::VSync(u32 field, bool registers_written, bool idle_frame)
{
if (GSConfig.DumpGSData && s_n >= GSConfig.SaveN)
if (GSConfig.SaveInfo && GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
{
DumpGSPrivRegs(*m_regs, GetDrawDumpPath("vsync_%05d_f%lld_gs_reg.txt", s_n, g_perfmon.GetFrame()));
DumpGSPrivRegs(*m_regs, GetDrawDumpPath("%05d_f%05lld_vsync_gs_reg.txt", s_n, g_perfmon.GetFrame()));
}

const int fb_sprite_blits = g_perfmon.GetDisplayFramebufferSpriteBlits();
Expand Down
7 changes: 2 additions & 5 deletions pcsx2/GS/Renderers/Common/GSTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,8 @@ bool GSTexture::Save(const std::string& fn)
return res;
}

#ifdef PCSX2_DEVBUILD
GSPng::Format format = GSPng::RGB_A_PNG;
#else
GSPng::Format format = GSPng::RGB_PNG;
#endif
GSPng::Format format = (IsDevBuild || GSConfig.SaveAlpha) ? GSPng::RGB_A_PNG : GSPng::RGB_PNG;

switch (m_format)
{
case Format::UNorm8:
Expand Down
Loading

0 comments on commit e9e649a

Please sign in to comment.