Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions pcsx2-gsrunner/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,8 +473,8 @@ 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|tr]: Enabling dumping of render target, texture, z buffer, frame, "
"alphas, and info (context, vertices, transfers (list)), transfers (images), respectively, per draw. Generates lots of data.\n");
std::fprintf(stderr, " -dump [rt|tex|z|f|a|i|tr|ds|fs]: Enabling dumping of render target, texture, z buffer, frame, "
"alphas, and info (context, vertices, list of transfers), transfers images, draw stats, frame stats, 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 -dumprangef used)."
"Defaults to 0,-1,1 (all draws). Only used if -dump used.\n");
Expand Down Expand Up @@ -560,6 +560,10 @@ bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& pa
s_settings_interface.SetBoolValue("EmuCore/GS", "SaveInfo", true);
if (str.find("tr") != std::string::npos)
s_settings_interface.SetBoolValue("EmuCore/GS", "SaveTransferImages", true);
if (str.find("ds") != std::string::npos)
s_settings_interface.SetBoolValue("EmuCore/GS", "SaveDrawStats", true);
if (str.find("fs") != std::string::npos)
s_settings_interface.SetBoolValue("EmuCore/GS", "SaveFrameStats", true);
continue;
}
else if (CHECK_ARG_PARAM("-dumprange"))
Expand Down
16 changes: 15 additions & 1 deletion pcsx2-qt/Settings/DebugGSSettingsTab.ui
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,21 @@
</property>
</widget>
</item>
<item row="4" column="0">
<item row="4" column="0">
<widget class="QCheckBox" name="saveDrawStats">
<property name="text">
<string>Save Draw Stats</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="saveFrameStats">
<property name="text">
<string>Save Frame Stats</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="saveTransferImages">
<property name="text">
<string>Save Transfer Image Data</string>
Expand Down
4 changes: 4 additions & 0 deletions pcsx2-qt/Settings/DebugSettingsWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ DebugSettingsWidget::DebugSettingsWidget(SettingsWindow* settings_dialog, QWidge
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_gs.saveAlpha, "EmuCore/GS", "SaveAlpha", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_gs.saveInfo, "EmuCore/GS", "SaveInfo", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_gs.saveTransferImages, "EmuCore/GS", "SaveTransferImages", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_gs.saveDrawStats, "EmuCore/GS", "SaveDrawStats", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_gs.saveFrameStats, "EmuCore/GS", "SaveFrameStats", false);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_gs.saveDrawStart, "EmuCore/GS", "SaveDrawStart", 0);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_gs.saveDrawCount, "EmuCore/GS", "SaveDrawCount", 5000);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_gs.saveFrameStart, "EmuCore/GS", "SaveFrameStart", 0);
Expand Down Expand Up @@ -215,6 +217,8 @@ void DebugSettingsWidget::onDrawDumpingChanged()
m_gs.saveAlpha->setEnabled(enabled);
m_gs.saveInfo->setEnabled(enabled);
m_gs.saveTransferImages->setEnabled(enabled);
m_gs.saveDrawStats->setEnabled(enabled);
m_gs.saveFrameStats->setEnabled(enabled);
m_gs.saveDrawStart->setEnabled(enabled);
m_gs.saveDrawCount->setEnabled(enabled);
m_gs.saveFrameStart->setEnabled(enabled);
Expand Down
2 changes: 2 additions & 0 deletions pcsx2/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,8 @@ struct Pcsx2Config
SaveAlpha : 1,
SaveInfo : 1,
SaveTransferImages : 1,
SaveDrawStats : 1,
SaveFrameStats : 1,
DumpReplaceableTextures : 1,
DumpReplaceableMipmaps : 1,
DumpTexturesWithFMVActive : 1,
Expand Down
27 changes: 27 additions & 0 deletions pcsx2/GS/GSPerfMon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

#include "GSPerfMon.h"
#include "GS.h"
#include "GSUtil.h"

#include <cstring>
#include <inttypes.h>

GSPerfMon g_perfmon;

Expand Down Expand Up @@ -41,3 +43,28 @@ void GSPerfMon::Update()

memset(m_counters, 0, sizeof(m_counters));
}

GSPerfMon GSPerfMon::operator-(const GSPerfMon& other)
{
GSPerfMon diff;
for (std::size_t i = 0; i < std::size(diff.m_counters); i++)
{
diff.m_counters[i] = m_counters[i] - other.m_counters[i];
}
return diff;
}

void GSPerfMon::Dump(const std::string& filename, bool hw)
{
FILE* fp = fopen(filename.c_str(), "w");
if (!fp)
return;

std::size_t last = hw ? CounterLastHW : CounterLastSW;
for (std::size_t i = 0; i < last; i++)
{
fprintf(fp, "%s: %" PRIu64 "\n", GSUtil::GetPerfMonCounterName(static_cast<counter_t>(i), hw), static_cast<u64>(m_counters[i]));
}

fclose(fp);
}
8 changes: 8 additions & 0 deletions pcsx2/GS/GSPerfMon.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "common/Pcsx2Defs.h"

#include <ctime>
#include <string>

class GSPerfMon
{
Expand All @@ -27,6 +28,9 @@ class GSPerfMon
// Reused counters for HW.
TextureCopies = Fillrate,
TextureUploads = SyncPoint,

CounterLastHW = CounterLast,
CounterLastSW = SyncPoint + 1
};

