Separate libdrm and libdrm_amdgpu loader

This commit is contained in:
jackun 2021-08-12 16:21:37 +03:00
parent 822e325d11
commit a431c092eb
No known key found for this signature in database
GPG Key ID: 119DB3F1D05A9ED3
3 changed files with 146 additions and 81 deletions

View File

@ -148,10 +148,10 @@ enum {
GRBM_STATUS = 0x8010,
};
static std::unique_ptr<libdrm_loader> libdrm_ptr;
static std::unique_ptr<libdrm_amdgpu_loader> 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<libdrm_loader>();
if (!g_libdrm.IsLoaded())
return false;
if (!libdrm_ptr->IsLoaded())
if (!libdrm_amdgpu_ptr)
libdrm_amdgpu_ptr = std::make_unique<libdrm_amdgpu_loader>();
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

View File

@ -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_cast<decltype(this->drmGetVersion)>(
dlsym(library_drm, "drmGetVersion"));
dlsym(library, "drmGetVersion"));
if (!drmGetVersion) {
CleanUp(true);
return false;
@ -49,48 +42,16 @@ bool libdrm_loader::Load() {
drmFreeVersion =
reinterpret_cast<decltype(this->drmFreeVersion)>(
dlsym(library_drm, "drmFreeVersion"));
dlsym(library, "drmFreeVersion"));
if (!drmFreeVersion) {
CleanUp(true);
return false;
}
amdgpu_device_initialize =
reinterpret_cast<decltype(this->amdgpu_device_initialize)>(
dlsym(library_amdgpu, "amdgpu_device_initialize"));
if (!amdgpu_device_initialize) {
CleanUp(true);
return false;
}
amdgpu_device_deinitialize =
reinterpret_cast<decltype(this->amdgpu_device_deinitialize)>(
dlsym(library_amdgpu, "amdgpu_device_deinitialize"));
if (!amdgpu_device_deinitialize) {
CleanUp(true);
return false;
}
amdgpu_query_info =
reinterpret_cast<decltype(this->amdgpu_query_info)>(
dlsym(library_amdgpu, "amdgpu_query_info"));
if (!amdgpu_query_info) {
CleanUp(true);
return false;
}
amdgpu_query_sensor_info =
reinterpret_cast<decltype(this->amdgpu_query_sensor_info)>(
dlsym(library_amdgpu, "amdgpu_query_sensor_info"));
if (!amdgpu_query_sensor_info) {
CleanUp(true);
return false;
}
amdgpu_read_mm_registers =
reinterpret_cast<decltype(this->amdgpu_read_mm_registers)>(
dlsym(library_amdgpu, "amdgpu_read_mm_registers"));
if (!amdgpu_read_mm_registers) {
drmCommandWriteRead =
reinterpret_cast<decltype(this->drmCommandWriteRead)>(
dlsym(library, "drmCommandWriteRead"));
if (!drmCommandWriteRead) {
CleanUp(true);
return false;
}
@ -100,7 +61,91 @@ bool libdrm_loader::Load() {
#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_cast<decltype(this->amdgpu_device_initialize)>(
dlsym(library, "amdgpu_device_initialize"));
if (!amdgpu_device_initialize) {
CleanUp(true);
return false;
}
amdgpu_device_deinitialize =
reinterpret_cast<decltype(this->amdgpu_device_deinitialize)>(
dlsym(library, "amdgpu_device_deinitialize"));
if (!amdgpu_device_deinitialize) {
CleanUp(true);
return false;
}
amdgpu_query_info =
reinterpret_cast<decltype(this->amdgpu_query_info)>(
dlsym(library, "amdgpu_query_info"));
if (!amdgpu_query_info) {
CleanUp(true);
return false;
}
amdgpu_query_sensor_info =
reinterpret_cast<decltype(this->amdgpu_query_sensor_info)>(
dlsym(library, "amdgpu_query_sensor_info"));
if (!amdgpu_query_sensor_info) {
CleanUp(true);
return false;
}
amdgpu_read_mm_registers =
reinterpret_cast<decltype(this->amdgpu_read_mm_registers)>(
dlsym(library, "amdgpu_read_mm_registers"));
if (!amdgpu_read_mm_registers) {
CleanUp(true);
return false;
}
#endif
#if defined(LIBRARY_LOADER_LIBDRM_H_DT_NEEDED)
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;

View File

@ -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