Use libdrm_amdgpu for amdgpu sensor info, if available
Using plain `open` as `drmOpen` needs bus id check which needs interface 1.4 ioctl which gives EPERM cause only DRM_MASTER can call it :( https://github.com/clbr/radeontop/issues/48#issuecomment-493792404libinput_only
parent
88d801bd7e
commit
c093f9823e
@ -0,0 +1,56 @@
|
||||
/*
|
||||
Inspired by radeontop
|
||||
*/
|
||||
#include "auth.h"
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/dri2.h>
|
||||
#include <xf86drm.h>
|
||||
#include <libdrm/amdgpu_drm.h>
|
||||
#include <libdrm/amdgpu.h>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
/* Try to authenticate the DRM client with help from the X server. */
|
||||
bool authenticate_drm_xcb(drm_magic_t magic) {
|
||||
xcb_connection_t *conn = xcb_connect(NULL, NULL);
|
||||
if (!conn) {
|
||||
return false;
|
||||
}
|
||||
if (xcb_connection_has_error(conn)) {
|
||||
xcb_disconnect(conn);
|
||||
return false;
|
||||
}
|
||||
|
||||
xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
|
||||
xcb_window_t window = screen->root;
|
||||
|
||||
/* Authenticate our client via the X server using the magic. */
|
||||
xcb_dri2_authenticate_cookie_t auth_cookie =
|
||||
xcb_dri2_authenticate(conn, window, magic);
|
||||
xcb_dri2_authenticate_reply_t *auth_reply =
|
||||
xcb_dri2_authenticate_reply(conn, auth_cookie, NULL);
|
||||
free(auth_reply);
|
||||
|
||||
xcb_disconnect(conn);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool authenticate_drm(int fd) {
|
||||
drm_magic_t magic;
|
||||
|
||||
/* Obtain magic for our DRM client. */
|
||||
if (drmGetMagic(fd, &magic) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Try self-authenticate (if we are somehow the master). */
|
||||
if (drmAuthMagic(fd, magic) == 0) {
|
||||
if (drmDropMaster(fd)) {
|
||||
perror("MANGOHUD: Failed to drop DRM master");
|
||||
fprintf(stderr, "\n\tWARNING: other DRM clients will crash on VT switch\n");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return authenticate_drm_xcb(magic);
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include <libdrm/drm.h>
|
||||
|
||||
bool authenticate_drm_xcb(drm_magic_t magic);
|
||||
bool authenticate_drm(int fd);
|
@ -0,0 +1,135 @@
|
||||
|
||||
#include "loaders/loader_libdrm.h"
|
||||
#include <iostream>
|
||||
|
||||
// Put these sanity checks here so that they fire at most once
|
||||
// (to avoid cluttering the build output).
|
||||
#if !defined(LIBRARY_LOADER_LIBDRM_H_DLOPEN) && !defined(LIBRARY_LOADER_LIBDRM_H_DT_NEEDED)
|
||||
#error neither LIBRARY_LOADER_LIBDRM_H_DLOPEN nor LIBRARY_LOADER_LIBDRM_H_DT_NEEDED defined
|
||||
#endif
|
||||
#if defined(LIBRARY_LOADER_LIBDRM_H_DLOPEN) && defined(LIBRARY_LOADER_LIBDRM_H_DT_NEEDED)
|
||||
#error both LIBRARY_LOADER_LIBDRM_H_DLOPEN and LIBRARY_LOADER_LIBDRM_H_DT_NEEDED defined
|
||||
#endif
|
||||
|
||||
libdrm_loader::libdrm_loader() : loaded_(false) {
|
||||
Load();
|
||||
}
|
||||
|
||||
libdrm_loader::~libdrm_loader() {
|
||||
CleanUp(loaded_);
|
||||
}
|
||||
|
||||
bool libdrm_loader::Load() {
|
||||
if (loaded_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(LIBRARY_LOADER_LIBDRM_H_DLOPEN)
|
||||
library_drm = dlopen("libdrm.so.2", RTLD_LAZY);
|
||||
if (!library_drm) {
|
||||
std::cerr << "MANGOHUD: Failed to open " << "" MANGOHUD_ARCH << " libdrm.so.2: " << dlerror() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
library_amdgpu = dlopen("libdrm_amdgpu.so.1", RTLD_LAZY);
|
||||
if (!library_amdgpu) {
|
||||
std::cerr << "MANGOHUD: Failed to open " << "" MANGOHUD_ARCH << " libdrm_amdgpu.so.1: " << dlerror() << std::endl;
|
||||
CleanUp(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
drmGetVersion =
|
||||
reinterpret_cast<decltype(this->drmGetVersion)>(
|
||||
dlsym(library_drm, "drmGetVersion"));
|
||||
if (!drmGetVersion) {
|
||||
CleanUp(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
drmFreeVersion =
|
||||
reinterpret_cast<decltype(this->drmFreeVersion)>(
|
||||
dlsym(library_drm, "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) {
|
||||
CleanUp(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
#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;
|
||||
amdgpu_query_sensor_info = &::amdgpu_query_sensor_info;
|
||||
amdgpu_read_mm_registers = &::amdgpu_read_mm_registers;
|
||||
|
||||
#endif
|
||||
|
||||
loaded_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void libdrm_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;
|
||||
}
|
||||
#endif
|
||||
loaded_ = false;
|
||||
drmGetVersion = nullptr;
|
||||
drmFreeVersion = nullptr;
|
||||
|
||||
amdgpu_device_initialize = nullptr;
|
||||
amdgpu_device_deinitialize = nullptr;
|
||||
amdgpu_query_info = nullptr;
|
||||
amdgpu_query_sensor_info = nullptr;
|
||||
amdgpu_read_mm_registers = nullptr;
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
|
||||
#ifndef LIBRARY_LOADER_LIBDRM_H
|
||||
#define LIBRARY_LOADER_LIBDRM_H
|
||||
|
||||
#define LIBRARY_LOADER_LIBDRM_H_DLOPEN
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <xf86drm.h>
|
||||
//#include <libdrm/amdgpu_drm.h>
|
||||
//#include <libdrm/amdgpu.h>
|
||||
|
||||
typedef struct amdgpu_device *amdgpu_device_handle;
|
||||
int amdgpu_device_initialize(int fd,
|
||||
uint32_t *major_version,
|
||||
uint32_t *minor_version,
|
||||
amdgpu_device_handle *device_handle);
|
||||
int amdgpu_device_deinitialize(amdgpu_device_handle device_handle);
|
||||
int amdgpu_query_info(amdgpu_device_handle dev, unsigned info_id,
|
||||
unsigned size, void *value);
|
||||
int amdgpu_query_sensor_info(amdgpu_device_handle dev, unsigned sensor_type,
|
||||
unsigned size, void *value);
|
||||
int amdgpu_read_mm_registers(amdgpu_device_handle dev, unsigned dword_offset,
|
||||
unsigned count, uint32_t instance, uint32_t flags,
|
||||
uint32_t *values);
|
||||
|
||||
class libdrm_loader {
|
||||
public:
|
||||
libdrm_loader();
|
||||
~libdrm_loader();
|
||||
|
||||
bool Load();
|
||||
bool IsLoaded() { return loaded_; }
|
||||
|
||||
decltype(&::drmGetVersion) drmGetVersion;
|
||||
decltype(&::drmFreeVersion) drmFreeVersion;
|
||||
|
||||
decltype(&::amdgpu_device_initialize) amdgpu_device_initialize;
|
||||
decltype(&::amdgpu_device_deinitialize) amdgpu_device_deinitialize;
|
||||
decltype(&::amdgpu_query_info) amdgpu_query_info;
|
||||
decltype(&::amdgpu_query_sensor_info) amdgpu_query_sensor_info;
|
||||
decltype(&::amdgpu_read_mm_registers) amdgpu_read_mm_registers;
|
||||
|
||||
private:
|
||||
void CleanUp(bool unload);
|
||||
|
||||
#if defined(LIBRARY_LOADER_LIBDRM_H_DLOPEN)
|
||||
void* library_drm;
|
||||
void* library_amdgpu;
|
||||
#endif
|
||||
|
||||
bool loaded_;
|
||||
|
||||
// Disallow copy constructor and assignment operator.
|
||||
libdrm_loader(const libdrm_loader&);
|
||||
void operator=(const libdrm_loader&);
|
||||
};
|
||||
|
||||
#endif // LIBRARY_LOADER_LIBDRM_H
|
Loading…
Reference in New Issue