GS: Get rid of hardcoded dump directory

This commit is contained in:
Stenzek 2022-12-24 13:47:10 +10:00 committed by refractionpcsx2
parent 35e28fc0d0
commit 8dcda63c85
11 changed files with 91 additions and 120 deletions

View File

@ -748,6 +748,8 @@ struct Pcsx2Config
int VideoCaptureBitrate{DEFAULT_VIDEO_CAPTURE_BITRATE};
std::string Adapter;
std::string HWDumpDirectory;
std::string SWDumpDirectory;
GSOptions();

View File

@ -908,20 +908,6 @@ std::string format(const char* fmt, ...)
return {buffer.data()};
}
// Helper path to dump texture
#ifdef _WIN32
const std::string root_sw("c:\\temp1\\_");
const std::string root_hw("c:\\temp2\\_");
#else
#ifdef _M_AMD64
const std::string root_sw("/tmp/GS_SW_dump64/");
const std::string root_hw("/tmp/GS_HW_dump64/");
#else
const std::string root_sw("/tmp/GS_SW_dump32/");
const std::string root_hw("/tmp/GS_HW_dump32/");
#endif
#endif
#ifdef _WIN32
static HANDLE s_fh = NULL;

View File

@ -114,10 +114,6 @@ static constexpr int MAXIMUM_TEXTURE_MIPMAP_LEVELS = 7;
// The maximum number of duplicate frames we can skip presenting for.
static constexpr u32 MAX_SKIPPED_DUPLICATE_FRAMES = 3;
// Helper path to dump texture
extern const std::string root_sw;
extern const std::string root_hw;
extern void* GSAllocateWrappedMemory(size_t size, size_t repeat);
extern void GSFreeWrappedMemory(void* ptr, size_t size, size_t repeat);

View File

