|
16 | 16 | namespace nbl::video
|
17 | 17 | {
|
18 | 18 |
|
19 |
| -std::span<IPhysicalDevice* const> IAPIConnection::getPhysicalDevices() const |
| 19 | +void IAPIConnection::loadDebuggers() |
20 | 20 | {
|
21 |
| - static_assert(sizeof(std::unique_ptr<IPhysicalDevice>) == sizeof(void*)); |
| 21 | + // there's a debugger already attached to the process |
| 22 | + if (m_debugger!=EDebuggerType::None) |
| 23 | + return; |
22 | 24 |
|
23 |
| - IPhysicalDevice* const* const begin = reinterpret_cast<IPhysicalDevice* const*>(m_physicalDevices.data()); |
24 |
| - return {begin,m_physicalDevices.size()}; |
| 25 | + // NGFX takes precedence, but don't want to use NGFX SDK unless NSight launched our application. |
| 26 | + // Otherwise we end up starting random NSight GUI instances if only the NGFX DLL is found (interferes with Renderdoccing) |
| 27 | + if (std::getenv("NVTX_INJECTION64_PATH")) |
| 28 | + { |
| 29 | + if (loadNGFX()) |
| 30 | + m_debugger = EDebuggerType::NSight; |
| 31 | + return; |
| 32 | + } |
| 33 | + |
| 34 | + // now load renderdoc |
| 35 | + if (loadRenderdoc()) |
| 36 | + m_debugger = EDebuggerType::Renderdoc; |
25 | 37 | }
|
26 | 38 |
|
27 |
| -bool IAPIConnection::loadNGFX() const |
| 39 | +bool IAPIConnection::loadNGFX() |
28 | 40 | {
|
29 | 41 | #ifdef NBL_BUILD_WITH_NGFX
|
30 | 42 | //! absolute path to official install NGFX SDK runtime directory
|
@@ -67,47 +79,42 @@ bool IAPIConnection::loadNGFX() const
|
67 | 79 | #error "TODO!"
|
68 | 80 | #endif
|
69 | 81 |
|
| 82 | + if (isAlreadyLoaded) |
| 83 | + return true; |
| 84 | + |
70 | 85 | // now call the APIs for the first time
|
71 |
| - if (!isAlreadyLoaded) |
| 86 | + uint32_t numInstallations = 0; |
| 87 | + auto result = NGFX_Injection_EnumerateInstallations(&numInstallations, nullptr); |
| 88 | + if (numInstallations==0 || NGFX_INJECTION_RESULT_OK!=result) |
| 89 | + return false; |
| 90 | + |
| 91 | + std::vector<NGFX_Injection_InstallationInfo> installations(numInstallations); |
| 92 | + result = NGFX_Injection_EnumerateInstallations(&numInstallations,installations.data()); |
| 93 | + if (NGFX_INJECTION_RESULT_OK!=result) |
| 94 | + return false; |
| 95 | + assert(installations.size()==numInstallations); |
| 96 | + |
| 97 | + // get latest installation |
| 98 | + const NGFX_Injection_InstallationInfo& versionInfo = installations.back(); |
| 99 | + |
| 100 | + uint32_t numActivities = 0; |
| 101 | + result = NGFX_Injection_EnumerateActivities(&versionInfo, &numActivities, nullptr); |
| 102 | + if (numActivities==0 || NGFX_INJECTION_RESULT_OK!=result) |
| 103 | + return false; |
| 104 | + |
| 105 | + std::vector<NGFX_Injection_Activity> activities(numActivities); |
| 106 | + result = NGFX_Injection_EnumerateActivities(&versionInfo, &numActivities, activities.data()); |
| 107 | + if (NGFX_INJECTION_RESULT_OK != result) |
| 108 | + return false; |
| 109 | + assert(activities.size()==numActivities); |
| 110 | + |
| 111 | + for (const auto& activity : activities) |
| 112 | + if (activity.type==NGFX_INJECTION_ACTIVITY_FRAME_DEBUGGER) |
72 | 113 | {
|
73 |
| - uint32_t numInstallations = 0; |
74 |
| - auto result = NGFX_Injection_EnumerateInstallations(&numInstallations, nullptr); |
75 |
| - if (numInstallations==0 || NGFX_INJECTION_RESULT_OK!=result) |
76 |
| - return false; |
77 |
| - |
78 |
| - std::vector<NGFX_Injection_InstallationInfo> installations(numInstallations); |
79 |
| - result = NGFX_Injection_EnumerateInstallations(&numInstallations,installations.data()); |
80 |
| - if (NGFX_INJECTION_RESULT_OK!=result) |
81 |
| - return false; |
82 |
| - assert(installations.size()==numInstallations); |
83 |
| - |
84 |
| - // get latest installation |
85 |
| - const NGFX_Injection_InstallationInfo& versionInfo = installations.back(); |
86 |
| - |
87 |
| - uint32_t numActivities = 0; |
88 |
| - result = NGFX_Injection_EnumerateActivities(&versionInfo, &numActivities, nullptr); |
89 |
| - if (numActivities==0 || NGFX_INJECTION_RESULT_OK!=result) |
90 |
| - return false; |
91 |
| - |
92 |
| - std::vector<NGFX_Injection_Activity> activities(numActivities); |
93 |
| - result = NGFX_Injection_EnumerateActivities(&versionInfo, &numActivities, activities.data()); |
94 |
| - if (NGFX_INJECTION_RESULT_OK != result) |
95 |
| - return false; |
96 |
| - assert(activities.size()==numActivities); |
97 |
| - |
98 |
| - // only want frame debugger |
99 |
| - const auto itActivityToInject = std::find_if(activities.begin(),activities.end(),[](const NGFX_Injection_Activity& activity)->bool{ |
100 |
| - return activity.type==NGFX_INJECTION_ACTIVITY_FRAME_DEBUGGER; |
101 |
| - }); |
102 |
| - if (itActivityToInject==activities.end()) |
103 |
| - return false; |
104 |
| - |
105 |
| - result = NGFX_Injection_InjectToProcess(&versionInfo,&(*itActivityToInject)); |
106 |
| - if (NGFX_INJECTION_RESULT_OK!=result) |
107 |
| - return false; |
| 114 | + result = NGFX_Injection_InjectToProcess(&versionInfo,&activity); |
| 115 | + if (result==NGFX_INJECTION_RESULT_DRIVER_STILL_LOADED) |
| 116 | + return true; |
108 | 117 | }
|
109 |
| - |
110 |
| - return true; |
111 | 118 | #endif
|
112 | 119 | // no NGFX build -> no API to load
|
113 | 120 | return false;
|
@@ -136,23 +143,21 @@ bool IAPIConnection::loadRenderdoc()
|
136 | 143 | return false;
|
137 | 144 | }
|
138 | 145 |
|
139 |
| -IAPIConnection::IAPIConnection(const SFeatures& enabledFeatures) |
140 |
| - : m_physicalDevices() |
141 |
| - , m_rdoc_api(nullptr) |
142 |
| - , m_enabledFeatures(enabledFeatures) |
| 146 | +IAPIConnection::IAPIConnection(const SFeatures& enabledFeatures) : m_physicalDevices(), m_enabledFeatures(enabledFeatures) |
143 | 147 | {
|
144 |
| - // NGFX takes precedence |
145 |
| - if (loadNGFX()) |
146 |
| - m_debugger = EDebuggerType::NSight; |
147 |
| - if (isRunningInGraphicsDebugger()) |
148 |
| - return; |
149 |
| - |
150 |
| - // now load renderdoc |
151 |
| - if (loadRenderdoc()) |
152 |
| - m_debugger = EDebuggerType::Renderdoc; |
| 148 | + loadDebuggers(); |
153 | 149 | }
|
154 | 150 |
|
| 151 | +std::span<IPhysicalDevice* const> IAPIConnection::getPhysicalDevices() const |
| 152 | +{ |
| 153 | + static_assert(sizeof(std::unique_ptr<IPhysicalDevice>) == sizeof(void*)); |
| 154 | + |
| 155 | + IPhysicalDevice* const* const begin = reinterpret_cast<IPhysicalDevice* const*>(m_physicalDevices.data()); |
| 156 | + return {begin,m_physicalDevices.size()}; |
| 157 | +} |
155 | 158 |
|
| 159 | +// Current NGFX SDK API is extremely dumb, this will literally pop up a new NSight window every frame. |
| 160 | +// It also still fails to capture anything happening off the Queue that's acquiring and presenting to the swapchain or before the very first acquire. |
156 | 161 | void IAPIConnection::executeNGFXCommand()
|
157 | 162 | {
|
158 | 163 | assert(m_debugger==EDebuggerType::NSight);
|
|
0 commit comments