From d45e2450391fdfbe2ebd101808b2dd47f6ae0345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Thu, 11 Dec 2014 20:48:16 -0800 Subject: [PATCH] Updated RenderDoc to nightly 20141211. Added support for capturing OpenGL. --- 3rdparty/renderdoc/renderdoc_app.h | 36 +++---- src/renderdoc.cpp | 152 +++++++++++++++++++++++++++++ src/renderdoc.h | 11 +++ src/renderer_d3d11.cpp | 134 ------------------------- src/renderer_d3d11.h | 1 + src/renderer_gl.cpp | 11 +++ src/renderer_gl.h | 1 + 7 files changed, 191 insertions(+), 155 deletions(-) create mode 100644 src/renderdoc.cpp create mode 100644 src/renderdoc.h diff --git a/3rdparty/renderdoc/renderdoc_app.h b/3rdparty/renderdoc/renderdoc_app.h index c12430773..d06524096 100644 --- a/3rdparty/renderdoc/renderdoc_app.h +++ b/3rdparty/renderdoc/renderdoc_app.h @@ -61,7 +61,7 @@ struct CaptureOptions CaptureCallstacks(false), CaptureCallstacksOnlyDraws(false), DelayForDebugger(0), - CacheStateObjects(false), + VerifyMapWrites(false), HookIntoChildren(false), RefAllResources(false), SaveAllInitials(false), @@ -95,8 +95,9 @@ struct CaptureOptions // creating or injecting into a process, before continuing to allow it to run. uint32_t DelayForDebugger; - // Deprecated, ignored. - uint32_t CacheStateObjects; + // Verify any writes to mapped buffers, to check that they don't overwrite the + // bounds of the pointer returned. + uint32_t VerifyMapWrites; // Hooks any system API events that create child processes, and injects // renderdoc into them recursively with the same options. @@ -179,7 +180,9 @@ enum InAppOverlay eOverlay_None = 0, }; -#define RENDERDOC_API_VERSION 1 +// API breaking change history: +// Version 1 -> 2 - strings changed from wchar_t* to char* (UTF-8) +#define RENDERDOC_API_VERSION 2 ////////////////////////////////////////////////////////////////////////// // In-program functions @@ -188,14 +191,14 @@ enum InAppOverlay extern "C" RENDERDOC_API int RENDERDOC_CC RENDERDOC_GetAPIVersion(); typedef int (RENDERDOC_CC *pRENDERDOC_GetAPIVersion)(); -extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetLogFile(const wchar_t *logfile); -typedef void (RENDERDOC_CC *pRENDERDOC_SetLogFile)(const wchar_t *logfile); +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetLogFile(const char *logfile); +typedef void (RENDERDOC_CC *pRENDERDOC_SetLogFile)(const char *logfile); -extern "C" RENDERDOC_API const wchar_t* RENDERDOC_CC RENDERDOC_GetLogFile(); -typedef const wchar_t* (RENDERDOC_CC *pRENDERDOC_GetLogFile)(); +extern "C" RENDERDOC_API const char* RENDERDOC_CC RENDERDOC_GetLogFile(); +typedef const char* (RENDERDOC_CC *pRENDERDOC_GetLogFile)(); -extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_GetCapture(uint32_t idx, wchar_t *logfile, uint32_t *pathlength, uint64_t *timestamp); -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetCapture)(uint32_t idx, wchar_t *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); @@ -227,14 +230,5 @@ typedef void (RENDERDOC_CC *pRENDERDOC_SetCaptureKeys)(KeyButton *keys, int num) extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_InitRemoteAccess(uint32_t *ident); typedef void (RENDERDOC_CC *pRENDERDOC_InitRemoteAccess)(uint32_t *ident); -////////////////////////////////////////////////////////////////////////// -// Injection/execution capture functions. -////////////////////////////////////////////////////////////////////////// - -extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_ExecuteAndInject(const wchar_t *app, const wchar_t *workingDir, const wchar_t *cmdLine, - const wchar_t *logfile, const CaptureOptions *opts, uint32_t waitForExit); -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_ExecuteAndInject)(const wchar_t *app, const wchar_t *workingDir, const wchar_t *cmdLine, - const wchar_t *logfile, const CaptureOptions *opts, uint32_t waitForExit); - -extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_InjectIntoProcess(uint32_t pid, const wchar_t *logfile, const CaptureOptions *opts, uint32_t waitForExit); -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_InjectIntoProcess)(uint32_t pid, const wchar_t *logfile, const CaptureOptions *opts, uint32_t waitForExit); +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_UnloadCrashHandler(); +typedef void (RENDERDOC_CC *pRENDERDOC_UnloadCrashHandler)(); diff --git a/src/renderdoc.cpp b/src/renderdoc.cpp new file mode 100644 index 000000000..a5677da50 --- /dev/null +++ b/src/renderdoc.cpp @@ -0,0 +1,152 @@ +/* + * Copyright 2011-2014 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#include "bgfx_p.h" + +#if BGFX_CONFIG_DEBUG_PIX +# include +# include + +namespace bgfx +{ + bool findModule(const char* _name) + { +#if BX_PLATFORM_WINDOWS + HANDLE process = GetCurrentProcess(); + DWORD size; + BOOL result = EnumProcessModules(process + , NULL + , 0 + , &size + ); + if (0 != result) + { + HMODULE* modules = (HMODULE*)alloca(size); + result = EnumProcessModules(process + , modules + , size + , &size + ); + + if (0 != result) + { + char moduleName[MAX_PATH]; + for (uint32_t ii = 0, num = uint32_t(size/sizeof(HMODULE) ); ii < num; ++ii) + { + result = GetModuleBaseNameA(process + , modules[ii] + , moduleName + , BX_COUNTOF(moduleName) + ); + if (0 != result + && 0 == bx::stricmp(_name, moduleName) ) + { + return true; + } + } + } + } +#endif // BX_PLATFORM_WINDOWS + BX_UNUSED(_name); + return false; + } + +#define RENDERDOC_IMPORT \ + RENDERDOC_IMPORT_FUNC(RENDERDOC_SetLogFile); \ + RENDERDOC_IMPORT_FUNC(RENDERDOC_GetCapture); \ + RENDERDOC_IMPORT_FUNC(RENDERDOC_SetCaptureOptions); \ + RENDERDOC_IMPORT_FUNC(RENDERDOC_SetActiveWindow); \ + RENDERDOC_IMPORT_FUNC(RENDERDOC_TriggerCapture); \ + RENDERDOC_IMPORT_FUNC(RENDERDOC_StartFrameCapture); \ + RENDERDOC_IMPORT_FUNC(RENDERDOC_EndFrameCapture); \ + RENDERDOC_IMPORT_FUNC(RENDERDOC_GetOverlayBits); \ + RENDERDOC_IMPORT_FUNC(RENDERDOC_MaskOverlayBits); \ + RENDERDOC_IMPORT_FUNC(RENDERDOC_SetFocusToggleKeys); \ + RENDERDOC_IMPORT_FUNC(RENDERDOC_SetCaptureKeys); \ + RENDERDOC_IMPORT_FUNC(RENDERDOC_InitRemoteAccess); + +#define RENDERDOC_IMPORT_FUNC(_func) p##_func _func + RENDERDOC_IMPORT +#undef RENDERDOC_IMPORT_FUNC + + pRENDERDOC_GetAPIVersion RENDERDOC_GetAPIVersion; + + void* loadRenderDoc() + { + // Skip loading RenderDoc when IntelGPA is present to avoid RenderDoc crash. + if (findModule(BX_ARCH_32BIT ? "shimloader32.dll" : "shimloader64.dll") ) + { + return NULL; + } + + void* renderdocdll = bx::dlopen("renderdoc.dll"); + + if (NULL != renderdocdll) + { + RENDERDOC_GetAPIVersion = (pRENDERDOC_GetAPIVersion)bx::dlsym(renderdocdll, "RENDERDOC_GetAPIVersion"); + if (NULL != RENDERDOC_GetAPIVersion + && RENDERDOC_API_VERSION == RENDERDOC_GetAPIVersion() ) + { +#define RENDERDOC_IMPORT_FUNC(_func) \ + _func = (p##_func)bx::dlsym(renderdocdll, #_func); \ + BX_TRACE("%p " #_func, _func); +RENDERDOC_IMPORT +#undef RENDERDOC_IMPORT_FUNC + + RENDERDOC_SetLogFile("temp/bgfx"); + + RENDERDOC_SetFocusToggleKeys(NULL, 0); + + KeyButton captureKey = eKey_F11; + RENDERDOC_SetCaptureKeys(&captureKey, 1); + + CaptureOptions opt; + memset(&opt, 0, sizeof(opt) ); + opt.AllowVSync = 1; + opt.SaveAllInitials = 1; + RENDERDOC_SetCaptureOptions(&opt); + + uint32_t ident = 0; + RENDERDOC_InitRemoteAccess(&ident); + + RENDERDOC_MaskOverlayBits(eOverlay_None, eOverlay_None); + } + else + { + bx::dlclose(renderdocdll); + renderdocdll = NULL; + } + } + + return renderdocdll; + } + + void unloadRenderDoc(void* _renderdocdll) + { + if (NULL != _renderdocdll) + { + bx::dlclose(_renderdocdll); + } + } + +} // namespace bgfx + +#else + +namespace bgfx +{ + + void* loadRenderDoc() + { + return NULL; + } + + void unloadRenderDoc(void*) + { + } + +} // namespace bgfx + +#endif // BGFX_CONFIG_DEBUG_PIX diff --git a/src/renderdoc.h b/src/renderdoc.h new file mode 100644 index 000000000..c88d89cf5 --- /dev/null +++ b/src/renderdoc.h @@ -0,0 +1,11 @@ +/* + * Copyright 2011-2014 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +namespace bgfx +{ + void* loadRenderDoc(); + void unloadRenderDoc(void*); + +} // namespace bgfx diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index ce429fd8b..499267785 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -8,11 +8,6 @@ #if BGFX_CONFIG_RENDERER_DIRECT3D11 # include "renderer_d3d11.h" -# if BGFX_CONFIG_DEBUG_PIX -# include -# include -# endif // BGFX_CONFIG_DEBUG_PIX - namespace bgfx { static wchar_t s_viewNameW[BGFX_CONFIG_MAX_VIEWS][BGFX_CONFIG_MAX_VIEW_NAME]; @@ -396,135 +391,6 @@ namespace bgfx return false; }; -#if BGFX_CONFIG_DEBUG_PIX && BX_PLATFORM_WINDOWS - bool findModule(const char* _name) - { - HANDLE process = GetCurrentProcess(); - DWORD size; - BOOL result = EnumProcessModules(process - , NULL - , 0 - , &size - ); - if (0 != result) - { - HMODULE* modules = (HMODULE*)alloca(size); - result = EnumProcessModules(process - , modules - , size - , &size - ); - - if (0 != result) - { - char moduleName[MAX_PATH]; - for (uint32_t ii = 0, num = uint32_t(size/sizeof(HMODULE) ); ii < num; ++ii) - { - result = GetModuleBaseNameA(process - , modules[ii] - , moduleName - , BX_COUNTOF(moduleName) - ); - if (0 != result - && 0 == bx::stricmp(_name, moduleName) ) - { - return true; - } - } - } - } - - return false; - } - -#define RENDERDOC_IMPORT \ - RENDERDOC_IMPORT_FUNC(RENDERDOC_SetLogFile); \ - RENDERDOC_IMPORT_FUNC(RENDERDOC_GetCapture); \ - RENDERDOC_IMPORT_FUNC(RENDERDOC_SetCaptureOptions); \ - RENDERDOC_IMPORT_FUNC(RENDERDOC_SetActiveWindow); \ - RENDERDOC_IMPORT_FUNC(RENDERDOC_TriggerCapture); \ - RENDERDOC_IMPORT_FUNC(RENDERDOC_StartFrameCapture); \ - RENDERDOC_IMPORT_FUNC(RENDERDOC_EndFrameCapture); \ - RENDERDOC_IMPORT_FUNC(RENDERDOC_GetOverlayBits); \ - RENDERDOC_IMPORT_FUNC(RENDERDOC_MaskOverlayBits); \ - RENDERDOC_IMPORT_FUNC(RENDERDOC_SetFocusToggleKeys); \ - RENDERDOC_IMPORT_FUNC(RENDERDOC_SetCaptureKeys); \ - RENDERDOC_IMPORT_FUNC(RENDERDOC_InitRemoteAccess); - -#define RENDERDOC_IMPORT_FUNC(_func) p##_func _func - RENDERDOC_IMPORT -#undef RENDERDOC_IMPORT_FUNC - - pRENDERDOC_GetAPIVersion RENDERDOC_GetAPIVersion; - - void* loadRenderDoc() - { - // Skip loading RenderDoc when IntelGPA is present to avoid RenderDoc crash. - if (findModule(BX_ARCH_32BIT ? "shimloader32.dll" : "shimloader64.dll") ) - { - return NULL; - } - - void* renderdocdll = bx::dlopen("renderdoc.dll"); - - if (NULL != renderdocdll) - { - RENDERDOC_GetAPIVersion = (pRENDERDOC_GetAPIVersion)bx::dlsym(renderdocdll, "RENDERDOC_GetAPIVersion"); - if (NULL != RENDERDOC_GetAPIVersion - && RENDERDOC_API_VERSION == RENDERDOC_GetAPIVersion() ) - { -#define RENDERDOC_IMPORT_FUNC(_func) \ - _func = (p##_func)bx::dlsym(renderdocdll, #_func); \ - BX_TRACE("%p " #_func, _func); -RENDERDOC_IMPORT -#undef RENDERDOC_IMPORT_FUNC - - RENDERDOC_SetLogFile(L"temp/bgfx"); - - RENDERDOC_SetFocusToggleKeys(NULL, 0); - - KeyButton captureKey = eKey_F11; - RENDERDOC_SetCaptureKeys(&captureKey, 1); - - CaptureOptions opt; - memset(&opt, 0, sizeof(opt) ); - opt.AllowVSync = 1; - opt.SaveAllInitials = 1; - RENDERDOC_SetCaptureOptions(&opt); - - uint32_t ident = 0; - RENDERDOC_InitRemoteAccess(&ident); - - RENDERDOC_MaskOverlayBits(eOverlay_None, eOverlay_None); - } - else - { - bx::dlclose(renderdocdll); - renderdocdll = NULL; - } - } - - return renderdocdll; - } - - void unloadRenderDoc(void* _renderdocdll) - { - if (NULL != _renderdocdll) - { - bx::dlclose(_renderdocdll); - } - } -#else - void* loadRenderDoc() - { - return NULL; - } - - void unloadRenderDoc(void*) - { - } -#endif // BGFX_CONFIG_DEBUG_PIX - #if USE_D3D11_DYNAMIC_LIB static PFN_D3D11_CREATE_DEVICE D3D11CreateDevice; static PFN_CREATE_DXGI_FACTORY CreateDXGIFactory; diff --git a/src/renderer_d3d11.h b/src/renderer_d3d11.h index 20eb056f7..d0144dd1c 100644 --- a/src/renderer_d3d11.h +++ b/src/renderer_d3d11.h @@ -27,6 +27,7 @@ BX_PRAGMA_DIAGNOSTIC_POP() #include "renderer_d3d.h" #include "ovr.h" +#include "renderdoc.h" #ifndef D3DCOLOR_ARGB # define D3DCOLOR_ARGB(_a, _r, _g, _b) ( (DWORD)( ( ( (_a)&0xff)<<24)|( ( (_r)&0xff)<<16)|( ( (_g)&0xff)<<8)|( (_b)&0xff) ) ) diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 6516b3d6a..0c49055e8 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -869,6 +869,8 @@ namespace bgfx void init() { + m_renderdocdll = loadRenderDoc(); + m_fbh.idx = invalidHandle; memset(m_uniforms, 0, sizeof(m_uniforms) ); memset(&m_resolution, 0, sizeof(m_resolution) ); @@ -1401,6 +1403,8 @@ namespace bgfx m_glctx.destroy(); m_flip = false; + + unloadRenderDoc(m_renderdocdll); } RendererType::Enum getRendererType() const BX_OVERRIDE @@ -2384,6 +2388,8 @@ namespace bgfx } } + void* m_renderdocdll; + uint16_t m_numWindows; FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS]; @@ -5182,6 +5188,11 @@ namespace bgfx ); } + if (NULL != m_renderdocdll) + { + tvm.printf(tvm.m_width-27, 0, 0x1f, " [F11 - RenderDoc capture] "); + } + tvm.printf(10, pos++, 0x8e, " Indices: %7d", statsNumIndices); tvm.printf(10, pos++, 0x8e, " DVB size: %7d", _render->m_vboffset); tvm.printf(10, pos++, 0x8e, " DIB size: %7d", _render->m_iboffset); diff --git a/src/renderer_gl.h b/src/renderer_gl.h index 48da73f76..7a6e496cc 100644 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -87,6 +87,7 @@ typedef uint64_t GLuint64; #endif // BGFX_CONFIG_RENDERER_OPENGL #include "ovr.h" +#include "renderdoc.h" #ifndef GL_BGRA # define GL_BGRA 0x80E1