mirror of https://github.com/PCSX2/pcsx2.git
GSRunner: Dump/compare stats
This commit is contained in:
parent
c59ea602c5
commit
d5776e8946
|
@ -13,6 +13,7 @@
|
|||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <csignal>
|
||||
#include <cstdlib>
|
||||
|
@ -39,6 +40,7 @@
|
|||
#include "pcsx2/Achievements.h"
|
||||
#include "pcsx2/CDVD/CDVD.h"
|
||||
#include "pcsx2/GS.h"
|
||||
#include "pcsx2/GS/GSPerfMon.h"
|
||||
#include "pcsx2/GSDumpReplayer.h"
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/INISettingsInterface.h"
|
||||
|
@ -57,6 +59,7 @@ namespace GSRunner
|
|||
static void InitializeConsole();
|
||||
static bool InitializeConfig();
|
||||
static bool ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& params);
|
||||
static void DumpStats();
|
||||
|
||||
static bool CreatePlatformWindow();
|
||||
static void DestroyPlatformWindow();
|
||||
|
@ -77,6 +80,12 @@ static bool s_no_console = false;
|
|||
// Owned by the GS thread.
|
||||
static u32 s_dump_frame_number = 0;
|
||||
static u32 s_loop_number = s_loop_count;
|
||||
static u64 s_total_draws = 0;
|
||||
static u64 s_total_render_passes = 0;
|
||||
static u64 s_total_barriers = 0;
|
||||
static u64 s_total_copies = 0;
|
||||
static u64 s_total_uploads = 0;
|
||||
static u32 s_total_frames = 0;
|
||||
|
||||
bool GSRunner::InitializeConfig()
|
||||
{
|
||||
|
@ -265,6 +274,17 @@ void Host::BeginPresentFrame()
|
|||
std::string dump_path(fmt::format("{}_frame{}.png", s_output_prefix, s_dump_frame_number));
|
||||
GSQueueSnapshot(dump_path);
|
||||
}
|
||||
|
||||
if (GSConfig.UseHardwareRenderer())
|
||||
{
|
||||
s_total_draws += static_cast<u64>(g_perfmon.GetCounter(GSPerfMon::DrawCalls));
|
||||
s_total_render_passes += static_cast<u64>(g_perfmon.GetCounter(GSPerfMon::RenderPasses));
|
||||
s_total_barriers += static_cast<u64>(g_perfmon.GetCounter(GSPerfMon::Barriers));
|
||||
s_total_copies += static_cast<u64>(g_perfmon.GetCounter(GSPerfMon::TextureCopies));
|
||||
s_total_uploads += static_cast<u64>(g_perfmon.GetCounter(GSPerfMon::TextureUploads));
|
||||
s_total_frames++;
|
||||
std::atomic_thread_fence(std::memory_order_release);
|
||||
}
|
||||
}
|
||||
|
||||
void Host::RequestResizeHostDisplay(s32 width, s32 height)
|
||||
|
@ -601,6 +621,18 @@ bool GSRunner::ParseCommandLineArgs(int argc, char* argv[], VMBootParameters& pa
|
|||
return true;
|
||||
}
|
||||
|
||||
void GSRunner::DumpStats()
|
||||
{
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
Console.WriteLn(fmt::format("======= HW STATISTICS FOR {} FRAMES ========", s_total_frames));
|
||||
Console.WriteLn(fmt::format("@HWSTAT@ Draw Calls: {} (avg {})", s_total_draws, static_cast<u64>(std::ceil(s_total_draws / static_cast<double>(s_total_frames)))));
|
||||
Console.WriteLn(fmt::format("@HWSTAT@ Render Passes: {} (avg {})", s_total_render_passes, static_cast<u64>(std::ceil(s_total_render_passes / static_cast<double>(s_total_frames)))));
|
||||
Console.WriteLn(fmt::format("@HWSTAT@ Barriers: {} (avg {})", s_total_barriers, static_cast<u64>(std::ceil(s_total_barriers / static_cast<double>(s_total_frames)))));
|
||||
Console.WriteLn(fmt::format("@HWSTAT@ Copies: {} (avg {})", s_total_copies, static_cast<u64>(std::ceil(s_total_copies / static_cast<double>(s_total_frames)))));
|
||||
Console.WriteLn(fmt::format("@HWSTAT@ Uploads: {} (avg {})", s_total_uploads, static_cast<u64>(std::ceil(s_total_uploads / static_cast<double>(s_total_frames)))));
|
||||
Console.WriteLn("============================================");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
GSRunner::InitializeConsole();
|
||||
|
@ -636,6 +668,7 @@ int main(int argc, char* argv[])
|
|||
while (VMManager::GetState() == VMState::Running)
|
||||
VMManager::Execute();
|
||||
VMManager::Shutdown(false);
|
||||
GSRunner::DumpStats();
|
||||
}
|
||||
|
||||
VMManager::Internal::CPUThreadShutdown();
|
||||
|
|
|
@ -39,6 +39,36 @@ def compare_frames(path1, path2):
|
|||
return False
|
||||
|
||||
|
||||
def extract_stats(file):
|
||||
stats = {}
|
||||
try:
|
||||
with open(file, "r") as f:
|
||||
for line in f.readlines():
|
||||
m = re.match(".*@HWSTAT@ ([^:]+): (.*) \(avg ([^)]+)\)$", line)
|
||||
if m is None:
|
||||
continue
|
||||
stats[m[1]] = int(m[3])
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
except IOError:
|
||||
pass
|
||||
return stats
|
||||
|
||||
|
||||
def compare_stats(baselinedir, testdir):
|
||||
stats1 = extract_stats(os.path.join(baselinedir, "emulog.txt"))
|
||||
stats2 = extract_stats(os.path.join(testdir, "emulog.txt"))
|
||||
res = []
|
||||
for statname in stats1.keys():
|
||||
if statname not in stats2 or stats1[statname] == stats2[statname]:
|
||||
continue
|
||||
v2 = stats2[statname]
|
||||
v1 = stats1[statname]
|
||||
delta = v2 - v1
|
||||
res.append("%s: %s%d [%d=>%d]" % (statname, "+" if delta > 0 else "", delta, v1, v2))
|
||||
return res
|
||||
|
||||
|
||||
def check_regression_test(baselinedir, testdir, name):
|
||||
#print("Checking '%s'..." % name)
|
||||
|
||||
|
@ -51,6 +81,7 @@ def check_regression_test(baselinedir, testdir, name):
|
|||
images = glob.glob(os.path.join(dir1, "*_frame*.png"))
|
||||
diff_frames = []
|
||||
first_fail = True
|
||||
stats = compare_stats(dir1, dir2)
|
||||
|
||||
for imagepath in images:
|
||||
imagename = Path(imagepath).name
|
||||
|
@ -85,9 +116,15 @@ def check_regression_test(baselinedir, testdir, name):
|
|||
write("</table>")
|
||||
write("<pre>Difference in frames [%s] for %s</pre>" % (",".join(map(str, diff_frames)), name))
|
||||
print("*** Difference in frames [%s] for %s" % (",".join(map(str, diff_frames)), name))
|
||||
return False
|
||||
if len(stats) > 0:
|
||||
write("<pre>%s</pre>" % "\n".join(stats))
|
||||
print(stats)
|
||||
elif len(stats) > 0:
|
||||
write("<h1>{}</h1>".format(name))
|
||||
write("<pre>%s</pre>" % "\n".join(stats))
|
||||
print(name, stats)
|
||||
|
||||
return True
|
||||
return len(diff_frames) == 0
|
||||
|
||||
|
||||
def check_regression_tests(baselinedir, testdir):
|
||||
|
@ -103,6 +140,8 @@ def check_regression_tests(baselinedir, testdir):
|
|||
else:
|
||||
failure += 1
|
||||
|
||||
print("%d dumps unchanged" % success)
|
||||
print("%d dumps changed" % failure)
|
||||
return (failure == 0)
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@ def run_regression_test(runner, dumpdir, renderer, upscale, renderhacks, paralle
|
|||
real_dumpdir = os.path.join(dumpdir, gsname).strip()
|
||||
if not os.path.exists(real_dumpdir):
|
||||
os.mkdir(real_dumpdir)
|
||||
else:
|
||||
return
|
||||
|
||||
if renderer is not None:
|
||||
args.extend(["-renderer", renderer])
|
||||
|
|
|
@ -55,6 +55,7 @@ public:
|
|||
void EndFrame();
|
||||
|
||||
void Put(counter_t c, double val) { m_counters[c] += val; }
|
||||
double GetCounter(counter_t c) { return m_counters[c]; }
|
||||
double Get(counter_t c) { return m_stats[c]; }
|
||||
void Update();
|
||||
|
||||
|
|
Loading…
Reference in New Issue