debug_renderdoc.cpp 3.6 KB

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