VMManager: Log power profile and GPUs on startup

This commit is contained in:
Ty Lamontagne 2024-02-17 15:23:45 -05:00 committed by refractionpcsx2
parent 4d23410b99
commit 46e039dab2
2 changed files with 190 additions and 1 deletions

View File

@ -49,6 +49,41 @@ u64 GetCPUTicks()
std::string GetOSVersionString()
{
#if defined(__linux__)
FILE* file = fopen("/etc/os-release", "r");
if (file)
{
char line[256];
std::string distro;
std::string version = "";
while (fgets(line, sizeof(line), file))
{
std::string_view line_view(line);
if (line_view.starts_with("NAME="))
{
distro = line_view.substr(5, line_view.size() - 6);
}
else if (line_view.starts_with("BUILD_ID="))
{
version = line_view.substr(9, line_view.size() - 10);
}
else if (line_view.starts_with("VERSION_ID="))
{
version = line_view.substr(11, line_view.size() - 12);
}
}
fclose(file);
// Some distros put quotes around the name and or version.
if (distro.starts_with("\"") && distro.ends_with("\""))
distro = distro.substr(1, distro.size() - 2);
if (version.starts_with("\"") && version.ends_with("\""))
version = version.substr(1, version.size() - 2);
if (!distro.empty() && !version.empty())
return fmt::format("{} {}", distro, version);
}
return "Linux";
#else // freebsd
return "Other Unix";

View File

@ -65,6 +65,9 @@
#include "common/RedtapeWindows.h"
#include <objbase.h>
#include <timeapi.h>
#include <powrprof.h>
#include <wil/com.h>
#include <dxgi.h>
#endif
#ifdef __APPLE__
@ -2237,6 +2240,151 @@ bool VMManager::IsLoadableFileName(const std::string_view& path)
return IsDiscFileName(path) || IsElfFileName(path) || IsGSDumpFileName(path) || IsBlockDumpFileName(path);
}
#ifdef _WIN32
inline void LogUserPowerPlan()
{
wil::unique_any<GUID*, decltype(&::LocalFree), ::LocalFree> pPwrGUID;
DWORD ret = PowerGetActiveScheme(NULL, pPwrGUID.put());
if (ret != ERROR_SUCCESS)
return;
UCHAR aBuffer[2048];
DWORD aBufferSize = sizeof(aBuffer);
ret = PowerReadFriendlyName(NULL, pPwrGUID.get(), &NO_SUBGROUP_GUID, NULL, aBuffer, &aBufferSize);
std::string friendlyName(StringUtil::WideStringToUTF8String((wchar_t*)aBuffer));
if (ret != ERROR_SUCCESS)
return;
DWORD acMax = 0, acMin = 0, dcMax = 0, dcMin = 0;
if (PowerReadACValueIndex(NULL, pPwrGUID.get(), &GUID_PROCESSOR_SETTINGS_SUBGROUP, &GUID_PROCESSOR_THROTTLE_MAXIMUM, &acMax) ||
PowerReadACValueIndex(NULL, pPwrGUID.get(), &GUID_PROCESSOR_SETTINGS_SUBGROUP, &GUID_PROCESSOR_THROTTLE_MINIMUM, &acMin) ||
PowerReadDCValueIndex(NULL, pPwrGUID.get(), &GUID_PROCESSOR_SETTINGS_SUBGROUP, &GUID_PROCESSOR_THROTTLE_MAXIMUM, &dcMax) ||
PowerReadDCValueIndex(NULL, pPwrGUID.get(), &GUID_PROCESSOR_SETTINGS_SUBGROUP, &GUID_PROCESSOR_THROTTLE_MINIMUM, &dcMin))
return;
Console.WriteLnFmt(
" Power Profile = '{}'\n"
" Power States (min/max)\n"
" AC = {}% / {}%\n"
" Battery = {}% / {}%\n", friendlyName.c_str(), acMin, acMax, dcMin, dcMax);
}
#endif
#if defined(__linux__) || defined(_WIN32)
void LogGPUCapabilities()
{
Console.WriteLn(Color_StrongBlack, "Graphics Adapters Detected:");
#if defined(_WIN32)
IDXGIFactory1* pFactory = nullptr;
if (FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory)))
return;
UINT i = 0;
IDXGIAdapter* pAdapter = nullptr;
while (pFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND)
{
DXGI_ADAPTER_DESC desc;
LARGE_INTEGER umdver;
if (SUCCEEDED(pAdapter->GetDesc(&desc)) && SUCCEEDED(pAdapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &umdver)))
{
Console.WriteLnFmt(
" GPU = {}\n"
" Driver Version = {}.{}.{}.{}\n",
StringUtil::WideStringToUTF8String(desc.Description),
umdver.QuadPart >> 48,
(umdver.QuadPart >> 32) & 0xFFFF,
(umdver.QuadPart >> 16) & 0xFFFF,
umdver.QuadPart & 0xFFFF);
i++;
pAdapter->Release();
pAdapter = nullptr;
}
else
{
pAdapter->Release();
pAdapter = nullptr;
break;
}
}
if (pAdapter)
pAdapter->Release();
pFactory->Release();
#else
// Credits to neofetch for the following (modified) script
std::string gpu_script = R"gpu_script(
lspci -mm |
awk -F '\"|\" \"|\\(' \
'/"Display|"3D|"VGA/ {
a[$0] = $1 "" $3 " " ($(NF-1) ~ /^$|^Device [[:xdigit:]]+$/ ? $4 : $(NF-1))
}
END { for (i in a) {
if (!seen[a[i]]++) {
sub("^[^ ]+ ", "", a[i]);
print a[i]
}
}}'
)gpu_script";
FILE* f = popen(gpu_script.c_str(), "r");
if (f)
{
char buffer[1024];
while (fgets(buffer, sizeof(buffer), f))
{
std::string card(buffer);
std::string version = "Unknown\n";
if (card.find("NVIDIA") != std::string::npos)
{
// Assumes that all NVIDIA cards use the same driver
FILE* fnsmi = popen("nvidia-smi --query-gpu=driver_version --format=csv,noheader", "r");
if (fnsmi)
{
if (fgets(buffer, sizeof(buffer), fnsmi))
{
version = std::string(buffer);
}
pclose(fnsmi);
}
}
else
{
// Assuming non-NVIDIA cards are using the mesa driver
FILE* fglxinfo = popen("glxinfo | sed -n 's/OpenGL version string:/OGL/p'", "r");
if (fglxinfo)
{
if (fgets(buffer, sizeof(buffer), fglxinfo))
{
version = std::string(buffer);
// This path is taken if the card was Intel or AMD
// If glxinfo is reporting NVIDIA, then it's likely that this is a multi-gpu system
// and that this version doesn't apply to this AMD / Intel device
// Alternatively we could use vulkaninfo, which allows us to select the device
// But I was unable to get that to work on my system
// So for now, we cannot get the iGPU version on NVIDIA dGPU systems
if (version.find("NVIDIA") != std::string::npos)
{
version = "Unknown (OpenGL default is NVIDIA)\n";
}
}
pclose(fglxinfo);
}
}
Console.WriteLnFmt(
" GPU = {}"
" Driver Version = {}",
card, version);
}
pclose(f);
}
#endif
}
#endif
void VMManager::LogCPUCapabilities()
{
Console.WriteLn(Color_StrongGreen, "PCSX2 " GIT_REV);
@ -2254,7 +2402,9 @@ void VMManager::LogCPUCapabilities()
Console.WriteLnFmt(" Processor = {}", cpuinfo_get_package(0)->name);
Console.WriteLnFmt(" Core Count = {} cores", cpuinfo_get_cores_count());
Console.WriteLnFmt(" Thread Count = {} threads", cpuinfo_get_processors_count());
Console.WriteLn();
#ifdef _WIN32
LogUserPowerPlan();
#endif
std::string features;
if (cpuinfo_has_x86_avx())
@ -2267,6 +2417,10 @@ void VMManager::LogCPUCapabilities()
Console.WriteLn(Color_StrongBlack, "x86 Features Detected:");
Console.WriteLnFmt(" {}", features);
Console.WriteLn();
#if defined(__linux__) || defined(_WIN32)
LogGPUCapabilities();
#endif
}