diff options
author | Jens Peters <jp7677@gmail.com> | 2022-08-28 11:26:11 +0300 |
---|---|---|
committer | Jens Peters <jp7677@gmail.com> | 2022-08-28 14:27:47 +0300 |
commit | bbda12037f9ae860e621b2435292ecf6f78963d0 (patch) | |
tree | 5259f2dd65a73e5f4f001e21bff139f5d71f6b33 | |
parent | 42ad10b8418d986f74759e31ffaab34bc1ecabac (diff) |
nvapi-gpu: Implement GetIrq using nvml
-rw-r--r-- | src/nvapi_gpu.cpp | 39 | ||||
-rw-r--r-- | src/nvapi_interface.cpp | 1 | ||||
-rw-r--r-- | src/sysinfo/nvapi_adapter.cpp | 4 | ||||
-rw-r--r-- | src/sysinfo/nvapi_adapter.h | 1 | ||||
-rw-r--r-- | src/sysinfo/nvml.cpp | 7 | ||||
-rw-r--r-- | src/sysinfo/nvml.h | 2 | ||||
-rw-r--r-- | tests/nvapi_sysinfo.cpp | 21 | ||||
-rw-r--r-- | tests/nvapi_sysinfo_mocks.h | 1 | ||||
-rw-r--r-- | tests/nvapi_system.cpp | 10 |
9 files changed, 86 insertions, 0 deletions
diff --git a/src/nvapi_gpu.cpp b/src/nvapi_gpu.cpp index c667b73..e0341bc 100644 --- a/src/nvapi_gpu.cpp +++ b/src/nvapi_gpu.cpp @@ -45,6 +45,45 @@ extern "C" { } } + NvAPI_Status __cdecl NvAPI_GPU_GetIRQ(NvPhysicalGpuHandle hPhysicalGpu, NvU32* pIRQ) { + constexpr auto n = __func__; + static bool alreadyLoggedNoNvml = false; + static bool alreadyLoggedHandleInvalidated = false; + static bool alreadyLoggedOk = false; + + if (nvapiAdapterRegistry == nullptr) + return ApiNotInitialized(n); + + if (pIRQ == nullptr) + return InvalidArgument(n); + + auto adapter = reinterpret_cast<NvapiAdapter*>(hPhysicalGpu); + if (!nvapiAdapterRegistry->IsAdapter(adapter)) + return ExpectedPhysicalGpuHandle(n); + + if (!adapter->HasNvml()) + return NoImplementation(n, alreadyLoggedNoNvml); + + if (!adapter->HasNvmlDevice()) + return HandleInvalidated(str::format(n, ": NVML available but current adapter is not NVML compatible"), alreadyLoggedHandleInvalidated); + + unsigned int irq; + auto result = adapter->GetNvmlDeviceGetIrqNum(&irq); + switch (result) { + case NVML_SUCCESS: + *pIRQ = irq; + return Ok(n, alreadyLoggedOk); + case NVML_ERROR_FUNCTION_NOT_FOUND: + return NoImplementation(n, alreadyLoggedNoNvml); + case NVML_ERROR_NOT_SUPPORTED: + return NotSupported(n); + case NVML_ERROR_GPU_IS_LOST: + return HandleInvalidated(n); + default: + return Error(str::format(n, ": ", adapter->GetNvmlErrorString(result))); + } + } + NvAPI_Status __cdecl NvAPI_GPU_GetGpuCoreCount(NvPhysicalGpuHandle hPhysicalGpu, NvU32* pCount) { constexpr auto n = __func__; static bool alreadyLoggedNoNvml = false; diff --git a/src/nvapi_interface.cpp b/src/nvapi_interface.cpp index a62398a..64f13a6 100644 --- a/src/nvapi_interface.cpp +++ b/src/nvapi_interface.cpp @@ -72,6 +72,7 @@ extern "C" { INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D_GetLatency) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D_SetLatencyMarker) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_GPU_GetCurrentPCIEDownstreamWidth) + INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_GPU_GetIRQ) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_GPU_GetGpuCoreCount) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_GPU_GetGPUType) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_GPU_GetPCIIdentifiers) diff --git a/src/sysinfo/nvapi_adapter.cpp b/src/sysinfo/nvapi_adapter.cpp index fc56da5..0fd6a28 100644 --- a/src/sysinfo/nvapi_adapter.cpp +++ b/src/sysinfo/nvapi_adapter.cpp @@ -278,6 +278,10 @@ namespace dxvk { return m_nvml.DeviceGetCurrPcieLinkWidth(m_nvmlDevice, width); } + nvmlReturn_t NvapiAdapter::GetNvmlDeviceGetIrqNum(unsigned int* irq) const { + return m_nvml.DeviceGetIrqNum(m_nvmlDevice, irq); + } + nvmlReturn_t NvapiAdapter::GetNvmlDeviceNumGpuCores(unsigned int* numCores) const { return m_nvml.DeviceGetNumGpuCores(m_nvmlDevice, numCores); } diff --git a/src/sysinfo/nvapi_adapter.h b/src/sysinfo/nvapi_adapter.h index 364dd01..131627b 100644 --- a/src/sysinfo/nvapi_adapter.h +++ b/src/sysinfo/nvapi_adapter.h @@ -38,6 +38,7 @@ namespace dxvk { [[nodiscard]] nvmlReturn_t GetNvmlDeviceUtilizationRates(nvmlUtilization_t* utilization) const; [[nodiscard]] nvmlReturn_t GetNvmlDeviceVbiosVersion(char* version, unsigned int length) const; [[nodiscard]] nvmlReturn_t GetNvmlDeviceGetCurrPcieLinkWidth(unsigned int* width) const; + [[nodiscard]] nvmlReturn_t GetNvmlDeviceGetIrqNum(unsigned int* irq) const; [[nodiscard]] nvmlReturn_t GetNvmlDeviceNumGpuCores(unsigned int* numCores) const; [[nodiscard]] nvmlReturn_t GetNvmlDeviceBusType(nvmlBusType_t* type) const; [[nodiscard]] nvmlReturn_t GetNvmlDeviceDynamicPstatesInfo(nvmlGpuDynamicPstatesInfo_t* pDynamicPstatesInfo) const; diff --git a/src/sysinfo/nvml.cpp b/src/sysinfo/nvml.cpp index a34fcd3..674fb78 100644 --- a/src/sysinfo/nvml.cpp +++ b/src/sysinfo/nvml.cpp @@ -28,6 +28,7 @@ namespace dxvk { GETPROCADDR(nvmlDeviceGetUtilizationRates); GETPROCADDR(nvmlDeviceGetVbiosVersion); GETPROCADDR(nvmlDeviceGetCurrPcieLinkWidth); + GETPROCADDR(nvmlDeviceGetIrqNum); GETPROCADDR(nvmlDeviceGetNumGpuCores); GETPROCADDR(nvmlDeviceGetBusType); GETPROCADDR(nvmlDeviceGetDynamicPstatesInfo); @@ -120,6 +121,12 @@ namespace dxvk { : NVML_ERROR_FUNCTION_NOT_FOUND; } + nvmlReturn_t Nvml::DeviceGetIrqNum(nvmlDevice_t device, unsigned int* irqNum) const { + return m_nvmlDeviceGetIrqNum + ? m_nvmlDeviceGetIrqNum(device, irqNum) + : NVML_ERROR_FUNCTION_NOT_FOUND; + } + nvmlReturn_t Nvml::DeviceGetNumGpuCores(nvmlDevice_t device, unsigned int* numCores) const { return m_nvmlDeviceGetNumGpuCores ? m_nvmlDeviceGetNumGpuCores(device, numCores) diff --git a/src/sysinfo/nvml.h b/src/sysinfo/nvml.h index 5ee8444..d2b354e 100644 --- a/src/sysinfo/nvml.h +++ b/src/sysinfo/nvml.h @@ -20,6 +20,7 @@ namespace dxvk { [[nodiscard]] virtual nvmlReturn_t DeviceGetUtilizationRates(nvmlDevice_t device, nvmlUtilization_t* utilization) const; [[nodiscard]] virtual nvmlReturn_t DeviceGetVbiosVersion(nvmlDevice_t device, char* version, unsigned int length) const; [[nodiscard]] virtual nvmlReturn_t DeviceGetCurrPcieLinkWidth(nvmlDevice_t device, unsigned int* width) const; + [[nodiscard]] virtual nvmlReturn_t DeviceGetIrqNum(nvmlDevice_t device, unsigned int* irqNum) const; [[nodiscard]] virtual nvmlReturn_t DeviceGetNumGpuCores(nvmlDevice_t device, unsigned int* numCores) const; [[nodiscard]] virtual nvmlReturn_t DeviceGetBusType(nvmlDevice_t device, nvmlBusType_t* type) const; [[nodiscard]] virtual nvmlReturn_t DeviceGetDynamicPstatesInfo(nvmlDevice_t device, nvmlGpuDynamicPstatesInfo_t* pDynamicPstatesInfo) const; @@ -46,6 +47,7 @@ namespace dxvk { DECLARE_PFN(nvmlDeviceGetUtilizationRates); DECLARE_PFN(nvmlDeviceGetVbiosVersion); DECLARE_PFN(nvmlDeviceGetCurrPcieLinkWidth); + DECLARE_PFN(nvmlDeviceGetIrqNum); DECLARE_PFN(nvmlDeviceGetNumGpuCores); DECLARE_PFN(nvmlDeviceGetBusType); DECLARE_PFN(nvmlDeviceGetDynamicPstatesInfo); diff --git a/tests/nvapi_sysinfo.cpp b/tests/nvapi_sysinfo.cpp index 69b2aae..7a48147 100644 --- a/tests/nvapi_sysinfo.cpp +++ b/tests/nvapi_sysinfo.cpp @@ -765,6 +765,23 @@ TEST_CASE("Sysinfo methods succeed", "[.sysinfo]") { REQUIRE(width == linkWidth); } + SECTION("GetIrq returns OK") { + auto irqNum = 143U; + ALLOW_CALL(*nvml, DeviceGetIrqNum(_, _)) // NOLINT(bugprone-use-after-move) + .LR_SIDE_EFFECT(*_2 = irqNum) + .RETURN(NVML_SUCCESS); + + SetupResourceFactory(std::move(dxgiFactory), std::move(vulkan), std::move(nvml), std::move(lfx)); + REQUIRE(NvAPI_Initialize() == NVAPI_OK); + + NvPhysicalGpuHandle handle; + REQUIRE(NvAPI_SYS_GetPhysicalGpuFromDisplayId(0, &handle) == NVAPI_OK); + + NvU32 irq; + REQUIRE(NvAPI_GPU_GetIRQ(handle, &irq) == NVAPI_OK); + REQUIRE(irq == irqNum); + } + SECTION("GetGpuCoreCount returns OK") { auto cores = 1536U; ALLOW_CALL(*nvml, DeviceGetNumGpuCores(_, _)) // NOLINT(bugprone-use-after-move) @@ -1178,6 +1195,8 @@ TEST_CASE("Sysinfo methods succeed", "[.sysinfo]") { SECTION("NVML depending methods return no-implementation when NVML is not available") { NvU32 width; REQUIRE(NvAPI_GPU_GetCurrentPCIEDownstreamWidth(handle, &width) == NVAPI_NO_IMPLEMENTATION); + NvU32 irq; + REQUIRE(NvAPI_GPU_GetIRQ(handle, &irq) == NVAPI_NO_IMPLEMENTATION); NvU32 cores; REQUIRE(NvAPI_GPU_GetGpuCoreCount(handle, &cores) == NVAPI_NO_IMPLEMENTATION); NV_GPU_DYNAMIC_PSTATES_INFO_EX info; @@ -1218,6 +1237,8 @@ TEST_CASE("Sysinfo methods succeed", "[.sysinfo]") { SECTION("NVML depending methods return handle-invalidated when NVML is available but without suitable adapter") { NvU32 width; REQUIRE(NvAPI_GPU_GetCurrentPCIEDownstreamWidth(handle, &width) == NVAPI_HANDLE_INVALIDATED); + NvU32 irq; + REQUIRE(NvAPI_GPU_GetIRQ(handle, &irq) == NVAPI_HANDLE_INVALIDATED); NvU32 cores; REQUIRE(NvAPI_GPU_GetGpuCoreCount(handle, &cores) == NVAPI_HANDLE_INVALIDATED); NV_GPU_DYNAMIC_PSTATES_INFO_EX info; diff --git a/tests/nvapi_sysinfo_mocks.h b/tests/nvapi_sysinfo_mocks.h index efb9bb3..a3611c6 100644 --- a/tests/nvapi_sysinfo_mocks.h +++ b/tests/nvapi_sysinfo_mocks.h @@ -80,6 +80,7 @@ class NvmlMock : public trompeloeil::mock_interface<dxvk::Nvml> { IMPLEMENT_CONST_MOCK2(DeviceGetUtilizationRates); IMPLEMENT_CONST_MOCK3(DeviceGetVbiosVersion); IMPLEMENT_CONST_MOCK2(DeviceGetCurrPcieLinkWidth); + IMPLEMENT_CONST_MOCK2(DeviceGetIrqNum); IMPLEMENT_CONST_MOCK2(DeviceGetNumGpuCores); IMPLEMENT_CONST_MOCK2(DeviceGetBusType); IMPLEMENT_CONST_MOCK2(DeviceGetDynamicPstatesInfo); diff --git a/tests/nvapi_system.cpp b/tests/nvapi_system.cpp index a8ca983..c096f5e 100644 --- a/tests/nvapi_system.cpp +++ b/tests/nvapi_system.cpp @@ -96,6 +96,7 @@ TEST_CASE("Sysinfo methods succeed against local system", "[system]") { GETNVAPIPROCADDR(GPU_GetAdapterIdFromPhysicalGpu); GETNVAPIPROCADDR(GPU_GetArchInfo); GETNVAPIPROCADDR(GPU_GetCurrentPCIEDownstreamWidth); + GETNVAPIPROCADDR(GPU_GetIRQ); GETNVAPIPROCADDR(GPU_GetGpuCoreCount); GETNVAPIPROCADDR(GPU_CudaEnumComputeCapableGpus); GETNVAPIPROCADDR(GPU_GetVbiosVersionString); @@ -121,6 +122,7 @@ TEST_CASE("Sysinfo methods succeed against local system", "[system]") { REQUIRE(nvAPI_GPU_GetAdapterIdFromPhysicalGpu); REQUIRE(nvAPI_GPU_GetArchInfo); REQUIRE(nvAPI_GPU_GetCurrentPCIEDownstreamWidth); + REQUIRE(nvAPI_GPU_GetIRQ); REQUIRE(nvAPI_GPU_GetGpuCoreCount); REQUIRE(nvAPI_GPU_CudaEnumComputeCapableGpus); REQUIRE(nvAPI_GPU_GetVbiosVersionString); @@ -230,6 +232,14 @@ TEST_CASE("Sysinfo methods succeed against local system", "[system]") { else std::cout << "N/A" << std::endl; + NvU32 gpuIrq; + result = nvAPI_GPU_GetIRQ(handle, &gpuIrq); + std::cout << " IRQ: "; + if (result == NVAPI_OK) + std::cout << std::dec << gpuIrq << std::endl; + else + std::cout << "N/A" << std::endl; + auto computeGpusIt = std::find_if( std::begin(computeGpus), std::end(computeGpus), |