Capturing a Graphics Frame with RenderDoc¶
RenderDoc is a frame debugger that provides detailed information about the API calls and pipeline state that produced a frame. It supports all major graphics APIs and can be used in any application that creates a window. This guide walks you through using RenderDoc to capture a frame from a libretro core running in libretro.py.
Important
This is not a tutorial for using RenderDoc; this guide assumes that you’re proficient enough to analyze a capture after you’ve taken it. See the official docs for more guidance.
In this guide we’ll use Mupen64Plus-Next to demonstrate, though any core will work.
Getting Started¶
We’ll use the provided libretro.py.runs script to run the core.
Make sure that you’ve installed the cli extra when you installed libretro.py.
This script is a simple way to run a core for fixed length of time.
Prefer to use a custom script?
You can use RenderDoc to capture a frame even if you’re using a custom test script. However, the process of configuring your core’s content, system files, and options may be different.
Once you install RenderDoc, open up the Launch Application tab and configure it like so:
- Executable Path
Select the Python executable you’re using to run libretro.py. If you’re using a virtual environment, see Using a Virtual Environment for more information.
- Working Directory
You can leave this as-is unless your core or custom test script expects a specific working directory.
- Command-line Arguments
Enter the following:
-m libretro.py.runs path-to-core path-to-content -Omupen64plus-rdp-plugin=gliden64 -n600 --windowLet’s break this down:
-m libretro.py.runsUsing Python’s
-mflag will run the given module as a script, in this case thelibretro.py.runsmodule included with libretro.py.path-to-coreReplace this with the path to the core you’re using. For the purpose of this guide, we’re using Mupen64Plus-Next; on my machine, that’s
D:/SteamLibrary/steamapps/common/RetroArch/cores/mupen64plus_next_libretro.dll.Important
This needs to be a full path, not a short name like RetroArch uses (i.e. passing an argument of
mupen64plus_nextwill not work unless that’s literally the name of a core in the current working directory).path-to-contentReplace this with the path to the content you’re running. For this guide, I’m using a ROM located at
D:/ROMs/N64/Super Mario 64 (U) [!].z64.Tip
If you’re using a core that supports running without content, you can leave this out. If you’re using a subsystem, you’ll need to include the subsystem name with the
-sflag, plus additional content files after the main one if necessary.-Omupen64plus-rdp-plugin=gliden64The
-Oflag defines an option that will be passed to the core. It can be given as many times as you like, with each value given as-Oname=value. In this case we’re telling Mupen64Plus-Next to use the GlideN64 renderer; we want to use this particular renderer because it uses OpenGL, which is the only graphics API that libretro.py supports at the moment.-n600The
-nflag tells libretro.py to run the core for a fixed number of frames. In this case, we’re running for 600 frames (about 10 seconds).--windowThis flag tells
libretro.pyto create a window for the core to render to. This is necessary for RenderDoc to capture the frame.
See
herefor more details about available flags.- Environment Variables
You can leave this blank unless your core or custom script expects specific environment variables.
If you’re using a virtual environment, see Using a Virtual Environment for more information.
Taking a Capture¶
Now that we’ve got our capture settings for RenderDoc in place, we can run the core and take a capture. You’ll want to save your capture settings to avoid having to retype them later, but make sure not to commit them to your Git repo.
You can either take a capture with the F12 key or queue up one or more captures to be taken automatically.
Hint
Why not use RetroArch for capturing frames instead?
You absolutely can! However, frontends intended for gameplay tend to allocate their own graphics resources for features like UI overlays or shader effects. You may find these to be a distraction when trying to debug your core. libretro.py only allocates the resources needed to support GPU-rendered cores.
Using a Virtual Environment¶
Using libretro.py through a virtual environment to capture frames is supported, but may require a few extra steps depending on your platform. The following recommendations come from my own experience using RenderDoc and libretro.py on Windows, but may apply to other platforms as well.
You may need to do one or both of the following:
1. Set the Executable Path to the Python executable from which your virtual environment is derived, not the executable in the virtual environment itself. On Windows, this is actually a thin launcher for the system Python installation with some environment variables set to point to the virtual environment.
2. Add PYTHONPATH to the Environment Variables field,
set to the location of the virtual environment’s site-packages directory.
If you’re using a local copy of libretro.py (e.g. when contributing or fixing a bug),
you may also need to include the path to the directory containing libretro.py itself.