@ -17,6 +17,7 @@
#include "GSState.h"
#include "GSGL.h"
#include "GSUtil.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include <algorithm> // clamp
@ -25,7 +26,6 @@
#include <iomanip> // Dump Verticles
int GSState::s_n = 0;
std::string GSState::s_dump_root;
static __fi bool IsAutoFlushEnabled()
{
@ -56,14 +56,6 @@ GSState::GSState()
m_mipmap = GSConfig.Mipmap;
s_n = 0;
s_dump_root = "";
#if defined(__unix__)
if (GSConfig.DumpGSData)
{
GSmkdir(root_hw.c_str());
GSmkdir(root_sw.c_str());
}
#endif
m_crc_hack_level = GSConfig.CRCHack;
if (m_crc_hack_level == CRCHackLevel::Automatic)
@ -141,6 +133,21 @@ GSState::~GSState()
_aligned_free(m_index.buff);
}
std::string GSState::GetDrawDumpPath(const char* format, ...)
{
std::va_list ap;
va_start(ap, format);
#ifdef PCSX2_CORE
const std::string& base = GSConfig.UseHardwareRenderer() ? GSConfig.HWDumpDirectory : GSConfig.SWDumpDirectory;
#else
// Buzz off wx
const char* base = GSConfig.UseHardwareRenderer() ? "C:\\temp2" : "C:\\temp1";
#endif
std::string ret(Path::Combine(base, StringUtil::StdStringFromFormatV(format, ap)));
va_end(ap);
return ret;
}
void GSState::Reset(bool hardware_reset)
{
Flush(GSFlushReason::RESET);
@ -2081,10 +2088,10 @@ void GSState::Read(u8* mem, int len)
if (GSConfig.DumpGSData && GSConfig.SaveRT && s_n >= GSConfig.SaveN)
{
std::string s = s_dump_root + StringUtil::StdStringFromFormat(
const std::string s(GetDrawDumpPath(
"%05d_read_%05x_%d_%d_%d_%d_%d_%d.bmp",
s_n, (int)m_env.BITBLTBUF.SBP, (int)m_env.BITBLTBUF.SBW, (int)m_env.BITBLTBUF.SPSM,
r.left, r.top, r.right, r.bottom);
r.left, r.top, r.right, r.bottom));
m_mem.SaveBMP(s, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW, m_env.BITBLTBUF.SPSM, r.right, r.bottom);
}

View File

@ -241,7 +241,6 @@ public:
int m_backed_up_ctx;
static int s_n;
static std::string s_dump_root;
static constexpr u32 STATE_VERSION = 8;
@ -335,6 +334,9 @@ public:
GSState();
virtual ~GSState();
/// Returns the appropriate directory for draw dumping.
static std::string GetDrawDumpPath(const char* format, ...);
void ResetHandlers();
int GetFramebufferHeight();

View File

@ -205,37 +205,6 @@ GSRendererType GSUtil::GetPreferredRenderer()
#endif
}
#ifdef _WIN32
void GSmkdir(const wchar_t* dir)
{
if (!CreateDirectory(dir, nullptr))
{
DWORD errorID = ::GetLastError();
if (errorID != ERROR_ALREADY_EXISTS)
{
fprintf(stderr, "Failed to create directory: %ls error %u\n", dir, errorID);
}
}
#else
void GSmkdir(const char* dir)
{
int err = mkdir(dir, 0777);
if (!err && errno != EEXIST)
fprintf(stderr, "Failed to create directory: %s\n", dir);
#endif
}
std::string GStempdir()
{
#ifdef _WIN32
wchar_t path[MAX_PATH + 1];
GetTempPath(MAX_PATH, path);
return StringUtil::WideStringToUTF8String(path);
#else
return "/tmp";
#endif
}
const char* psm_str(int psm)
{
switch (psm)

View File

@ -42,11 +42,4 @@ public:
static GSRendererType GetPreferredRenderer();
};
#ifdef _WIN32
void GSmkdir(const wchar_t* dir);
#else
void GSmkdir(const char* dir);
#endif
std::string GStempdir();
const char* psm_str(int psm);

View File

@ -631,7 +631,7 @@ void GSRenderer::VSync(u32 field, bool registers_written)
if (GSConfig.DumpGSData && s_n >= GSConfig.SaveN)
{
m_regs->Dump(root_sw + StringUtil::StdStringFromFormat("%05d_f%lld_gs_reg.txt", s_n, g_perfmon.GetFrame()));
m_regs->Dump(GetDrawDumpPath("vsync_%05d_f%lld_gs_reg.txt", s_n, g_perfmon.GetFrame()));
}
const int fb_sprite_blits = g_perfmon.GetDisplayFramebufferSpriteBlits();

View File

@ -37,7 +37,6 @@ GSRendererHW::GSRendererHW()
m_mipmap = (GSConfig.HWMipmap >= HWMipmapLevel::Basic);
SetTCOffset();
s_dump_root = root_hw;
GSTextureReplacements::Initialize(m_tc);
// Hope nothing requires too many draw calls.
@ -1283,14 +1282,14 @@ void GSRendererHW::Draw()
std::string s;
// Dump Register state
s = StringUtil::StdStringFromFormat("%05d_context.txt", s_n);
s = GetDrawDumpPath("%05d_context.txt", s_n);
m_env.Dump(s_dump_root + s);
m_context->Dump(s_dump_root + s);
m_env.Dump(s);
m_context->Dump(s);
// Dump vertices
s = StringUtil::StdStringFromFormat("%05d_vertex.txt", s_n);
DumpVertices(s_dump_root + s);
s = GetDrawDumpPath("%05d_vertex.txt", s_n);
DumpVertices(s);
}
if (IsBadFrame())
@ -1786,36 +1785,36 @@ void GSRendererHW::Draw()
if (GSConfig.SaveTexture && s_n >= GSConfig.SaveN && m_src)
{
s = StringUtil::StdStringFromFormat("%05d_f%lld_itex_%05x_%s_%d%d_%02x_%02x_%02x_%02x.dds",
s = GetDrawDumpPath("%05d_f%lld_itex_%05x_%s_%d%d_%02x_%02x_%02x_%02x.dds",
s_n, frame, (int)context->TEX0.TBP0, psm_str(context->TEX0.PSM),
(int)context->CLAMP.WMS, (int)context->CLAMP.WMT,
(int)context->CLAMP.MINU, (int)context->CLAMP.MAXU,
(int)context->CLAMP.MINV, (int)context->CLAMP.MAXV);
m_src->m_texture->Save(s_dump_root + s);
m_src->m_texture->Save(s);
if (m_src->m_palette)
{
s = StringUtil::StdStringFromFormat("%05d_f%lld_itpx_%05x_%s.dds", s_n, frame, context->TEX0.CBP, psm_str(context->TEX0.CPSM));
s = GetDrawDumpPath("%05d_f%lld_itpx_%05x_%s.dds", s_n, frame, context->TEX0.CBP, psm_str(context->TEX0.CPSM));
m_src->m_palette->Save(s_dump_root + s);
m_src->m_palette->Save(s);
}
}
if (rt && GSConfig.SaveRT && s_n >= GSConfig.SaveN)
{
s = StringUtil::StdStringFromFormat("%05d_f%lld_rt0_%05x_%s.bmp", s_n, frame, context->FRAME.Block(), psm_str(context->FRAME.PSM));
s = GetDrawDumpPath("%05d_f%lld_rt0_%05x_%s.bmp", s_n, frame, context->FRAME.Block(), psm_str(context->FRAME.PSM));
if (rt->m_texture)
rt->m_texture->Save(s_dump_root + s);
rt->m_texture->Save(s);
}
if (ds && GSConfig.SaveDepth && s_n >= GSConfig.SaveN)
{
s = StringUtil::StdStringFromFormat("%05d_f%lld_rz0_%05x_%s.bmp", s_n, frame, context->ZBUF.Block(), psm_str(context->ZBUF.PSM));
s = GetDrawDumpPath("%05d_f%lld_rz0_%05x_%s.bmp", s_n, frame, context->ZBUF.Block(), psm_str(context->ZBUF.PSM));
if (ds->m_texture)
ds->m_texture->Save(s_dump_root + s);
ds->m_texture->Save(s);
}
}
@ -1947,18 +1946,18 @@ void GSRendererHW::Draw()
if (GSConfig.SaveRT && s_n >= GSConfig.SaveN)
{
s = StringUtil::StdStringFromFormat("%05d_f%lld_rt1_%05x_%s.bmp", s_n, frame, context->FRAME.Block(), psm_str(context->FRAME.PSM));
s = GetDrawDumpPath("%05d_f%lld_rt1_%05x_%s.bmp", s_n, frame, context->FRAME.Block(), psm_str(context->FRAME.PSM));
if (rt)
rt->m_texture->Save(s_dump_root + s);
rt->m_texture->Save(s);
}
if (GSConfig.SaveDepth && s_n >= GSConfig.SaveN)
{
s = StringUtil::StdStringFromFormat("%05d_f%lld_rz1_%05x_%s.bmp", s_n, frame, context->ZBUF.Block(), psm_str(context->ZBUF.PSM));
s = GetDrawDumpPath("%05d_f%lld_rz1_%05x_%s.bmp", s_n, frame, context->ZBUF.Block(), psm_str(context->ZBUF.PSM));
if (ds)
rt->m_texture->Save(s_dump_root + s);
rt->m_texture->Save(s);
}
if (GSConfig.SaveL > 0 && (s_n - GSConfig.SaveN) > GSConfig.SaveL)

