import argparse
import atexit
import os
import shutil
import sys
import tempfile
from pathlib import Path
TMP_DIR = tempfile.mkdtemp()
atexit.register(lambda: shutil.rmtree(TMP_DIR))
RENDERDOC_DEBUG_FILE = TMP_DIR + "/renderdoc.log"
os.environ['RENDERDOC_DEBUG_LOG_FILE'] = RENDERDOC_DEBUG_FILE
import renderdoc as rd
try:
from renderdoc import ResultCode
except ImportError:
from renderdoc import ReplayStatus as ResultCode
def load_capture(filename):
cap = rd.OpenCaptureFile()
status = cap.OpenFile(filename, '', None)
if status != ResultCode.Succeeded:
if os.path.exists(RENDERDOC_DEBUG_FILE):
print(open(RENDERDOC_DEBUG_FILE, "r").read(), file=sys.stderr)
raise RuntimeError("Couldn't open file: " + str(status))
if not cap.LocalReplaySupport():
raise RuntimeError("Capture cannot be replayed")
status, controller = cap.OpenCapture(rd.ReplayOptions(), None)
if status != ResultCode.Succeeded:
if os.path.exists(RENDERDOC_DEBUG_FILE):
print(open(RENDERDOC_DEBUG_FILE, "r").read(), file=sys.stderr)
raise RuntimeError("Couldn't initialise replay: " + str(status))
return cap, controller
def get_snapshot_action(controller):
try:
actions = list(controller.GetRootActions())
except AttributeError:
actions = list(controller.GetDrawcalls())
for action in reversed(actions):
if action.outputs[0] != rd.ResourceId.Null():
return action
raise RuntimeError("No action with color output found in capture")
def dump_snapshot(controller, action, output_path):
controller.SetFrameEvent(action.eventId, True)
texsave = rd.TextureSave()
texsave.resourceId = action.outputs[0]
texsave.mip = 0
texsave.slice.sliceIndex = 0
texsave.alpha = rd.AlphaMapping.Preserve
texsave.destType = rd.FileType.PNG
controller.SaveTexture(texsave, str(output_path))
print("Wrote " + str(output_path))
def main():
parser = argparse.ArgumentParser(
description='Dump snapshot images from a renderdoc capture')
parser.add_argument('file_path', help='path to the trace file')
parser.add_argument(
'output_dir', help='directory in which to place the results')
parser.add_argument('--loops', type=int, default=1,
help='number of snapshot captures (default 1)')
args = parser.parse_args()
rd.InitialiseReplay(rd.GlobalEnvironment(), [])
cap, controller = load_capture(args.file_path)
action = get_snapshot_action(controller)
output_dir = Path(args.output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
for i in range(args.loops):
output_path = output_dir / f"snapshot{i + 1:04d}.png"
dump_snapshot(controller, action, output_path)
cap.Shutdown()
rd.ShutdownReplay()
if __name__ == '__main__':
main()