mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-12 10:37:08 +00:00
7149302680
* There's not a good accepted terminology for this kind of event, and for historical reasons 'drawcall' has been the accepted term, even though that can be quite confusing when a dispatch or a copy is a 'drawcall'. * This is particularly highlighted by the event browser filters where $draw() includes draws and dispatches, but $dispatch() only includes dispatches, it's hard to intuitively understand why $draw() matches all of these calls. * As a result we've defined the term 'action' to cover these types of events in the same way that we defined 'event' in the first place to mean a single atomic API call.
353 lines
9.5 KiB
C++
353 lines
9.5 KiB
C++
/******************************************************************************
|
|
* The MIT License (MIT)
|
|
*
|
|
* Copyright (c) 2019-2021 Baldur Karlsson
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
******************************************************************************/
|
|
|
|
#include <string.h>
|
|
#include "api/app/renderdoc_app.h"
|
|
#include "api/replay/apidefs.h" // for RENDERDOC_API to export the RENDERDOC_GetAPI function
|
|
#include "common/common.h"
|
|
#include "common/formatting.h"
|
|
#include "core/core.h"
|
|
#include "hooks/hooks.h"
|
|
#include "serialise/rdcfile.h"
|
|
|
|
static void SetFocusToggleKeys(RENDERDOC_InputButton *keys, int num)
|
|
{
|
|
RenderDoc::Inst().SetFocusKeys(keys, num);
|
|
}
|
|
|
|
static void SetCaptureKeys(RENDERDOC_InputButton *keys, int num)
|
|
{
|
|
RenderDoc::Inst().SetCaptureKeys(keys, num);
|
|
}
|
|
|
|
static uint32_t GetOverlayBits()
|
|
{
|
|
return RenderDoc::Inst().GetOverlayBits();
|
|
}
|
|
|
|
static void MaskOverlayBits(uint32_t And, uint32_t Or)
|
|
{
|
|
RenderDoc::Inst().MaskOverlayBits(And, Or);
|
|
}
|
|
|
|
static void RemoveHooks()
|
|
{
|
|
RenderDoc::Inst().RemoveHooks();
|
|
LibraryHooks::RemoveHooks();
|
|
}
|
|
|
|
static void UnloadCrashHandler()
|
|
{
|
|
RenderDoc::Inst().UnloadCrashHandler();
|
|
}
|
|
|
|
static void SetCaptureFilePathTemplate(const char *pathtemplate)
|
|
{
|
|
RDCLOG("Using capture file template %s", pathtemplate);
|
|
RenderDoc::Inst().SetCaptureFileTemplate(pathtemplate);
|
|
}
|
|
|
|
static const char *GetCaptureFilePathTemplate()
|
|
{
|
|
return RenderDoc::Inst().GetCaptureFileTemplate();
|
|
}
|
|
|
|
static uint32_t GetNumCaptures()
|
|
{
|
|
return (uint32_t)RenderDoc::Inst().GetCaptures().size();
|
|
}
|
|
|
|
static uint32_t GetCapture(uint32_t idx, char *filename, uint32_t *pathlength, uint64_t *timestamp)
|
|
{
|
|
rdcarray<CaptureData> caps = RenderDoc::Inst().GetCaptures();
|
|
|
|
if(idx >= (uint32_t)caps.size())
|
|
{
|
|
if(filename)
|
|
filename[0] = 0;
|
|
if(pathlength)
|
|
*pathlength = 0;
|
|
if(timestamp)
|
|
*timestamp = 0;
|
|
return 0;
|
|
}
|
|
|
|
CaptureData &c = caps[idx];
|
|
|
|
if(filename)
|
|
memcpy(filename, c.path.c_str(), sizeof(char) * (c.path.size() + 1));
|
|
if(pathlength)
|
|
*pathlength = uint32_t(c.path.size() + 1);
|
|
if(timestamp)
|
|
*timestamp = c.timestamp;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static void SetCaptureFileComments(const char *filePath, const char *comments)
|
|
{
|
|
rdcstr path;
|
|
if(filePath == NULL || filePath[0] == 0)
|
|
{
|
|
rdcarray<CaptureData> caps = RenderDoc::Inst().GetCaptures();
|
|
if(caps.empty())
|
|
{
|
|
RDCERR(
|
|
"SetCaptureFileComments called with NULL/empty filePath, but no captures have been made");
|
|
return;
|
|
}
|
|
|
|
path = caps.back().path;
|
|
}
|
|
else
|
|
{
|
|
path = filePath;
|
|
}
|
|
|
|
RDCFile rdc;
|
|
rdc.Open(path);
|
|
if(rdc.ErrorCode() != ContainerError::NoError)
|
|
{
|
|
RDCERR("Error opening '%s' to add capture comments", path.c_str());
|
|
return;
|
|
}
|
|
|
|
SectionProperties props;
|
|
props.type = SectionType::Notes;
|
|
props.version = 1;
|
|
|
|
StreamWriter *writer = rdc.WriteSection(props);
|
|
|
|
if(comments)
|
|
{
|
|
rdcstr commentsjson = "{\"comments\":\"";
|
|
|
|
commentsjson.reserve(strlen(comments));
|
|
|
|
const char *c = comments;
|
|
|
|
while(*c)
|
|
{
|
|
// escape some characters
|
|
if(*c == '"')
|
|
commentsjson += "\\\"";
|
|
else if(*c == '\\')
|
|
commentsjson += "\\\\";
|
|
else if(*c == '\b')
|
|
commentsjson += "\\b";
|
|
else if(*c == '\f')
|
|
commentsjson += "\\f";
|
|
else if(*c == '\n')
|
|
commentsjson += "\\n";
|
|
else if(*c == '\r')
|
|
commentsjson += "\\r";
|
|
else if(*c == '\t')
|
|
commentsjson += "\\t";
|
|
else
|
|
commentsjson.push_back(*c);
|
|
|
|
c++;
|
|
}
|
|
|
|
commentsjson += "\"}";
|
|
|
|
writer->Write(commentsjson.c_str(), commentsjson.size());
|
|
}
|
|
|
|
delete writer;
|
|
}
|
|
|
|
static void TriggerCapture()
|
|
{
|
|
RenderDoc::Inst().TriggerCapture(1);
|
|
}
|
|
|
|
static void TriggerMultiFrameCapture(uint32_t numFrames)
|
|
{
|
|
RenderDoc::Inst().TriggerCapture(numFrames);
|
|
}
|
|
|
|
static uint32_t IsTargetControlConnected()
|
|
{
|
|
return RenderDoc::Inst().IsTargetControlConnected();
|
|
}
|
|
|
|
static uint32_t LaunchReplayUI(uint32_t connectTargetControl, const char *cmdline)
|
|
{
|
|
rdcstr replayapp = FileIO::GetReplayAppFilename();
|
|
|
|
if(replayapp.empty())
|
|
return 0;
|
|
|
|
rdcstr cmd = cmdline ? cmdline : "";
|
|
if(connectTargetControl)
|
|
cmd += StringFormat::Fmt(" --targetcontrol localhost:%u",
|
|
RenderDoc::Inst().GetTargetControlIdent());
|
|
|
|
return Process::LaunchProcess(replayapp, "", cmd, false);
|
|
}
|
|
|
|
static void SetActiveWindow(void *device, void *wndHandle)
|
|
{
|
|
RenderDoc::Inst().SetActiveWindow(device, wndHandle);
|
|
}
|
|
|
|
static void StartFrameCapture(void *device, void *wndHandle)
|
|
{
|
|
RenderDoc::Inst().StartFrameCapture(device, wndHandle);
|
|
|
|
if(device == NULL || wndHandle == NULL)
|
|
RenderDoc::Inst().MatchClosestWindow(device, wndHandle);
|
|
|
|
if(device != NULL && wndHandle != NULL)
|
|
RenderDoc::Inst().SetActiveWindow(device, wndHandle);
|
|
}
|
|
|
|
static uint32_t IsFrameCapturing()
|
|
{
|
|
return RenderDoc::Inst().IsFrameCapturing() ? 1 : 0;
|
|
}
|
|
|
|
static uint32_t EndFrameCapture(void *device, void *wndHandle)
|
|
{
|
|
return RenderDoc::Inst().EndFrameCapture(device, wndHandle) ? 1 : 0;
|
|
}
|
|
|
|
static uint32_t DiscardFrameCapture(void *device, void *wndHandle)
|
|
{
|
|
return RenderDoc::Inst().DiscardFrameCapture(device, wndHandle) ? 1 : 0;
|
|
}
|
|
|
|
// defined in capture_options.cpp
|
|
int RENDERDOC_CC SetCaptureOptionU32(RENDERDOC_CaptureOption opt, uint32_t val);
|
|
int RENDERDOC_CC SetCaptureOptionF32(RENDERDOC_CaptureOption opt, float val);
|
|
uint32_t RENDERDOC_CC GetCaptureOptionU32(RENDERDOC_CaptureOption opt);
|
|
float RENDERDOC_CC GetCaptureOptionF32(RENDERDOC_CaptureOption opt);
|
|
|
|
void RENDERDOC_CC GetAPIVersion_1_4_2(int *major, int *minor, int *patch)
|
|
{
|
|
if(major)
|
|
*major = 1;
|
|
if(minor)
|
|
*minor = 4;
|
|
if(patch)
|
|
*patch = 2;
|
|
}
|
|
|
|
RENDERDOC_API_1_4_2 api_1_4_2;
|
|
void Init_1_4_2()
|
|
{
|
|
RENDERDOC_API_1_4_2 &api = api_1_4_2;
|
|
|
|
api.GetAPIVersion = &GetAPIVersion_1_4_2;
|
|
|
|
api.SetCaptureOptionU32 = &SetCaptureOptionU32;
|
|
api.SetCaptureOptionF32 = &SetCaptureOptionF32;
|
|
|
|
api.GetCaptureOptionU32 = &GetCaptureOptionU32;
|
|
api.GetCaptureOptionF32 = &GetCaptureOptionF32;
|
|
|
|
api.SetFocusToggleKeys = &SetFocusToggleKeys;
|
|
api.SetCaptureKeys = &SetCaptureKeys;
|
|
|
|
api.GetOverlayBits = &GetOverlayBits;
|
|
api.MaskOverlayBits = &MaskOverlayBits;
|
|
|
|
api.RemoveHooks = &RemoveHooks;
|
|
api.UnloadCrashHandler = &UnloadCrashHandler;
|
|
|
|
api.SetCaptureFilePathTemplate = &SetCaptureFilePathTemplate;
|
|
api.GetCaptureFilePathTemplate = &GetCaptureFilePathTemplate;
|
|
|
|
api.GetNumCaptures = &GetNumCaptures;
|
|
api.GetCapture = &GetCapture;
|
|
|
|
api.TriggerCapture = &TriggerCapture;
|
|
|
|
api.IsTargetControlConnected = &IsTargetControlConnected;
|
|
api.LaunchReplayUI = &LaunchReplayUI;
|
|
|
|
api.SetActiveWindow = &SetActiveWindow;
|
|
|
|
api.StartFrameCapture = &StartFrameCapture;
|
|
api.IsFrameCapturing = &IsFrameCapturing;
|
|
api.EndFrameCapture = &EndFrameCapture;
|
|
|
|
api.TriggerMultiFrameCapture = &TriggerMultiFrameCapture;
|
|
|
|
api.SetCaptureFileComments = &SetCaptureFileComments;
|
|
|
|
api.DiscardFrameCapture = &DiscardFrameCapture;
|
|
}
|
|
|
|
extern "C" RENDERDOC_API int RENDERDOC_CC RENDERDOC_GetAPI(RENDERDOC_Version version,
|
|
void **outAPIPointers)
|
|
{
|
|
if(outAPIPointers == NULL)
|
|
{
|
|
RDCERR("Invalid call to RENDERDOC_GetAPI with NULL outAPIPointers");
|
|
return 0;
|
|
}
|
|
|
|
int ret = 0;
|
|
int major = 0, minor = 0, patch = 0;
|
|
|
|
rdcstr supportedVersions = "";
|
|
|
|
#define API_VERSION_HANDLE(enumver, actualver) \
|
|
supportedVersions += " " STRINGIZE(CONCAT(API_, enumver)); \
|
|
if(version == CONCAT(eRENDERDOC_API_Version_, enumver)) \
|
|
{ \
|
|
CONCAT(Init_, actualver)(); \
|
|
*outAPIPointers = &CONCAT(api_, actualver); \
|
|
CONCAT(api_, actualver).GetAPIVersion(&major, &minor, &patch); \
|
|
ret = 1; \
|
|
}
|
|
|
|
API_VERSION_HANDLE(1_0_0, 1_4_2);
|
|
API_VERSION_HANDLE(1_0_1, 1_4_2);
|
|
API_VERSION_HANDLE(1_0_2, 1_4_2);
|
|
API_VERSION_HANDLE(1_1_0, 1_4_2);
|
|
API_VERSION_HANDLE(1_1_1, 1_4_2);
|
|
API_VERSION_HANDLE(1_1_2, 1_4_2);
|
|
API_VERSION_HANDLE(1_2_0, 1_4_2);
|
|
API_VERSION_HANDLE(1_3_0, 1_4_2);
|
|
API_VERSION_HANDLE(1_4_0, 1_4_2);
|
|
API_VERSION_HANDLE(1_4_1, 1_4_2);
|
|
API_VERSION_HANDLE(1_4_2, 1_4_2);
|
|
|
|
#undef API_VERSION_HANDLE
|
|
|
|
if(ret)
|
|
{
|
|
RDCLOG("Initialising RenderDoc API version %d.%d.%d for requested version %d", major, minor,
|
|
patch, version);
|
|
return 1;
|
|
}
|
|
|
|
RDCERR("Unrecognised API version '%d'. Supported versions:%s", version, supportedVersions.c_str());
|
|
|
|
return 0;
|
|
}
|