pcsx2/pcsx2-gsrunner/test_run_dumps.py

107 lines
3.8 KiB
Python
Raw Permalink Normal View History

import argparse
import glob
import sys
import os
import subprocess
import multiprocessing
from pathlib import Path
from functools import partial
def get_gs_name(path):
lpath = path.lower()
for extension in [".gs", ".gs.xz", ".gs.zst"]:
if lpath.endswith(extension):
return os.path.basename(path)[:-len(extension)]
return None
2023-03-05 06:04:29 +00:00
def run_regression_test(runner, dumpdir, renderer, upscale, renderhacks, parallel, gspath):
args = [runner]
gsname = get_gs_name(gspath)
real_dumpdir = os.path.join(dumpdir, gsname).strip()
if not os.path.exists(real_dumpdir):
os.mkdir(real_dumpdir)
2023-07-20 08:37:36 +00:00
else:
return
if renderer is not None:
args.extend(["-renderer", renderer])
2023-03-05 06:04:29 +00:00
if upscale != 1.0:
args.extend(["-upscale", str(upscale)])
if renderhacks is not None:
args.extend(["-renderhacks", renderhacks])
args.extend(["-dumpdir", real_dumpdir])
args.extend(["-logfile", os.path.join(real_dumpdir, "emulog.txt")])
# loop a couple of times for those stubborn merge/interlace dumps that don't render anything
# the first time around
args.extend(["-loop", "2"])
# disable shader cache for parallel runs, otherwise it'll have sharing violations
if parallel > 1:
args.append("-noshadercache")
# run surfaceless, we don't want tons of windows popping up
args.append("-surfaceless");
2023-03-07 15:15:04 +00:00
# disable output console entirely
environ = os.environ.copy()
environ["PCSX2_NOCONSOLE"] = "1"
args.append("--")
args.append(gspath)
2023-03-07 15:15:04 +00:00
#print("Running '%s'" % (" ".join(args)))
subprocess.run(args, env=environ, stdin=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
2023-03-05 06:04:29 +00:00
def run_regression_tests(runner, gsdir, dumpdir, renderer, upscale, renderhacks, parallel=1):
paths = glob.glob(gsdir + "/*.*", recursive=True)
gamepaths = list(filter(lambda x: get_gs_name(x) is not None, paths))
if not os.path.isdir(dumpdir):
os.mkdir(dumpdir)
print("Found %u GS dumps" % len(gamepaths))
if parallel <= 1:
for game in gamepaths:
2023-03-05 06:04:29 +00:00
run_regression_test(runner, dumpdir, renderer, upscale, renderhacks, parallel, game)
else:
print("Processing %u games on %u processors" % (len(gamepaths), parallel))
2023-03-05 06:04:29 +00:00
func = partial(run_regression_test, runner, dumpdir, renderer, upscale, renderhacks, parallel)
pool = multiprocessing.Pool(parallel)
2023-03-07 15:15:04 +00:00
completed = 0
for _ in pool.imap_unordered(func, gamepaths, chunksize=1):
completed += 1
print("Processed %u of %u GS dumps (%u%%)" % (completed, len(gamepaths), (completed * 100) // len(gamepaths)))
pool.close()
return True
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Generate frame dump images for regression tests")
parser.add_argument("-runner", action="store", required=True, help="Path to PCSX2 GS runner")
parser.add_argument("-gsdir", action="store", required=True, help="Directory containing GS dumps")
parser.add_argument("-dumpdir", action="store", required=True, help="Base directory to dump frames to")
parser.add_argument("-renderer", action="store", required=False, help="Renderer to use")
2023-03-05 06:04:29 +00:00
parser.add_argument("-upscale", action="store", type=float, default=1, help="Upscaling multiplier to use")
parser.add_argument("-renderhacks", action="store", required=False, help="Enable HW Rendering hacks")
parser.add_argument("-parallel", action="store", type=int, default=1, help="Number of proceeses to run")
args = parser.parse_args()
2023-03-05 06:04:29 +00:00
if not run_regression_tests(args.runner, os.path.realpath(args.gsdir), os.path.realpath(args.dumpdir), args.renderer, args.upscale, args.renderhacks, args.parallel):
sys.exit(1)
else:
sys.exit(0)