Integrating RenderDoc for Unconventional Apps

RenderDoc is a fantastic tool to debug your graphics application, with broad support for many graphics APIs. Sometimes however it’s impossible for RenderDoc to figure out what you’re doing. Point in case: I was recently debugging some shader compiler issue, for which I’ve been using a small test harness which does one submission with one dispatch. That’s not how any game looks like, there is no real frame beginning nor end, and I really only care about capturing the dispatch, so how do I tell RenderDoc that’s what I’m up to?

Fortunately, this is fairly easy, thanks to the RenderDoc API. It requires only a few small code changes, no extra linking step, and does not impact anything else when RenderDoc is not used. What do we need to do? It’s fairly simple: If we’re running with RenderDoc enabled, the renderdoc.dll will be present, so we can query the API off that. We then use it to manually start/stop a capture. If you already read the API documentation then you’re probably all set, if you haven’t, please stay around 😊

It’s quite easy in practice, all you need is to get hold of the RenderDoc API pointer, and once you have it, use the API to control RenderDoc. For the API you need to include the <renderdoc_app.h> header (which is in your RenderDoc installation directory), from there on it’s smooth sailing:


RENDERDOC_API_1_0_0* GetRenderDocApi() 
{ 
    RENDERDOC_API_1_0_0* rdoc = nullptr; 
    HMODULE module = GetModuleHandleA("renderdoc.dll"); 

    if (module == NULL) 
    { 
        return nullptr; 
    } 

    pRENDERDOC_GetAPI getApi = nullptr;
    getApi = (pRENDERDOC_GetAPI)GetProcAddress(module, "RENDERDOC_GetAPI"); 

    if (getApi == nullptr) 
    {
        return nullptr;
    }
    
    if (getApi(eRENDERDOC_API_Version_1_0_0, (void**)&rdoc) != 1) 
    {
        return nullptr;
    } 

    return rdoc; 
}

This can be done any time in your application. Once you have your device ready, you can then trigger the capture using:


if (rdoc)
{
    rdoc->StartFrameCapture(nullptr, nullptr); 
}

and stop it using:


if (rdoc) 
{
    rdoc->EndFrameCapture(nullptr, nullptr); 
}

Note that if your app exists super-fast, like mine did – it only ran a few milliseconds — the UI may not keep up with it. An easy fix is to wait for a keypress before exiting. This is also just the start of what you can do with the RenderDoc API. Make sure to check the documentation for more details and advanced use cases!

Other content by Matthäus Chajdas

Matthäus Chajdas

Matthäus Chajdas

Matthäus Chajdas is a developer technology engineer at AMD. Links to third party sites, and references to third party trademarks, are provided for convenience and illustrative purposes only. Unless explicitly stated, AMD is not responsible for the contents of such links, and no third party endorsement of AMD or any of its products is implied.

Enjoy this blog post? If you found it useful, why not share it with other game developers?

You may also like...

Getting started: our software

New or fairly new to AMD’s tools, libraries, and effects? This is the best place to get started on GPUOpen!

Getting started: development and performance

Looking for tips on getting started with developing and/or optimizing your game, whether on AMD hardware or generally? We’ve got you covered!

If slide decks are what you’re after, you’ll find 100+ of our finest presentations here. Plus there’s a handy list of our product manuals!

Developer guides

Browse our developer guides, and find valuable advice on developing with AMD hardware, ray tracing, Vulkan, DirectX, UE4, and lots more.

Words not enough? How about pictures? How about moving pictures? We have some amazing videos to share with you!

The home of great performance and optimization advice for AMD RDNA™ 2 GPUs, AMD Ryzen™ CPUs, and so much more.

Product Blogs

Our handy product blogs will help you make good use of our tools, SDKs, and effects, as well as sharing the latest features with new releases.

Publications

Discover our published publications.