From 8f242043aa8da0aa594f5b765cd6874ff9edfd57 Mon Sep 17 00:00:00 2001 From: Jonathan Glines Date: Mon, 9 Jun 2025 11:45:13 -0700 Subject: [PATCH] Update NVD3D11Counters to use the latest Nsight PerfSDK APIs Updated NVD3D11Counters to use the RawCounterConfig and counter availability APIs from the latest Nsight PerfSDK headers. --- renderdoc/driver/ihv/nv/nv_d3d11_counters.cpp | 85 +++++++++++++++++-- 1 file changed, 78 insertions(+), 7 deletions(-) diff --git a/renderdoc/driver/ihv/nv/nv_d3d11_counters.cpp b/renderdoc/driver/ihv/nv/nv_d3d11_counters.cpp index babafeeaa..a1f6178cb 100644 --- a/renderdoc/driver/ihv/nv/nv_d3d11_counters.cpp +++ b/renderdoc/driver/ihv/nv/nv_d3d11_counters.cpp @@ -38,6 +38,7 @@ struct NVD3D11Counters::Impl { NVCounterEnumerator *CounterEnumerator; bool LibraryNotFound = false; + bool LibraryNotSupported = false; Impl() : CounterEnumerator(NULL) {} ~Impl() @@ -64,6 +65,32 @@ struct NVD3D11Counters::Impl MessageSource::RuntimeWarning, message); } + static bytebuf GetCounterAvailabilityImage(WrappedID3D11Device *device) + { + bytebuf counterAvailabilityImage; + NVPA_Status result; + NVPW_D3D11_Profiler_DeviceContext_GetCounterAvailability_Params params = {}; + params.structSize = NVPW_D3D11_Profiler_DeviceContext_GetCounterAvailability_Params_STRUCT_SIZE; + params.pDeviceContext = device->GetImmediateContext()->GetReal(); + result = NVPW_D3D11_Profiler_DeviceContext_GetCounterAvailability(¶ms); + if(result != NVPA_STATUS_SUCCESS) + { + Impl::LogDebugMessage("NVD3D11Counters::GetCounterAvailabilityImage", + "NvPerf could not determine counter availability for this GPU", device); + return {}; + } + counterAvailabilityImage.resize(params.counterAvailabilityImageSize); + params.pCounterAvailabilityImage = counterAvailabilityImage.data(); + result = NVPW_D3D11_Profiler_DeviceContext_GetCounterAvailability(¶ms); + if(result != NVPA_STATUS_SUCCESS) + { + Impl::LogDebugMessage("NVD3D11Counters::GetCounterAvailabilityImage", + "NvPerf could not determine counter availability for this GPU", device); + return {}; + } + return counterAvailabilityImage; + } + bool TryInitializePerfSDK(WrappedID3D11Device *device) { if(!NVCounterEnumerator::InitializeNvPerf()) @@ -76,6 +103,16 @@ struct NVD3D11Counters::Impl return true; } + if(!NVPA_GetProcAddress("NVPW_D3D11_RawCounterConfig_Create")) + { + RDCWARN("NvPerf library version is out-of-date"); + LibraryNotSupported = true; + + // NOTE: Return success here so that we can later show a message + // directing the user to download the Nsight Perf SDK library. + return true; + } + nv::perf::UserLogEnableCustom(NVD3D11Counters::Impl::LogNvPerfAsDebugMessage, (void *)device); auto logGuard = nv::perf::ScopeExitGuard([]() { nv::perf::UserLogDisableCustom(); }); @@ -125,12 +162,40 @@ struct NVD3D11Counters::Impl nv::perf::MetricsEvaluator metricsEvaluator(pMetricsEvaluator, std::move(scratchBuffer)); + bytebuf counterAvailabilityImage = Impl::GetCounterAvailabilityImage(device); + if(counterAvailabilityImage.empty()) + { + Impl::LogDebugMessage("NVD3D11Counters::Impl::TryInitializePerfSDK", + "NvPerf could not initialize counter availability image", device); + // NOTE: Not a fatal error; we can attempt to list counters regardless of availability + } + + NVPW_RawCounterConfig *pRawCounterConfig = + nv::perf::profiler::D3D11CreateRawCounterConfig(deviceIdentifiers.pChipName); + if(!pRawCounterConfig) + { + Impl::LogDebugMessage("NVD3D11Counters::Impl::TryInitializePerfSDK", + "NvPerf could not initialize raw counter config", device); + return false; + } + + nv::perf::RawCounterConfigBuilder rawCounterConfigBuilder; + if(!rawCounterConfigBuilder.Initialize(pRawCounterConfig)) + { + Impl::LogDebugMessage("NVD3D11Counters::Impl::TryInitializePerfSDK", + "NvPerf failed to initialize raw counter config builder", device); + return false; + } + CounterEnumerator = new NVCounterEnumerator; - if(!CounterEnumerator->Init(std::move(metricsEvaluator))) + if(!CounterEnumerator->Init(std::move(metricsEvaluator), std::move(rawCounterConfigBuilder), + std::move(counterAvailabilityImage))) { Impl::LogDebugMessage("NVD3D11Counters::Impl::TryInitializePerfSDK", "NvPerf could not initialize metrics evaluator", device); delete CounterEnumerator; + CounterEnumerator = NULL; + // NOTE: Not reachable; CounterEnumerator::Init() never returns false return false; } return true; @@ -218,7 +283,7 @@ bool NVD3D11Counters::Init(WrappedID3D11Device *device) rdcarray NVD3D11Counters::EnumerateCounters() const { - if(m_Impl->LibraryNotFound) + if(m_Impl->LibraryNotFound || m_Impl->LibraryNotSupported) { return {GPUCounter::FirstNvidia}; } @@ -227,7 +292,7 @@ rdcarray NVD3D11Counters::EnumerateCounters() const bool NVD3D11Counters::HasCounter(GPUCounter counterID) const { - if(m_Impl->LibraryNotFound) + if(m_Impl->LibraryNotFound || m_Impl->LibraryNotSupported) { return counterID == GPUCounter::FirstNvidia; } @@ -242,6 +307,12 @@ CounterDescription NVD3D11Counters::DescribeCounter(GPUCounter counterID) const // Dummy counter shows message directing user to download the Nsight Perf SDK library return NVCounterEnumerator::LibraryNotFoundMessage(); } + if(m_Impl->LibraryNotSupported) + { + RDCASSERT(counterID == GPUCounter::FirstNvidia); + // Dummy counter shows message directing user to update the Nsight Perf SDK library + return NVCounterEnumerator::LibraryNotSupportedMessage(); + } return m_Impl->CounterEnumerator->GetCounterDescription(counterID); } @@ -250,7 +321,7 @@ rdcarray NVD3D11Counters::FetchCounters(const rdcarrayLibraryNotFound) + if(m_Impl->LibraryNotFound || m_Impl->LibraryNotSupported) { return {}; } @@ -289,9 +360,9 @@ rdcarray NVD3D11Counters::FetchCounters(const rdcarrayCounterEnumerator->CreateConfig(deviceIdentifiers.pChipName, pRawMetricsConfig, counters); + NVPW_RawCounterConfig *pRawCounterConfig = + nv::perf::profiler::D3D11CreateRawCounterConfig(deviceIdentifiers.pChipName); + m_Impl->CounterEnumerator->CreateConfig(deviceIdentifiers.pChipName, pRawCounterConfig, counters); } nv::perf::profiler::SetConfigParams setConfigParams;