diff --git a/src/gpu.cpp b/src/gpu.cpp index bddefd6..ca69b4d 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -148,10 +148,10 @@ enum { GRBM_STATUS = 0x8010, }; -static std::unique_ptr libdrm_ptr; +static std::unique_ptr libdrm_amdgpu_ptr; static int getgrbm_amdgpu(amdgpu_device_handle dev, uint32_t *out) { - return libdrm_ptr->amdgpu_read_mm_registers(dev, GRBM_STATUS / 4, 1, + return libdrm_amdgpu_ptr->amdgpu_read_mm_registers(dev, GRBM_STATUS / 4, 1, 0xffffffff, 0, out); } @@ -181,7 +181,7 @@ struct amdgpu_handles quit = true; if (collector.joinable()) collector.join(); - libdrm_ptr->amdgpu_device_deinitialize(dev); + libdrm_amdgpu_ptr->amdgpu_device_deinitialize(dev); close(fd); } @@ -225,10 +225,13 @@ void amdgpu_set_sampling_period(uint32_t period) } bool amdgpu_open(const char *path) { - if (!libdrm_ptr) - libdrm_ptr = std::make_unique(); + if (!g_libdrm.IsLoaded()) + return false; + + if (!libdrm_amdgpu_ptr) + libdrm_amdgpu_ptr = std::make_unique(); - if (!libdrm_ptr->IsLoaded()) + if (!libdrm_amdgpu_ptr->IsLoaded()) return false; int fd = open(path, O_RDWR | O_CLOEXEC); @@ -238,7 +241,7 @@ bool amdgpu_open(const char *path) { return false; } - drmVersionPtr ver = libdrm_ptr->drmGetVersion(fd); + drmVersionPtr ver = g_libdrm.drmGetVersion(fd); if (!ver) { SPDLOG_ERROR("Failed to query driver version: {}", strerror(errno)); @@ -249,10 +252,10 @@ bool amdgpu_open(const char *path) { if (strcmp(ver->name, "amdgpu") || !DRM_ATLEAST_VERSION(ver, 3, 11)) { SPDLOG_ERROR("Unsupported driver/version: {} {}.{}.{}", ver->name, ver->version_major, ver->version_minor, ver->version_patchlevel); close(fd); - libdrm_ptr->drmFreeVersion(ver); + g_libdrm.drmFreeVersion(ver); return false; } - libdrm_ptr->drmFreeVersion(ver); + g_libdrm.drmFreeVersion(ver); /* if (!authenticate_drm(fd)) { @@ -263,7 +266,7 @@ bool amdgpu_open(const char *path) { uint32_t drm_major, drm_minor; amdgpu_device_handle dev; - if (libdrm_ptr->amdgpu_device_initialize(fd, &drm_major, &drm_minor, &dev)){ + if (libdrm_amdgpu_ptr->amdgpu_device_initialize(fd, &drm_major, &drm_minor, &dev)){ SPDLOG_ERROR("Failed to initialize amdgpu device: {}", strerror(errno)); close(fd); return false; @@ -278,37 +281,34 @@ void getAmdGpuInfo_libdrm() uint64_t value = 0; uint32_t value32 = 0; - if (!DRM_ATLEAST_VERSION(amdgpu_dev, 3, 11)) + if (!amdgpu_dev || !DRM_ATLEAST_VERSION(amdgpu_dev, 3, 11)) { getAmdGpuInfo(); getAmdGpuInfo_actual = getAmdGpuInfo; return; } - if (!libdrm_ptr || !libdrm_ptr->IsLoaded()) - return; - - if (!libdrm_ptr->amdgpu_query_info(amdgpu_dev->dev, AMDGPU_INFO_VRAM_USAGE, sizeof(uint64_t), &value)) + if (!libdrm_amdgpu_ptr->amdgpu_query_info(amdgpu_dev->dev, AMDGPU_INFO_VRAM_USAGE, sizeof(uint64_t), &value)) gpu_info.memoryUsed = float(value) / (1024 * 1024 * 1024); // FIXME probably not correct sensor - if (!libdrm_ptr->amdgpu_query_info(amdgpu_dev->dev, AMDGPU_INFO_MEMORY, sizeof(uint64_t), &value)) + if (!libdrm_amdgpu_ptr->amdgpu_query_info(amdgpu_dev->dev, AMDGPU_INFO_MEMORY, sizeof(uint64_t), &value)) gpu_info.memoryTotal = float(value) / (1024 * 1024 * 1024); - if (!libdrm_ptr->amdgpu_query_sensor_info(amdgpu_dev->dev, AMDGPU_INFO_SENSOR_GFX_SCLK, sizeof(uint32_t), &value32)) + if (!libdrm_amdgpu_ptr->amdgpu_query_sensor_info(amdgpu_dev->dev, AMDGPU_INFO_SENSOR_GFX_SCLK, sizeof(uint32_t), &value32)) gpu_info.CoreClock = value32; - if (!libdrm_ptr->amdgpu_query_sensor_info(amdgpu_dev->dev, AMDGPU_INFO_SENSOR_GFX_MCLK, sizeof(uint32_t), &value32)) // XXX Doesn't work on APUs + if (!libdrm_amdgpu_ptr->amdgpu_query_sensor_info(amdgpu_dev->dev, AMDGPU_INFO_SENSOR_GFX_MCLK, sizeof(uint32_t), &value32)) // XXX Doesn't work on APUs gpu_info.MemClock = value32; - //if (!libdrm_ptr->amdgpu_query_sensor_info(amdgpu_dev->dev, AMDGPU_INFO_SENSOR_GPU_LOAD, sizeof(uint32_t), &value32)) + //if (!libdrm_amdgpu_ptr->amdgpu_query_sensor_info(amdgpu_dev->dev, AMDGPU_INFO_SENSOR_GPU_LOAD, sizeof(uint32_t), &value32)) // gpu_info.load = value32; gpu_info.load = amdgpu_dev->gui_percent; - if (!libdrm_ptr->amdgpu_query_sensor_info(amdgpu_dev->dev, AMDGPU_INFO_SENSOR_GPU_TEMP, sizeof(uint32_t), &value32)) + if (!libdrm_amdgpu_ptr->amdgpu_query_sensor_info(amdgpu_dev->dev, AMDGPU_INFO_SENSOR_GPU_TEMP, sizeof(uint32_t), &value32)) gpu_info.temp = value32 / 1000; - if (!libdrm_ptr->amdgpu_query_sensor_info(amdgpu_dev->dev, AMDGPU_INFO_SENSOR_GPU_AVG_POWER, sizeof(uint32_t), &value32)) + if (!libdrm_amdgpu_ptr->amdgpu_query_sensor_info(amdgpu_dev->dev, AMDGPU_INFO_SENSOR_GPU_AVG_POWER, sizeof(uint32_t), &value32)) gpu_info.powerUsage = value32; } #endif diff --git a/src/loaders/loader_libdrm.cpp b/src/loaders/loader_libdrm.cpp index 595104d..f28525b 100644 --- a/src/loaders/loader_libdrm.cpp +++ b/src/loaders/loader_libdrm.cpp @@ -26,22 +26,15 @@ bool libdrm_loader::Load() { } #if defined(LIBRARY_LOADER_LIBDRM_H_DLOPEN) - library_drm = dlopen("libdrm.so.2", RTLD_LAZY); - if (!library_drm) { + library = dlopen("libdrm.so.2", RTLD_LAZY); + if (!library) { SPDLOG_ERROR("Failed to open " MANGOHUD_ARCH " libdrm.so.2: {}", dlerror()); return false; } - library_amdgpu = dlopen("libdrm_amdgpu.so.1", RTLD_LAZY); - if (!library_amdgpu) { - SPDLOG_ERROR("Failed to open " MANGOHUD_ARCH " libdrm_amdgpu.so.1: {}", dlerror()); - CleanUp(true); - return false; - } - drmGetVersion = reinterpret_castdrmGetVersion)>( - dlsym(library_drm, "drmGetVersion")); + dlsym(library, "drmGetVersion")); if (!drmGetVersion) { CleanUp(true); return false; @@ -49,15 +42,70 @@ bool libdrm_loader::Load() { drmFreeVersion = reinterpret_castdrmFreeVersion)>( - dlsym(library_drm, "drmFreeVersion")); + dlsym(library, "drmFreeVersion")); if (!drmFreeVersion) { CleanUp(true); return false; } + drmCommandWriteRead = + reinterpret_castdrmCommandWriteRead)>( + dlsym(library, "drmCommandWriteRead")); + if (!drmCommandWriteRead) { + CleanUp(true); + return false; + } + +#endif + +#if defined(LIBRARY_LOADER_LIBDRM_H_DT_NEEDED) + drmGetVersion = &::drmGetVersion; + drmFreeVersion = &::drmFreeVersion; + drmCommandWriteRead = &::drmCommandWriteRead; +#endif + + loaded_ = true; + return true; +} + +void libdrm_loader::CleanUp(bool unload) { +#if defined(LIBRARY_LOADER_LIBDRM_H_DLOPEN) + if (unload) { + dlclose(library); + library = nullptr; + } +#endif + loaded_ = false; + drmGetVersion = nullptr; + drmFreeVersion = nullptr; + drmCommandWriteRead = nullptr; + +} + +libdrm_amdgpu_loader::libdrm_amdgpu_loader() : loaded_(false) { + Load(); +} + +libdrm_amdgpu_loader::~libdrm_amdgpu_loader() { + CleanUp(loaded_); +} + +bool libdrm_amdgpu_loader::Load() { + if (loaded_) { + return true; + } + +#if defined(LIBRARY_LOADER_LIBDRM_H_DLOPEN) + library = dlopen("libdrm_amdgpu.so.1", RTLD_LAZY); + if (!library) { + SPDLOG_ERROR("Failed to open " MANGOHUD_ARCH " libdrm_amdgpu.so.1: {}", dlerror()); + CleanUp(true); + return false; + } + amdgpu_device_initialize = reinterpret_castamdgpu_device_initialize)>( - dlsym(library_amdgpu, "amdgpu_device_initialize")); + dlsym(library, "amdgpu_device_initialize")); if (!amdgpu_device_initialize) { CleanUp(true); return false; @@ -65,7 +113,7 @@ bool libdrm_loader::Load() { amdgpu_device_deinitialize = reinterpret_castamdgpu_device_deinitialize)>( - dlsym(library_amdgpu, "amdgpu_device_deinitialize")); + dlsym(library, "amdgpu_device_deinitialize")); if (!amdgpu_device_deinitialize) { CleanUp(true); return false; @@ -73,7 +121,7 @@ bool libdrm_loader::Load() { amdgpu_query_info = reinterpret_castamdgpu_query_info)>( - dlsym(library_amdgpu, "amdgpu_query_info")); + dlsym(library, "amdgpu_query_info")); if (!amdgpu_query_info) { CleanUp(true); return false; @@ -81,7 +129,7 @@ bool libdrm_loader::Load() { amdgpu_query_sensor_info = reinterpret_castamdgpu_query_sensor_info)>( - dlsym(library_amdgpu, "amdgpu_query_sensor_info")); + dlsym(library, "amdgpu_query_sensor_info")); if (!amdgpu_query_sensor_info) { CleanUp(true); return false; @@ -89,7 +137,7 @@ bool libdrm_loader::Load() { amdgpu_read_mm_registers = reinterpret_castamdgpu_read_mm_registers)>( - dlsym(library_amdgpu, "amdgpu_read_mm_registers")); + dlsym(library, "amdgpu_read_mm_registers")); if (!amdgpu_read_mm_registers) { CleanUp(true); return false; @@ -98,9 +146,6 @@ bool libdrm_loader::Load() { #endif #if defined(LIBRARY_LOADER_LIBDRM_H_DT_NEEDED) - drmGetVersion = &::drmGetVersion; - drmFreeVersion = &::drmFreeVersion; - amdgpu_device_initialize = &::amdgpu_device_initialize; amdgpu_device_deinitialize = &::amdgpu_device_deinitialize; amdgpu_query_info = &::amdgpu_query_info; @@ -113,20 +158,14 @@ bool libdrm_loader::Load() { return true; } -void libdrm_loader::CleanUp(bool unload) { +void libdrm_amdgpu_loader::CleanUp(bool unload) { #if defined(LIBRARY_LOADER_LIBDRM_H_DLOPEN) if (unload) { - dlclose(library_drm); - library_drm = nullptr; - if (library_amdgpu) - dlclose(library_amdgpu); - library_amdgpu = nullptr; + dlclose(library); + library = nullptr; } #endif loaded_ = false; - drmGetVersion = nullptr; - drmFreeVersion = nullptr; - amdgpu_device_initialize = nullptr; amdgpu_device_deinitialize = nullptr; amdgpu_query_info = nullptr; @@ -134,3 +173,5 @@ void libdrm_loader::CleanUp(bool unload) { amdgpu_read_mm_registers = nullptr; } + +libdrm_loader g_libdrm; diff --git a/src/loaders/loader_libdrm.h b/src/loaders/loader_libdrm.h index 6da4464..897e571 100644 --- a/src/loaders/loader_libdrm.h +++ b/src/loaders/loader_libdrm.h @@ -33,6 +33,29 @@ class libdrm_loader { decltype(&::drmGetVersion) drmGetVersion; decltype(&::drmFreeVersion) drmFreeVersion; + decltype(&::drmCommandWriteRead) drmCommandWriteRead; + + private: + void CleanUp(bool unload); + +#if defined(LIBRARY_LOADER_LIBDRM_H_DLOPEN) + void* library; +#endif + + bool loaded_; + + // Disallow copy constructor and assignment operator. + libdrm_loader(const libdrm_loader&); + void operator=(const libdrm_loader&); +}; + +class libdrm_amdgpu_loader { + public: + libdrm_amdgpu_loader(); + ~libdrm_amdgpu_loader(); + + bool Load(); + bool IsLoaded() { return loaded_; } decltype(&::amdgpu_device_initialize) amdgpu_device_initialize; decltype(&::amdgpu_device_deinitialize) amdgpu_device_deinitialize; @@ -44,15 +67,16 @@ class libdrm_loader { void CleanUp(bool unload); #if defined(LIBRARY_LOADER_LIBDRM_H_DLOPEN) - void* library_drm; - void* library_amdgpu; + void* library; #endif bool loaded_; // Disallow copy constructor and assignment operator. - libdrm_loader(const libdrm_loader&); - void operator=(const libdrm_loader&); + libdrm_amdgpu_loader(const libdrm_amdgpu_loader&); + void operator=(const libdrm_amdgpu_loader&); }; +extern libdrm_loader g_libdrm; + #endif // LIBRARY_LOADER_LIBDRM_H