Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ngfx sdk integration #777

Merged
merged 12 commits into from
Dec 31, 2024
20 changes: 18 additions & 2 deletions include/nbl/video/IAPIConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

#include "nbl/video/utilities/renderdoc.h"


namespace nbl::video
{

Expand Down Expand Up @@ -61,15 +60,32 @@ class NBL_API2 IAPIConnection : public core::IReferenceCounted

const SFeatures& getEnabledFeatures() const { return m_enabledFeatures; }

const bool isRunningInRenderdoc() const { return m_rdoc_api; }
enum SDebuggerType
{
EDT_NONE,
EDT_RENDERDOC,
EDT_NGFX
};
const SDebuggerType isRunningInGraphicsDebugger() const { return m_debuggerType; }
virtual bool startCapture() = 0;
virtual bool endCapture() = 0;

protected:
IAPIConnection(const SFeatures& enabledFeatures);

std::vector<std::unique_ptr<IPhysicalDevice>> m_physicalDevices;
SDebuggerType m_debuggerType;
renderdoc_api_t* m_rdoc_api;

struct SNGFXIntegration {
bool useNGFX;

bool injectNGFXToProcess();
bool executeNGFXCommand();
};
using ngfx_api_t = SNGFXIntegration;
ngfx_api_t m_ngfx_api;

SFeatures m_enabledFeatures = {};
};

Expand Down
16 changes: 12 additions & 4 deletions src/nbl/video/CVulkanConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,8 @@ CVulkanConnection::~CVulkanConnection()

bool CVulkanConnection::startCapture()
{
if (!isRunningInRenderdoc())
auto debugType = isRunningInGraphicsDebugger();
if (debugType == EDT_NONE)
return false;
if (flag.test())
{
Expand All @@ -335,13 +336,17 @@ bool CVulkanConnection::startCapture()
}

flag.test_and_set();
m_rdoc_api->StartFrameCapture(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(m_vkInstance), NULL);
if (debugType == EDT_RENDERDOC)
m_rdoc_api->StartFrameCapture(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(m_vkInstance), NULL);
else
m_ngfx_api.executeNGFXCommand();
return true;
}

bool CVulkanConnection::endCapture()
{
if (!isRunningInRenderdoc())
auto debugType = isRunningInGraphicsDebugger();
if (debugType == EDT_NONE)
return false;
if (!flag.test())
{
Expand All @@ -352,7 +357,10 @@ bool CVulkanConnection::endCapture()
return false;
}

m_rdoc_api->EndFrameCapture(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(m_vkInstance), NULL);
if (debugType == EDT_RENDERDOC)
m_rdoc_api->EndFrameCapture(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(m_vkInstance), NULL);
// no equivalent end frame capture for ngfx, ends captures on next frame delimiter
// see https://www.reddit.com/r/GraphicsProgramming/comments/w0hl9o/graphics_debugger_record_before_first_frame/
flag.clear();
return true;
}
Expand Down
79 changes: 79 additions & 0 deletions src/nbl/video/IAPIConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

#include "nbl/video/IPhysicalDevice.h"
#include "nbl/video/utilities/renderdoc.h"
#include "nbl/video/utilities/ngfx.h"

// TODO: temporary hopefully
#include "C:\Program Files\NVIDIA Corporation\Nsight Graphics 2024.1.0\SDKs\NsightGraphicsSDK\0.8.0\include\NGFX_Injection.h"

#if defined(_NBL_POSIX_API_)
#include <dlfcn.h>
Expand All @@ -10,6 +14,7 @@
namespace nbl::video
{


std::span<IPhysicalDevice* const> IAPIConnection::getPhysicalDevices() const
{
static_assert(sizeof(std::unique_ptr<IPhysicalDevice>) == sizeof(void*));
Expand Down Expand Up @@ -43,7 +48,81 @@ IAPIConnection::IAPIConnection(const SFeatures& enabledFeatures)
int ret = RENDERDOC_GetAPI(MinRenderdocVersion, (void**)&m_rdoc_api);
assert(ret == 1);
#endif

// probably is platform agnostic, for now
m_ngfx_api.injectNGFXToProcess();

m_debuggerType = m_ngfx_api.useNGFX ? EDT_NGFX : // ngfx takes priority?
m_rdoc_api ? EDT_RENDERDOC : EDT_NONE;
}
}

bool IAPIConnection::SNGFXIntegration::injectNGFXToProcess()
{
uint32_t numInstallations = 0;
auto result = NGFX_Injection_EnumerateInstallations(&numInstallations, nullptr);
if (numInstallations == 0 || NGFX_INJECTION_RESULT_OK != result)
{
useNGFX = false;
return false;
}

std::vector<NGFX_Injection_InstallationInfo> installations(numInstallations);
result = NGFX_Injection_EnumerateInstallations(&numInstallations, installations.data());
if (numInstallations == 0 || NGFX_INJECTION_RESULT_OK != result)
{
useNGFX = false;
return false;
}

// get latest installation
NGFX_Injection_InstallationInfo versionInfo = installations.back();

uint32_t numActivities = 0;
result = NGFX_Injection_EnumerateActivities(&versionInfo, &numActivities, nullptr);
if (numActivities == 0 || NGFX_INJECTION_RESULT_OK != result)
{
useNGFX = false;
return false;
}

std::vector<NGFX_Injection_Activity> activities(numActivities);
result = NGFX_Injection_EnumerateActivities(&versionInfo, &numActivities, activities.data());
if (NGFX_INJECTION_RESULT_OK != result)
{
useNGFX = false;
return false;
}

const NGFX_Injection_Activity* pActivityToInject = nullptr;
for (const NGFX_Injection_Activity& activity : activities)
{
if (activity.type == NGFX_INJECTION_ACTIVITY_FRAME_DEBUGGER) // only want frame debugger
{
pActivityToInject = &activity;
break;
}
}

if (!pActivityToInject) {
useNGFX = false;
return false;
}

result = NGFX_Injection_InjectToProcess(&versionInfo, pActivityToInject);
if (NGFX_INJECTION_RESULT_OK != result)
{
useNGFX = false;
return false;
}

useNGFX = true;
return true;
}

bool IAPIConnection::SNGFXIntegration::executeNGFXCommand()
{
return NGFX_Injection_ExecuteActivityCommand() == NGFX_INJECTION_RESULT_OK;
}

}