From 1d96ac2b05e65aba1f862ebc980c1eca0291f55b Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 2 Apr 2015 17:36:55 +0100 Subject: [PATCH] Simplify renderdoc_app.h to remove typedefs and dependency on stl --- renderdoc/api/app/renderdoc_app.h | 131 +++++++++++---------------- renderdoc/core/core.h | 2 +- renderdoc/hooks/linux_libentry.cpp | 10 +- renderdoc/os/linux/linux_process.cpp | 13 ++- renderdoc/os/win32/win32_process.cpp | 26 +++++- renderdoccmd/renderdoccmd.cpp | 13 ++- renderdoccmd/renderdoccmd_win32.cpp | 4 +- 7 files changed, 109 insertions(+), 90 deletions(-) diff --git a/renderdoc/api/app/renderdoc_app.h b/renderdoc/api/app/renderdoc_app.h index e2b428c55..36214c6bf 100644 --- a/renderdoc/api/app/renderdoc_app.h +++ b/renderdoc/api/app/renderdoc_app.h @@ -27,9 +27,6 @@ #include -typedef uint8_t byte; -typedef uint32_t bool32; - #ifdef WIN32 #ifdef RENDERDOC_EXPORTS @@ -55,9 +52,6 @@ typedef uint32_t bool32; #endif -#include -#include // istringstream/ostringstream used to avoid other dependencies - struct CaptureOptions { CaptureOptions() @@ -76,49 +70,63 @@ struct CaptureOptions // Whether or not to allow the application to enable vsync // - // Enabled - allows the application to enable or disable vsync at will - // Disabled - vsync is force disabled - bool32 AllowVSync; + // 1 - allows the application to enable or disable vsync at will + // 0 - vsync is force disabled + uint32_t AllowVSync; // Whether or not to allow the application to enable fullscreen // - // Enabled - allows the application to enable or disable fullscreen at will - // Disabled - fullscreen is force disabled - bool32 AllowFullscreen; + // 1 - allows the application to enable or disable fullscreen at will + // 0 - fullscreen is force disabled + uint32_t AllowFullscreen; - // Enables in-built API debugging features and records the results into the - // capture logfile, which is matched up with events on replay - bool32 DebugDeviceMode; + // 1 - in-built API debugging features and records the results into the + // capture logfile, which is matched up with events on replay + // 0 - no API debugging is enabled + uint32_t DebugDeviceMode; - // Captures callstacks for every API event during capture - bool32 CaptureCallstacks; + // 1 - Captures callstacks for every API event during capture + // 0 - no callstacks are captured + uint32_t CaptureCallstacks; - // Only captures callstacks for drawcall type API events. - // Ignored if CaptureCallstacks is disabled - bool32 CaptureCallstacksOnlyDraws; + // 1 - Only captures callstacks for drawcall type API events. + // Ignored if CaptureCallstacks is disabled + // 0 - Callstacks, if enabled, are captured for every event. + uint32_t CaptureCallstacksOnlyDraws; // Specify a delay in seconds to wait for a debugger to attach after // creating or injecting into a process, before continuing to allow it to run. + // 0 indicates no delay, and the process will run immediately after injection uint32_t DelayForDebugger; - // Verify any writes to mapped buffers, to check that they don't overwrite the - // bounds of the pointer returned. - bool32 VerifyMapWrites; + // 1 - Verify any writes to mapped buffers, to check that they don't overwrite the + // bounds of the pointer returned. + // 0 - No verification is performed, and overwriting bounds may cause crashes or + // corruption in RenderDoc + uint32_t VerifyMapWrites; - // Hooks any system API events that create child processes, and injects - // renderdoc into them recursively with the same options. - bool32 HookIntoChildren; + // 1 - Hooks any system API events that create child processes, and injects + // renderdoc into them recursively with the same options. + // 0 - Child processes are not hooked by RenderDoc + uint32_t HookIntoChildren; // By default renderdoc only includes resources in the final logfile necessary // for that frame, this allows you to override that behaviour // - // Enabled - all live resources at the time of capture are included in the log - // and available for inspection - // Disabled - only the resources referenced by the captured frame are included - bool32 RefAllResources; + // 1 - all live resources at the time of capture are included in the log + // and available for inspection + // 0 - only the resources referenced by the captured frame are included + uint32_t RefAllResources; - // By default renderdoc skips saving initial states for - bool32 SaveAllInitials; + // By default renderdoc skips saving initial states for resources where the + // previous contents don't appear to be used, assuming that writes before + // reads indicate previous contents aren't used. + // + // 1 - initial contents at the start of each captured frame are saved, even if + // they are later overwritten or cleared before being used. + // 0 - unless a read is detected, initial contents will not be saved and will + // appear as black or empty data. + uint32_t SaveAllInitials; // In APIs that allow for the recording of command lists to be replayed later, // renderdoc may choose to not capture command lists before a frame capture is @@ -126,48 +134,15 @@ struct CaptureOptions // and replayed many times will not be available and may cause a failure to // capture. // - // Enabled - All command lists are captured from the start of the application - // Disabled - Command lists are only captured if their recording begins during - // the period when a frame capture is in progress. - bool32 CaptureAllCmdLists; - -#ifdef __cplusplus - void FromString(std::string str) - { - std::istringstream iss(str); - - iss >> AllowFullscreen - >> AllowVSync - >> DebugDeviceMode - >> CaptureCallstacks - >> CaptureCallstacksOnlyDraws - >> DelayForDebugger - >> VerifyMapWrites - >> HookIntoChildren - >> RefAllResources - >> SaveAllInitials - >> CaptureAllCmdLists; - } - - std::string ToString() const - { - std::ostringstream oss; - - oss << AllowFullscreen << " " - << AllowVSync << " " - << DebugDeviceMode << " " - << CaptureCallstacks << " " - << CaptureCallstacksOnlyDraws << " " - << DelayForDebugger << " " - << VerifyMapWrites << " " - << HookIntoChildren << " " - << RefAllResources << " " - << SaveAllInitials << " " - << CaptureAllCmdLists << " "; - - return oss.str(); - } -#endif + // Note this is typically only true for APIs where multithreading is difficult + // or discouraged. Newer APIs like Vulkan and D3D12 will ignore this option and + // always capture all command lists since the API is heavily oriented around it, + // and the overheads have been reduced by API design. + // + // 1 - All command lists are captured from the start of the application + // 0 - Command lists are only captured if their recording begins during + // the period when a frame capture is in progress. + uint32_t CaptureAllCmdLists; }; enum KeyButton @@ -249,8 +224,8 @@ typedef void (RENDERDOC_CC *pRENDERDOC_SetLogFile)(const char *logfile); extern "C" RENDERDOC_API const char* RENDERDOC_CC RENDERDOC_GetLogFile(); typedef const char* (RENDERDOC_CC *pRENDERDOC_GetLogFile)(); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC RENDERDOC_GetCapture(uint32_t idx, char *logfile, uint32_t *pathlength, uint64_t *timestamp); -typedef bool32 (RENDERDOC_CC *pRENDERDOC_GetCapture)(uint32_t idx, char *logfile, uint32_t *pathlength, uint64_t *timestamp); +extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_GetCapture(uint32_t idx, char *logfile, uint32_t *pathlength, uint64_t *timestamp); +typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetCapture)(uint32_t idx, char *logfile, uint32_t *pathlength, uint64_t *timestamp); extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetCaptureOptions(const CaptureOptions *opts); typedef void (RENDERDOC_CC *pRENDERDOC_SetCaptureOptions)(const CaptureOptions *opts); @@ -264,8 +239,8 @@ typedef void (RENDERDOC_CC *pRENDERDOC_TriggerCapture)(); extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_StartFrameCapture(void *device, void *wndHandle); typedef void (RENDERDOC_CC *pRENDERDOC_StartFrameCapture)(void *device, void *wndHandle); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC RENDERDOC_EndFrameCapture(void *device, void *wndHandle); -typedef bool32 (RENDERDOC_CC *pRENDERDOC_EndFrameCapture)(void *device, void *wndHandle); +extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_EndFrameCapture(void *device, void *wndHandle); +typedef uint32_t (RENDERDOC_CC *pRENDERDOC_EndFrameCapture)(void *device, void *wndHandle); extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_GetOverlayBits(); typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetOverlayBits)(); diff --git a/renderdoc/core/core.h b/renderdoc/core/core.h index 671c126ee..3a13f8b11 100644 --- a/renderdoc/core/core.h +++ b/renderdoc/core/core.h @@ -176,7 +176,7 @@ class RenderDoc void SetReplayApp(bool replay) { m_Replay = replay; } bool IsReplayApp() const { return m_Replay; } - void BecomeReplayHost(volatile bool32 &killReplay); + void BecomeReplayHost(volatile uint32_t &killReplay); void SetCaptureOptions(const CaptureOptions *opts); const CaptureOptions &GetCaptureOptions() const { return m_Options; } diff --git a/renderdoc/hooks/linux_libentry.cpp b/renderdoc/hooks/linux_libentry.cpp index a59b557c8..0e0c6b355 100644 --- a/renderdoc/hooks/linux_libentry.cpp +++ b/renderdoc/hooks/linux_libentry.cpp @@ -26,6 +26,14 @@ #include "hooks/hooks.h" #include "os/os_specific.h" +void readCapOpts(const char *str, CaptureOptions *opts) +{ + // serialise from string with two chars per byte + byte *b = (byte *)opts; + for(size_t i=0; i < sizeof(CaptureOptions); i++) + *(b++) = (byte(str[i*2+0] - 'a') << 4) | byte(str[i*2+1] - 'a'); +} + // DllMain equivalent __attribute__((constructor)) void library_loaded() @@ -56,7 +64,7 @@ void library_loaded() string optstr = opts; CaptureOptions optstruct; - optstruct.FromString(optstr); + readCapOpts(optstr.c_str(), &optstruct); RenderDoc::Inst().SetCaptureOptions(&optstruct); } diff --git a/renderdoc/os/linux/linux_process.cpp b/renderdoc/os/linux/linux_process.cpp index 3f1dd9958..dc4b2c6da 100644 --- a/renderdoc/os/linux/linux_process.cpp +++ b/renderdoc/os/linux/linux_process.cpp @@ -133,7 +133,18 @@ uint32_t Process::CreateAndInjectIntoProcess(const char *app, const char *workin if(opts) { - string e = StringFormat::Fmt("RENDERDOC_CAPTUREOPTS=%s", opts->ToString().c_str()); + string optstr; + { + optstr.reserve(sizeof(CaptureOptions)*2+1); + byte *b = (byte *)opts; + for(size_t i=0; i < sizeof(CaptureOptions); i++) + { + optstr.push_back(char( 'a' + ((b[i] >> 4)&0xf) )); + optstr.push_back(char( 'a' + ((b[i] )&0xf) )); + } + } + + string e = StringFormat::Fmt("RENDERDOC_CAPTUREOPTS=%s", optstr.c_str()); envp[i] = new char[e.length()+1]; memcpy(envp[i], e.c_str(), e.length()+1); i++; diff --git a/renderdoc/os/win32/win32_process.cpp b/renderdoc/os/win32/win32_process.cpp index 331669954..04f3ca9e2 100644 --- a/renderdoc/os/win32/win32_process.cpp +++ b/renderdoc/os/win32/win32_process.cpp @@ -277,8 +277,18 @@ uint32_t Process::InjectIntoProcess(uint32_t pid, const char *logfile, const Cap tSec.nLength = sizeof(tSec); wchar_t *paramsAlloc = new wchar_t[2048]; - - string optstr = opts->ToString(); + + // serialise to string with two chars per byte + string optstr; + { + optstr.reserve(sizeof(CaptureOptions)*2+1); + byte *b = (byte *)opts; + for(size_t i=0; i < sizeof(CaptureOptions); i++) + { + optstr.push_back(char( 'a' + ((b[i] >> 4)&0xf) )); + optstr.push_back(char( 'a' + ((b[i] )&0xf) )); + } + } _snwprintf_s(paramsAlloc, 2047, 2047, L"\"%ls\" --cap32for64 %d \"%ls\" \"%hs\"", renderdocPath, pid, wlogfile.c_str(), optstr.c_str()); @@ -460,7 +470,17 @@ void Process::StartGlobalHook(const char *pathmatch, const char *logfile, const wchar_t *paramsAlloc = new wchar_t[2048]; - string optstr = opts->ToString(); + // serialise to string with two chars per byte + string optstr; + { + optstr.reserve(sizeof(CaptureOptions)*2+1); + byte *b = (byte *)opts; + for(size_t i=0; i < sizeof(CaptureOptions); i++) + { + optstr.push_back(char( 'a' + ((b[i] >> 4)&0xf) )); + optstr.push_back(char( 'a' + ((b[i] )&0xf) )); + } + } wstring wlogfile = logfile == NULL ? L"" : StringFormat::UTF82Wide(string(logfile)); wstring wpathmatch = StringFormat::UTF82Wide(string(pathmatch)); diff --git a/renderdoccmd/renderdoccmd.cpp b/renderdoccmd/renderdoccmd.cpp index fab931a93..f2ae6c820 100644 --- a/renderdoccmd/renderdoccmd.cpp +++ b/renderdoccmd/renderdoccmd.cpp @@ -70,6 +70,14 @@ bool argequal(const char *a, const char *b) return *a == 0 && *b == 0; } +void readCapOpts(const char *str, CaptureOptions *opts) +{ + // serialise from string with two chars per byte + byte *b = (byte *)opts; + for(size_t i=0; i < sizeof(CaptureOptions); i++) + *(b++) = (byte(str[i*2+0] - 'a') << 4) | byte(str[i*2+1] - 'a'); +} + // defined in platform .cpps void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay displayCfg); wstring GetUsername(); @@ -278,10 +286,7 @@ int renderdoccmd(int argc, char **argv) if(log[0] == 0) log = NULL; CaptureOptions cmdopts; - - string optstring(&argv[4][0], &argv[4][0] + strlen(argv[4])); - - cmdopts.FromString(optstring); + readCapOpts(argv[4], &cmdopts); return RENDERDOC_InjectIntoProcess(pidNum, log, &cmdopts, false); } diff --git a/renderdoccmd/renderdoccmd_win32.cpp b/renderdoccmd/renderdoccmd_win32.cpp index c4e584ec5..143a6a411 100644 --- a/renderdoccmd/renderdoccmd_win32.cpp +++ b/renderdoccmd/renderdoccmd_win32.cpp @@ -251,6 +251,7 @@ void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay displayCfg) int renderdoccmd(int argc, char **argv); bool argequal(const char *a, const char *b); +void readCapOpts(const char *str, CaptureOptions *opts); int WINAPI wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInstance, @@ -487,8 +488,7 @@ int WINAPI wWinMain(_In_ HINSTANCE hInst, wpathmatch.resize(wcslen(wpathmatch.c_str())); CaptureOptions cmdopts; - string optstring(&argv[4][0]); - cmdopts.FromString(optstring); + readCapOpts(argv[4], &cmdopts); // make sure the user doesn't accidentally run this with 'a' as a parameter or something. // "a.exe" is over 4 characters so this limit should not be a problem.