wrapadl.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /* Copyright (C) 1883 Thomas Edison - All Rights Reserved
  2. * You may use, distribute and modify this code under the
  3. * terms of the GPLv3 license, which unfortunately won't be
  4. * written for another century.
  5. *
  6. * You should have received a copy of the LICENSE file with
  7. * this file.
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <string>
  13. #include "wrapadl.h"
  14. #include "wraphelper.h"
  15. #if defined(__cplusplus)
  16. extern "C" {
  17. #endif
  18. void* ADL_API_CALL ADL_Main_Memory_Alloc(int iSize) {
  19. void* lpBuffer = malloc(iSize);
  20. return lpBuffer;
  21. }
  22. wrap_adl_handle* wrap_adl_create() {
  23. wrap_adl_handle* adlh = nullptr;
  24. #if defined(_WIN32)
  25. /* Windows */
  26. #define libatiadlxx "atiadlxx.dll"
  27. #elif defined(__linux) && (defined(__i386__) || defined(__ARM_ARCH_7A__))
  28. /* 32-bit linux assumed */
  29. #define libatiadlxx "libatiadlxx.so"
  30. #elif defined(__linux)
  31. /* 64-bit linux assumed */
  32. #define libatiadlxx "libatiadlxx.so"
  33. #else
  34. #define libatiadlxx ""
  35. #warning "Unrecognized platform: need ADL DLL path for this platform..."
  36. return nullptr;
  37. #endif
  38. #ifdef _WIN32
  39. char tmp[512];
  40. ExpandEnvironmentStringsA(libatiadlxx, tmp, sizeof(tmp));
  41. #else
  42. char tmp[512] = libatiadlxx;
  43. #endif
  44. void* adl_dll = wrap_dlopen(tmp);
  45. if (adl_dll == nullptr) {
  46. cwarn << "Failed to obtain all required ADL function pointers";
  47. cwarn << "AMD hardware monitoring disabled";
  48. return nullptr;
  49. }
  50. adlh = (wrap_adl_handle*)calloc(1, sizeof(wrap_adl_handle));
  51. adlh->adl_dll = adl_dll;
  52. adlh->adlMainControlCreate =
  53. (wrap_adlReturn_t(*)(ADL_MAIN_MALLOC_CALLBACK, int))wrap_dlsym(adlh->adl_dll, "ADL_Main_Control_Create");
  54. adlh->adlAdapterNumberOfAdapters =
  55. (wrap_adlReturn_t(*)(int*))wrap_dlsym(adlh->adl_dll, "ADL_Adapter_NumberOfAdapters_Get");
  56. adlh->adlAdapterAdapterInfoGet =
  57. (wrap_adlReturn_t(*)(LPAdapterInfo, int))wrap_dlsym(adlh->adl_dll, "ADL_Adapter_AdapterInfo_Get");
  58. adlh->adlAdapterAdapterIdGet = (wrap_adlReturn_t(*)(int, int*))wrap_dlsym(adlh->adl_dll, "ADL_Adapter_ID_Get");
  59. adlh->adlOverdrive5TemperatureGet =
  60. (wrap_adlReturn_t(*)(int, int, ADLTemperature*))wrap_dlsym(adlh->adl_dll, "ADL_Overdrive5_Temperature_Get");
  61. adlh->adlOverdrive5FanSpeedGet =
  62. (wrap_adlReturn_t(*)(int, int, ADLFanSpeedValue*))wrap_dlsym(adlh->adl_dll, "ADL_Overdrive5_FanSpeed_Get");
  63. adlh->adlMainControlRefresh = (wrap_adlReturn_t(*)(void))wrap_dlsym(adlh->adl_dll, "ADL_Main_Control_Refresh");
  64. adlh->adlMainControlDestroy = (wrap_adlReturn_t(*)(void))wrap_dlsym(adlh->adl_dll, "ADL_Main_Control_Destroy");
  65. adlh->adl2MainControlCreate = (wrap_adlReturn_t(*)(ADL_MAIN_MALLOC_CALLBACK, int, ADL_CONTEXT_HANDLE*))wrap_dlsym(
  66. adlh->adl_dll, "ADL2_Main_Control_Create");
  67. adlh->adl2MainControlDestroy =
  68. (wrap_adlReturn_t(*)(ADL_CONTEXT_HANDLE))wrap_dlsym(adlh->adl_dll, "ADL_Main_Control_Destroy");
  69. adlh->adl2Overdrive6CurrentPowerGet = (wrap_adlReturn_t(*)(ADL_CONTEXT_HANDLE, int, int, int*))wrap_dlsym(
  70. adlh->adl_dll, "ADL2_Overdrive6_CurrentPower_Get");
  71. adlh->adl2MainControlRefresh =
  72. (wrap_adlReturn_t(*)(ADL_CONTEXT_HANDLE))wrap_dlsym(adlh->adl_dll, "ADL2_Main_Control_Refresh");
  73. if (adlh->adlMainControlCreate == nullptr || adlh->adlMainControlDestroy == nullptr ||
  74. adlh->adlMainControlRefresh == nullptr || adlh->adlAdapterNumberOfAdapters == nullptr ||
  75. adlh->adlAdapterAdapterInfoGet == nullptr || adlh->adlAdapterAdapterIdGet == nullptr ||
  76. adlh->adlOverdrive5TemperatureGet == nullptr || adlh->adlOverdrive5FanSpeedGet == nullptr ||
  77. adlh->adl2MainControlCreate == nullptr || adlh->adl2MainControlRefresh == nullptr ||
  78. adlh->adl2MainControlDestroy == nullptr || adlh->adl2Overdrive6CurrentPowerGet == nullptr) {
  79. cwarn << "Failed to obtain all required ADL function pointers";
  80. cwarn << "AMD hardware monitoring disabled";
  81. wrap_dlclose(adlh->adl_dll);
  82. free(adlh);
  83. return nullptr;
  84. }
  85. adlh->adlMainControlCreate(ADL_Main_Memory_Alloc, 1);
  86. adlh->adlMainControlRefresh();
  87. adlh->context = nullptr;
  88. adlh->adl2MainControlCreate(ADL_Main_Memory_Alloc, 1, &(adlh->context));
  89. adlh->adl2MainControlRefresh(adlh->context);
  90. int logicalGpuCount = 0;
  91. adlh->adlAdapterNumberOfAdapters(&logicalGpuCount);
  92. adlh->phys_logi_device_id = (int*)calloc(logicalGpuCount, sizeof(int));
  93. adlh->adl_gpucount = 0;
  94. int last_adapter = 0;
  95. if (logicalGpuCount > 0) {
  96. adlh->log_gpucount = logicalGpuCount;
  97. adlh->devs = (LPAdapterInfo)malloc(sizeof(AdapterInfo) * logicalGpuCount);
  98. memset(adlh->devs, '\0', sizeof(AdapterInfo) * logicalGpuCount);
  99. adlh->devs->iSize = sizeof(adlh->devs);
  100. int res = adlh->adlAdapterAdapterInfoGet(adlh->devs, sizeof(AdapterInfo) * logicalGpuCount);
  101. if (res != WRAPADL_OK) {
  102. cwarn << "Failed to obtain using adlAdapterAdapterInfoGet().";
  103. cwarn << "AMD hardware monitoring disabled";
  104. wrap_dlclose(adlh->adl_dll);
  105. free(adlh);
  106. return nullptr;
  107. }
  108. for (int i = 0; i < logicalGpuCount; i++) {
  109. int adapterIndex = adlh->devs[i].iAdapterIndex;
  110. int adapterID = 0;
  111. res = adlh->adlAdapterAdapterIdGet(adapterIndex, &adapterID);
  112. if (res != WRAPADL_OK) {
  113. continue;
  114. }
  115. adlh->phys_logi_device_id[adlh->adl_gpucount] = adapterIndex;
  116. if (adapterID == last_adapter) {
  117. continue;
  118. }
  119. last_adapter = adapterID;
  120. adlh->adl_gpucount++;
  121. }
  122. }
  123. return adlh;
  124. }
  125. int wrap_adl_destroy(wrap_adl_handle* adlh) {
  126. adlh->adlMainControlDestroy();
  127. adlh->adl2MainControlDestroy(adlh->context);
  128. wrap_dlclose(adlh->adl_dll);
  129. free(adlh);
  130. return 0;
  131. }
  132. int wrap_adl_get_gpucount(wrap_adl_handle* adlh, int* gpucount) {
  133. *gpucount = adlh->adl_gpucount;
  134. return 0;
  135. }
  136. int wrap_adl_get_gpu_name(wrap_adl_handle* adlh, int gpuindex, char* namebuf, int bufsize) {
  137. if (gpuindex < 0 || gpuindex >= adlh->adl_gpucount)
  138. return -1;
  139. memcpy(namebuf, adlh->devs[adlh->phys_logi_device_id[gpuindex]].strAdapterName, bufsize);
  140. return 0;
  141. }
  142. int wrap_adl_get_gpu_pci_id(wrap_adl_handle* adlh, int gpuindex, char* idbuf, int bufsize) {
  143. if (gpuindex < 0 || gpuindex >= adlh->adl_gpucount)
  144. return -1;
  145. char buf[256];
  146. sprintf(buf, "%04x:%02x:%02x",
  147. 0, // Is probably 0
  148. adlh->devs[adlh->phys_logi_device_id[gpuindex]].iBusNumber,
  149. adlh->devs[adlh->phys_logi_device_id[gpuindex]].iDeviceNumber);
  150. memcpy(idbuf, buf, bufsize);
  151. return 0;
  152. }
  153. int wrap_adl_get_tempC(wrap_adl_handle* adlh, int gpuindex, unsigned int* tempC) {
  154. if (gpuindex < 0 || gpuindex >= adlh->adl_gpucount)
  155. return -1;
  156. ADLTemperature* temperature = new ADLTemperature();
  157. if (adlh->adlOverdrive5TemperatureGet(adlh->phys_logi_device_id[gpuindex], 0, temperature) != WRAPADL_OK)
  158. return -1;
  159. *tempC = unsigned(temperature->iTemperature / 1000);
  160. delete temperature;
  161. return 0;
  162. }
  163. int wrap_adl_get_mem_tempC(wrap_adl_handle* adlh, int gpuindex, unsigned int* tempC) {
  164. if (gpuindex < 0 || gpuindex >= adlh->adl_gpucount)
  165. return -1;
  166. ADLTemperature* temperature = new ADLTemperature();
  167. if (adlh->adlOverdrive5TemperatureGet(adlh->phys_logi_device_id[gpuindex], 1, temperature) != WRAPADL_OK)
  168. return -1;
  169. *tempC = unsigned(temperature->iTemperature / 1000);
  170. delete temperature;
  171. return 0;
  172. }
  173. int wrap_adl_get_fanpcnt(wrap_adl_handle* adlh, int gpuindex, unsigned int* fanpcnt) {
  174. if (gpuindex < 0 || gpuindex >= adlh->adl_gpucount)
  175. return -1;
  176. ADLFanSpeedValue* fan = new ADLFanSpeedValue();
  177. fan->iSpeedType = 1;
  178. if (adlh->adlOverdrive5FanSpeedGet(adlh->phys_logi_device_id[gpuindex], 0, fan) != WRAPADL_OK)
  179. return -1;
  180. *fanpcnt = unsigned(fan->iFanSpeed);
  181. delete fan;
  182. return 0;
  183. }
  184. int wrap_adl_get_power_usage(wrap_adl_handle* adlh, int gpuindex, unsigned int* miliwatts) {
  185. if (gpuindex < 0 || gpuindex >= adlh->adl_gpucount)
  186. return -1;
  187. int power = 0;
  188. if (adlh->adl2Overdrive6CurrentPowerGet(adlh->context, adlh->phys_logi_device_id[gpuindex], 0, &power) !=
  189. WRAPADL_OK)
  190. return -1;
  191. *miliwatts = (unsigned int)(power * 3.90625);
  192. return 0;
  193. }
  194. #if defined(__cplusplus)
  195. }
  196. #endif