View File

@ -43,8 +43,6 @@ GSRendererSW::GSRendererSW(int threads)
std::fill(std::begin(m_fzb_pages), std::end(m_fzb_pages), 0);
std::fill(std::begin(m_tex_pages), std::end(m_tex_pages), 0);
s_dump_root = root_sw;
}
GSRendererSW::~GSRendererSW()
@ -205,7 +203,7 @@ GSTexture* GSRendererSW::GetOutput(int i, int& y_offset)
{
if (GSConfig.SaveFrame && s_n >= GSConfig.SaveN)
{
m_texture[i]->Save(s_dump_root + StringUtil::StdStringFromFormat("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), i, (int)DISPFB.Block(), psm_str(DISPFB.PSM)));
m_texture[i]->Save(GetDrawDumpPath("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), i, (int)DISPFB.Block(), psm_str(DISPFB.PSM)));
}
}
}
@ -340,14 +338,14 @@ void GSRendererSW::Draw()
if (s_n >= GSConfig.SaveN)
{
// Dump Register state
s = StringUtil::StdStringFromFormat("%05d_context.txt", s_n);
s = GetDrawDumpPath("%05d_context.txt", s_n);
m_env.Dump(s_dump_root + s);
m_context->Dump(s_dump_root + s);
m_env.Dump(s);
m_context->Dump(s);
// Dump vertices
s = StringUtil::StdStringFromFormat("%05d_vertex.txt", s_n);
DumpVertices(s_dump_root + s);
s = GetDrawDumpPath("%05d_vertex.txt", s_n);
DumpVertices(s);
}
}
@ -470,12 +468,12 @@ void GSRendererSW::Draw()
if (texture_shuffle)
{
// Dump the RT in 32 bits format. It helps to debug texture shuffle effect
s = StringUtil::StdStringFromFormat("%05d_f%lld_itexraw_%05x_32bits.bmp", s_n, frame, (int)m_context->TEX0.TBP0);
m_mem.SaveBMP(s_dump_root + s, m_context->TEX0.TBP0, m_context->TEX0.TBW, 0, 1 << m_context->TEX0.TW, 1 << m_context->TEX0.TH);
s = GetDrawDumpPath("%05d_f%lld_itexraw_%05x_32bits.bmp", s_n, frame, (int)m_context->TEX0.TBP0);
m_mem.SaveBMP(s, m_context->TEX0.TBP0, m_context->TEX0.TBW, 0, 1 << m_context->TEX0.TW, 1 << m_context->TEX0.TH);
}
s = StringUtil::StdStringFromFormat("%05d_f%lld_itexraw_%05x_%s.bmp", s_n, frame, (int)m_context->TEX0.TBP0, psm_str(m_context->TEX0.PSM));
m_mem.SaveBMP(s_dump_root + s, m_context->TEX0.TBP0, m_context->TEX0.TBW, m_context->TEX0.PSM, 1 << m_context->TEX0.TW, 1 << m_context->TEX0.TH);
s = GetDrawDumpPath("%05d_f%lld_itexraw_%05x_%s.bmp", s_n, frame, (int)m_context->TEX0.TBP0, psm_str(m_context->TEX0.PSM));
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)
@ -484,19 +482,19 @@ void GSRendererSW::Draw()
if (texture_shuffle)
{
// Dump the RT in 32 bits format. It helps to debug texture shuffle effect
s = StringUtil::StdStringFromFormat("%05d_f%lld_rt0_%05x_32bits.bmp", s_n, frame, m_context->FRAME.Block());
m_mem.SaveBMP(s_dump_root + s, m_context->FRAME.Block(), m_context->FRAME.FBW, 0, GetFrameRect().width(), 512);
s = GetDrawDumpPath("%05d_f%lld_rt0_%05x_32bits.bmp", s_n, frame, m_context->FRAME.Block());
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, 0, GetFrameRect().width(), 512);
}
s = StringUtil::StdStringFromFormat("%05d_f%lld_rt0_%05x_%s.bmp", s_n, frame, m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
m_mem.SaveBMP(s_dump_root + s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameRect().width(), 512);
s = GetDrawDumpPath("%05d_f%lld_rt0_%05x_%s.bmp", s_n, frame, m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameRect().width(), 512);
}
if (GSConfig.SaveDepth && s_n >= GSConfig.SaveN)
{
s = StringUtil::StdStringFromFormat("%05d_f%lld_rz0_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
s = GetDrawDumpPath("%05d_f%lld_rz0_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
m_mem.SaveBMP(s_dump_root + s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameRect().width(), 512);
m_mem.SaveBMP(s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameRect().width(), 512);
}
Queue(data);
@ -508,19 +506,19 @@ void GSRendererSW::Draw()
if (texture_shuffle)
{
// Dump the RT in 32 bits format. It helps to debug texture shuffle effect
s = StringUtil::StdStringFromFormat("%05d_f%lld_rt1_%05x_32bits.bmp", s_n, frame, m_context->FRAME.Block());
m_mem.SaveBMP(s_dump_root + s, m_context->FRAME.Block(), m_context->FRAME.FBW, 0, GetFrameRect().width(), 512);
s = GetDrawDumpPath("%05d_f%lld_rt1_%05x_32bits.bmp", s_n, frame, m_context->FRAME.Block());
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, 0, GetFrameRect().width(), 512);
}
s = StringUtil::StdStringFromFormat("%05d_f%lld_rt1_%05x_%s.bmp", s_n, frame, m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
m_mem.SaveBMP(s_dump_root + s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameRect().width(), 512);
s = GetDrawDumpPath("%05d_f%lld_rt1_%05x_%s.bmp", s_n, frame, m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameRect().width(), 512);
}
if (GSConfig.SaveDepth && s_n >= GSConfig.SaveN)
{
s = StringUtil::StdStringFromFormat("%05d_f%lld_rz1_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
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_dump_root + s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameRect().width(), 512);
m_mem.SaveBMP(s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameRect().width(), 512);
}
if (GSConfig.SaveL > 0 && (s_n - GSConfig.SaveN) > GSConfig.SaveL)
@ -606,16 +604,16 @@ void GSRendererSW::Sync(int reason)
if (GSConfig.SaveRT)
{
s = StringUtil::StdStringFromFormat("%05d_f%lld_rt1_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
s = GetDrawDumpPath("%05d_f%lld_rt1_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
m_mem.SaveBMP(s_dump_root + s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameRect().width(), 512);
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameRect().width(), 512);
}
if (GSConfig.SaveDepth)
{
s = StringUtil::StdStringFromFormat("%05d_f%lld_zb1_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
s = GetDrawDumpPath("%05d_f%lld_zb1_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
m_mem.SaveBMP(s_dump_root + s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameRect().width(), 512);
m_mem.SaveBMP(s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameRect().width(), 512);
}
}
@ -1583,9 +1581,9 @@ void GSRendererSW::SharedData::UpdateSource()
{
const GIFRegTEX0& TEX0 = g_gs_renderer->GetTex0Layer(i);
s = StringUtil::StdStringFromFormat("%05d_f%lld_itex%d_%05x_%s.bmp", g_gs_renderer->s_n, frame, i, TEX0.TBP0, psm_str(TEX0.PSM));
s = GetDrawDumpPath("%05d_f%lld_itex%d_%05x_%s.bmp", g_gs_renderer->s_n, frame, i, TEX0.TBP0, psm_str(TEX0.PSM));
m_tex[i].t->Save(root_sw + s);
m_tex[i].t->Save(s);
}
if (global.clut != NULL)
@ -1594,9 +1592,9 @@ void GSRendererSW::SharedData::UpdateSource()
t->Update(GSVector4i(0, 0, 256, 1), global.clut, sizeof(u32) * 256);
s = StringUtil::StdStringFromFormat("%05d_f%lld_itexp_%05x_%s.bmp", g_gs_renderer->s_n, frame, (int)g_gs_renderer->m_context->TEX0.CBP, psm_str(g_gs_renderer->m_context->TEX0.CPSM));
s = GetDrawDumpPath("%05d_f%lld_itexp_%05x_%s.bmp", g_gs_renderer->s_n, frame, (int)g_gs_renderer->m_context->TEX0.CBP, psm_str(g_gs_renderer->m_context->TEX0.CPSM));
t->Save(root_sw + s);
t->Save(s);
delete t;
}

View File

@ -501,7 +501,10 @@ bool Pcsx2Config::GSOptions::OptionsAreEqual(const GSOptions& right) const
OpEqu(VideoCaptureCodec) &&
OpEqu(VideoCaptureBitrate) &&
OpEqu(Adapter));
OpEqu(Adapter) &&
OpEqu(HWDumpDirectory) &&
OpEqu(SWDumpDirectory));
}
bool Pcsx2Config::GSOptions::operator!=(const GSOptions& right) const
@ -703,6 +706,12 @@ void Pcsx2Config::GSOptions::ReloadIniSettings()
GSSettingIntEx(VideoCaptureBitrate, "VideoCaptureBitrate");
GSSettingString(Adapter);
GSSettingString(HWDumpDirectory);
if (!HWDumpDirectory.empty() && !Path::IsAbsolute(HWDumpDirectory))
HWDumpDirectory = Path::Combine(EmuFolders::DataRoot, HWDumpDirectory);
GSSettingString(SWDumpDirectory);
if (!SWDumpDirectory.empty() && !Path::IsAbsolute(SWDumpDirectory))
SWDumpDirectory = Path::Combine(EmuFolders::DataRoot, SWDumpDirectory);
#undef GSSettingInt
#undef GSSettingIntEx
@ -713,6 +722,16 @@ void Pcsx2Config::GSOptions::ReloadIniSettings()
#undef GSSettingIntEnumEx
#undef GSSettingString
#undef GSSettingStringEx
#ifdef PCSX2_CORE
// Sanity check: don't dump a bunch of crap in the current working directory.
const std::string& dump_dir = UseHardwareRenderer() ? HWDumpDirectory : SWDumpDirectory;
if (DumpGSData && dump_dir.empty())
{
Console.Error("Draw dumping is enabled but directory is unconfigured, please set one.");
DumpGSData = false;
}
#endif
}
void Pcsx2Config::GSOptions::MaskUserHacks()