debug_renderdoc.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * Copyright 2011-2023 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
  4. */
  5. #include "bgfx_p.h"
  6. #if BX_PLATFORM_WINDOWS || BX_PLATFORM_LINUX
  7. # if BX_PLATFORM_WINDOWS
  8. # ifndef WIN32_LEAN_AND_MEAN
  9. # define WIN32_LEAN_AND_MEAN
  10. # endif // WIN32_LEAN_AND_MEAN
  11. # include <windows.h>
  12. # include <psapi.h>
  13. # endif // BX_PLATFORM_WINDOWS
  14. # include <renderdoc/renderdoc_app.h>
  15. namespace bgfx
  16. {
  17. void* findModule(const char* _name)
  18. {
  19. #if BX_PLATFORM_WINDOWS
  20. // NOTE: there was some reason to do it this way instead of simply calling GetModuleHandleA,
  21. // but not sure what it was.
  22. HANDLE process = GetCurrentProcess();
  23. DWORD size;
  24. BOOL result = EnumProcessModules(process
  25. , NULL
  26. , 0
  27. , &size
  28. );
  29. if (0 != result)
  30. {
  31. HMODULE* modules = (HMODULE*)alloca(size);
  32. result = EnumProcessModules(process
  33. , modules
  34. , size
  35. , &size
  36. );
  37. if (0 != result)
  38. {
  39. char moduleName[MAX_PATH];
  40. for (uint32_t ii = 0, num = uint32_t(size/sizeof(HMODULE) ); ii < num; ++ii)
  41. {
  42. result = GetModuleBaseNameA(process
  43. , modules[ii]
  44. , moduleName
  45. , BX_COUNTOF(moduleName)
  46. );
  47. if (0 != result
  48. && 0 == bx::strCmpI(_name, moduleName) )
  49. {
  50. return (void*)modules[ii];
  51. }
  52. }
  53. }
  54. }
  55. #else
  56. BX_UNUSED(_name);
  57. #endif // BX_PLATFORM_WINDOWS
  58. return NULL;
  59. }
  60. pRENDERDOC_GetAPI RENDERDOC_GetAPI;
  61. static RENDERDOC_API_1_1_2* s_renderDoc = NULL;
  62. static void* s_renderDocDll = NULL;
  63. void* loadRenderDoc()
  64. {
  65. if (NULL != s_renderDoc)
  66. {
  67. return s_renderDocDll;
  68. }
  69. // Skip loading RenderDoc when IntelGPA is present to avoid RenderDoc crash.
  70. if (findModule(BX_ARCH_32BIT ? "shimloader32.dll" : "shimloader64.dll") )
  71. {
  72. return NULL;
  73. }
  74. // If RenderDoc is already injected in the process then use the already present DLL
  75. void* renderDocDll = findModule("renderdoc.dll");
  76. if (NULL == renderDocDll)
  77. {
  78. // TODO: try common installation paths before looking in current directory
  79. renderDocDll = bx::dlopen(
  80. #if BX_PLATFORM_WINDOWS
  81. "renderdoc.dll"
  82. #else
  83. "./librenderdoc.so"
  84. #endif // BX_PLATFORM_WINDOWS
  85. );
  86. }
  87. if (NULL != renderDocDll)
  88. {
  89. RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)bx::dlsym(renderDocDll, "RENDERDOC_GetAPI");
  90. if (NULL != RENDERDOC_GetAPI
  91. && 1 == RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void**)&s_renderDoc) )
  92. {
  93. s_renderDoc->SetCaptureFilePathTemplate(BGFX_CONFIG_RENDERDOC_LOG_FILEPATH);
  94. s_renderDoc->SetFocusToggleKeys(NULL, 0);
  95. RENDERDOC_InputButton captureKeys[] = BGFX_CONFIG_RENDERDOC_CAPTURE_KEYS;
  96. s_renderDoc->SetCaptureKeys(captureKeys, BX_COUNTOF(captureKeys) );
  97. s_renderDoc->SetCaptureOptionU32(eRENDERDOC_Option_AllowVSync, 1);
  98. s_renderDoc->SetCaptureOptionU32(eRENDERDOC_Option_SaveAllInitials, 1);
  99. s_renderDoc->MaskOverlayBits(eRENDERDOC_Overlay_None, eRENDERDOC_Overlay_None);
  100. s_renderDocDll = renderDocDll;
  101. }
  102. else
  103. {
  104. bx::dlclose(renderDocDll);
  105. renderDocDll = NULL;
  106. }
  107. }
  108. return renderDocDll;
  109. }
  110. void unloadRenderDoc(void* _renderdocdll)
  111. {
  112. if (NULL != _renderdocdll)
  113. {
  114. // BK - Once RenderDoc is loaded there shouldn't be calls
  115. // to Shutdown or unload RenderDoc DLL.
  116. // https://github.com/bkaradzic/bgfx/issues/1192
  117. //
  118. // s_renderDoc->Shutdown();
  119. // bx::dlclose(_renderdocdll);
  120. }
  121. }
  122. void renderDocTriggerCapture()
  123. {
  124. if (NULL != s_renderDoc)
  125. {
  126. s_renderDoc->TriggerCapture();
  127. }
  128. }
  129. } // namespace bgfx
  130. #else
  131. namespace bgfx
  132. {
  133. void* loadRenderDoc()
  134. {
  135. return NULL;
  136. }
  137. void unloadRenderDoc(void*)
  138. {
  139. }
  140. void renderDocTriggerCapture()
  141. {
  142. }
  143. } // namespace bgfx
  144. #endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_LINUX