protected:
Expand Down Expand Up @@ -58,6 +62,10 @@ class GSPerfMon
m_disp_fb_sprite_blits = 0;
return blits;
}

GSPerfMon operator-(const GSPerfMon& other);

void Dump(const std::string& filename, bool hw);
};

extern GSPerfMon g_perfmon;
13 changes: 13 additions & 0 deletions pcsx2/GS/GSState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ void GSState::Reset(bool hardware_reset)
m_backed_up_ctx = -1;

memcpy(&m_prev_env, &m_env, sizeof(m_prev_env));

m_perfmon_draw.Reset();
m_perfmon_frame.Reset();
}

template<bool auto_flush>
Expand Down Expand Up @@ -2125,6 +2128,16 @@ void GSState::FlushPrim()
g_perfmon.Put(GSPerfMon::Draw, 1);
g_perfmon.Put(GSPerfMon::Prim, m_index.tail / GSUtil::GetVertexCount(PRIM->PRIM));

if (GSConfig.ShouldDump(s_n, g_perfmon.GetFrame()))
{
if (GSConfig.SaveDrawStats)
{
m_perfmon_draw = g_perfmon - m_perfmon_draw;
m_perfmon_draw.Dump(GetDrawDumpPath("%05d_draw_stats.txt", s_n), GSIsHardwareRenderer());
m_perfmon_draw = g_perfmon;
}
}

m_index.tail = 0;
m_vertex.head = 0;

Expand Down
4 changes: 4 additions & 0 deletions pcsx2/GS/GSState.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include "GS/GS.h"
#include "GS/GSPerfMon.h"
#include "GS/GSLocalMemory.h"
#include "GS/GSDrawingContext.h"
#include "GS/GSDrawingEnvironment.h"
Expand Down Expand Up @@ -262,6 +263,9 @@ class GSState : public GSAlignedClass<32>
static int s_last_transfer_draw_n;
static int s_transfer_n;

GSPerfMon m_perfmon_frame; // Track stat across a frame.
GSPerfMon m_perfmon_draw; // Track stat across a draw.

static constexpr u32 STATE_VERSION = 9;

enum REG_DIRTY
Expand Down
34 changes: 34 additions & 0 deletions pcsx2/GS/GSUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,40 @@ const char* GSUtil::GetACName(u32 ac)
return (ac < std::size(names)) ? names[ac] : "";
}

const char* GSUtil::GetPerfMonCounterName(GSPerfMon::counter_t counter, bool hw)
{
if (hw)
{
static constexpr const char* names_hw[GSPerfMon::CounterLastHW] = {
"Prim",
"Draw",
"DrawCalls",
"Readbacks",
"Swizzle",
"Unswizzle",
"TextureCopies",
"TextureUploads",
"Barriers",
"RenderPasses"
};
return counter < std::size(names_hw) ? names_hw[counter] : "";
}
else
{
static constexpr const char* names_sw[GSPerfMon::CounterLastSW] = {
"Prim",
"Draw",
"DrawCalls",
"Readbacks",
"Swizzle",
"Unswizzle",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the swizzle/unswizzle stuff relevant to sw as well?

"Fillrate",
"SyncPoint"
};
return counter < std::size(names_sw) ? names_sw[counter] : "";
}
}

const u32* GSUtil::HasSharedBitsPtr(u32 dpsm)
{
return s_maps.SharedBitsField[dpsm];
Expand Down
2 changes: 2 additions & 0 deletions pcsx2/GS/GSUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "GS.h"
#include "GSRegs.h"
#include "GSPerfMon.h"

class GSUtil
{
Expand All @@ -25,6 +26,7 @@ class GSUtil
static const char* GetTFXName(u32 tfx);
static const char* GetTCCName(u32 tcc);
static const char* GetACName(u32 ac);
static const char* GetPerfMonCounterName(GSPerfMon::counter_t counter, bool hw = true);

static const u32* HasSharedBitsPtr(u32 dpsm);
static bool HasSharedBits(u32 spsm, const u32* ptr);
Expand Down
7 changes: 7 additions & 0 deletions pcsx2/GS/Renderers/Common/GSRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,13 @@ void GSRenderer::VSync(u32 field, bool registers_written, bool idle_frame)

if (GSConfig.SaveTransferImages)
DumpTransferImages();

if (GSConfig.SaveFrameStats)
{
m_perfmon_frame = g_perfmon - m_perfmon_frame;
m_perfmon_frame.Dump(GetDrawDumpPath("%05d_f%05lld_frame_stats.txt", s_n, g_perfmon.GetFrame()), GSIsHardwareRenderer());
m_perfmon_frame = g_perfmon;
}
}

const int fb_sprite_blits = g_perfmon.GetDisplayFramebufferSpriteBlits();
Expand Down
2 changes: 2 additions & 0 deletions pcsx2/Pcsx2Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,8 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
SettingsWrapBitBoolEx(SaveAlpha, "SaveAlpha");
SettingsWrapBitBoolEx(SaveInfo, "SaveInfo");
SettingsWrapBitBoolEx(SaveTransferImages, "SaveTransferImages");
SettingsWrapBitBoolEx(SaveDrawStats, "SaveDrawStats");
SettingsWrapBitBoolEx(SaveFrameStats, "SaveFrameStats");
SettingsWrapBitBool(DumpReplaceableTextures);
SettingsWrapBitBool(DumpReplaceableMipmaps);
SettingsWrapBitBool(DumpTexturesWithFMVActive);
Expand Down