diff --git a/src/detection/gpu/adl.h b/src/detection/gpu/adl.h index b5d20703e..892a19c18 100644 --- a/src/detection/gpu/adl.h +++ b/src/detection/gpu/adl.h @@ -46,6 +46,14 @@ extern int ADL2_Overdrive6_StateInfo_Get(ADL_CONTEXT_HANDLE context, int iAdapte /// Overdrive 8 functions +// Function to retrieve the Overdrive8 current settings. +extern int ADL2_Overdrive8_Current_Setting_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLOD8CurrentSetting *lpCurrentSetting); + +// Function to retrieve the Overdrive8 current settings. +extern int ADL2_New_QueryPMLogData_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLPMLogDataOutput *lpDataOutput); + +/// Overdrive N functions + // Function to retrieve the OverdriveN capabilities. extern int ADL2_OverdriveN_Capabilities_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNCapabilities* lpODCapabilities); @@ -54,3 +62,6 @@ extern int ADL2_OverdriveN_PerformanceStatus_Get(ADL_CONTEXT_HANDLE context, int // Function to retrieve the current temperature. extern int ADL2_OverdriveN_Temperature_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iTemperatureType, int *iTemperature); + +// Function to retrieve the current GPU clocks settings. +extern int ADL2_OverdriveN_SystemClocks_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNPerformanceLevels *lpODPerformanceLevels); diff --git a/src/detection/gpu/gpu_amd.c b/src/detection/gpu/gpu_amd.c index a6f6a70e8..3a08c45c4 100644 --- a/src/detection/gpu/gpu_amd.c +++ b/src/detection/gpu/gpu_amd.c @@ -51,8 +51,11 @@ struct FFAdlData { FF_LIBRARY_SYMBOL(ADL2_Adapter_ASICFamilyType_Get) FF_LIBRARY_SYMBOL(ADL2_Overdrive_Caps) FF_LIBRARY_SYMBOL(ADL2_OverdriveN_Capabilities_Get) + FF_LIBRARY_SYMBOL(ADL2_OverdriveN_SystemClocks_Get) FF_LIBRARY_SYMBOL(ADL2_OverdriveN_PerformanceStatus_Get) FF_LIBRARY_SYMBOL(ADL2_OverdriveN_Temperature_Get) + FF_LIBRARY_SYMBOL(ADL2_Overdrive8_Current_Setting_Get) + FF_LIBRARY_SYMBOL(ADL2_New_QueryPMLogData_Get) FF_LIBRARY_SYMBOL(ADL2_Overdrive6_CurrentStatus_Get) FF_LIBRARY_SYMBOL(ADL2_Overdrive6_Temperature_Get) FF_LIBRARY_SYMBOL(ADL2_Overdrive6_StateInfo_Get) @@ -90,7 +93,10 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Adapter_ASICFamilyType_Get) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Overdrive_Caps) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_OverdriveN_Capabilities_Get) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_OverdriveN_SystemClocks_Get) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_OverdriveN_PerformanceStatus_Get) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Overdrive8_Current_Setting_Get) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_New_QueryPMLogData_Get) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_OverdriveN_Temperature_Get) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Overdrive6_CurrentStatus_Get) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Overdrive6_Temperature_Get) @@ -163,6 +169,7 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu if (status == ADL_OK) { + FF_DEBUG("Core info - NumCUs: %d, NumPEsPerCU: %d", coreInfo.iNumCUs, coreInfo.iNumPEsPerCU); *result.coreCount = (uint32_t) coreInfo.iNumCUs * (uint32_t) coreInfo.iNumPEsPerCU; FF_DEBUG("Got core count: %u", *result.coreCount); } @@ -179,8 +186,12 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu FF_DEBUG("ADL2_Adapter_DedicatedVRAMUsage_Get returned %s (%d), usage: %d MB", ffAdlStatusToString(status), status, vramUsage); - if (status == ADL_OK) + if (status == ADL_OK) { result.memory->used = (uint64_t) vramUsage * 1024 * 1024; + FF_DEBUG("Dedicated VRAM usage: %llu bytes (%d MB)", result.memory->used, vramUsage); + } else { + FF_DEBUG("Failed to get dedicated VRAM usage"); + } if (result.sharedMemory) { @@ -189,8 +200,14 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu FF_DEBUG("ADL2_Adapter_VRAMUsage_Get returned %s (%d), usage: %d MB", ffAdlStatusToString(status), status, vramUsage); - if (status == ADL_OK) - result.sharedMemory->used = (uint64_t) vramUsage * 1024 * 1024 - result.memory->used; + if (status == ADL_OK) { + uint64_t totalUsage = (uint64_t) vramUsage * 1024 * 1024; + result.sharedMemory->used = totalUsage - result.memory->used; + FF_DEBUG("Total VRAM usage: %llu bytes, Shared VRAM usage: %llu bytes (%llu MB)", + totalUsage, result.sharedMemory->used, result.sharedMemory->used / (1024 * 1024)); + } else { + FF_DEBUG("Failed to get total VRAM usage"); + } } } @@ -202,6 +219,7 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu if (status == ADL_OK) { + FF_DEBUG("Memory info - Type: %s, Size: %lld MB", memoryInfo.strMemoryType, memoryInfo.iMemorySize / 1024 / 1024); ffStrbufSetS(result.memoryType, memoryInfo.strMemoryType); FF_DEBUG("Got memory type: %s", memoryInfo.strMemoryType); } @@ -223,7 +241,8 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu { asicTypes &= valids; // This design is strange *result.type = asicTypes & ADL_ASIC_INTEGRATED ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE; - FF_DEBUG("GPU type: %s", *result.type == FF_GPU_TYPE_INTEGRATED ? "Integrated" : "Discrete"); + FF_DEBUG("GPU type: %s (asicTypes: 0x%x, valids: 0x%x)", + *result.type == FF_GPU_TYPE_INTEGRATED ? "Integrated" : "Discrete", asicTypes, valids); } else { @@ -240,7 +259,7 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu if (result.name) { ffStrbufSetS(result.name, device->strAdapterName); - FF_DEBUG("Setting adapter name: %s", device->strAdapterName); + FF_DEBUG("Setting adapter name: %s; UDID: %s, Present: %d, Exist: %d", device->strAdapterName, device->strUDID, device->iPresent, device->iExist); } int odVersion = 0; @@ -249,23 +268,54 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu int odSupported = 0; int odEnabled = 0; int status = adlData.ffADL2_Overdrive_Caps(adlData.apiHandle, device->iAdapterIndex, &odSupported, &odEnabled, &odVersion); - FF_DEBUG("ADL2_Overdrive_Caps returned %s (%d); supported %d, enabled %d; version %d", ffAdlStatusToString(status), status, odSupported, odEnabled, odVersion); + FF_DEBUG("ADL2_Overdrive_Caps returned %s (%d); supported %d, enabled %d; version %d", + ffAdlStatusToString(status), status, odSupported, odEnabled, odVersion); } - if (odVersion >= 6) + if (odVersion > 8) { FF_DEBUG("Using OverdriveN API (odVersion=%d)", odVersion); if (result.frequency) { + // https://github.com/MaynardMiner/odvii/blob/master/OverdriveN.cpp#L176 ADLODNCapabilities odCapabilities; int status = adlData.ffADL2_OverdriveN_Capabilities_Get(adlData.apiHandle, device->iAdapterIndex, &odCapabilities); FF_DEBUG("ADL2_OverdriveN_Capabilities_Get returned %s (%d)", ffAdlStatusToString(status), status); if (status == ADL_OK) { - *result.frequency = (uint32_t) odCapabilities.sEngineClockRange.iMax / 100; // assume in 10 KHz - FF_DEBUG("Got max engine clock: %u MHz", *result.frequency); + if (odCapabilities.iMaximumNumberOfPerformanceLevels == 0) + { + FF_DEBUG("ADL2_OverdriveN_Capabilities_Get: no performance levels available"); + } + else + { + FF_DEBUG("ODN Capabilities - MaxPerformanceLevels: %d, GPU Clock Range: [%d - %d]", + odCapabilities.iMaximumNumberOfPerformanceLevels, + odCapabilities.sEngineClockRange.iMin, odCapabilities.sEngineClockRange.iMax); + + size_t size = sizeof(ADLODNPerformanceLevels) + sizeof(ADLODNPerformanceLevel) * ((unsigned) odCapabilities.iMaximumNumberOfPerformanceLevels - 1); + FF_AUTO_FREE ADLODNPerformanceLevels* odPerfLevels = malloc(size); + *odPerfLevels = (ADLODNPerformanceLevels) { + .iSize = (int) size, + .iNumberOfPerformanceLevels = odCapabilities.iMaximumNumberOfPerformanceLevels, + }; + int status = adlData.ffADL2_OverdriveN_SystemClocks_Get(adlData.apiHandle, device->iAdapterIndex, odPerfLevels); + FF_DEBUG("ADL2_OverdriveN_SystemClocks_Get returned %s (%d), levels: %d", + ffAdlStatusToString(status), status, odPerfLevels->iNumberOfPerformanceLevels); + + *result.frequency = 0; + for (int i = 0; i < odPerfLevels->iNumberOfPerformanceLevels; i++) + { + uint32_t clock = (uint32_t) odPerfLevels->aLevels[i].iClock; + FF_DEBUG("Performance level %d: engine clock = %u", i, clock); + if (clock > *result.frequency) + *result.frequency = clock; + } + *result.frequency /= 10; // assume in 10 kHz + FF_DEBUG("Got max engine clock: %u MHz", *result.frequency); + } } else { @@ -275,12 +325,17 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu if (result.coreUsage) { - ADLODNPerformanceStatus performanceStatus; + ADLODNPerformanceStatus performanceStatus = {}; int status = adlData.ffADL2_OverdriveN_PerformanceStatus_Get(adlData.apiHandle, device->iAdapterIndex, &performanceStatus); FF_DEBUG("ADL2_OverdriveN_PerformanceStatus_Get returned %s (%d)", ffAdlStatusToString(status), status); if (status == ADL_OK) { + FF_DEBUG("Performance Status - Activity: %d%%, CoreClock: %dMHz, MemoryClock: %dMHz", + performanceStatus.iGPUActivityPercent, + performanceStatus.iCoreClock / 100, + performanceStatus.iMemoryClock / 100); + *result.coreUsage = performanceStatus.iGPUActivityPercent; FF_DEBUG("Got GPU activity: %d%%", performanceStatus.iGPUActivityPercent); } @@ -294,13 +349,13 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu { int milliDegrees = 0; int status = adlData.ffADL2_OverdriveN_Temperature_Get(adlData.apiHandle, device->iAdapterIndex, 1, &milliDegrees); - FF_DEBUG("ADL2_OverdriveN_Temperature_Get returned %s (%d), temperature: %d milliC", - ffAdlStatusToString(status), status, milliDegrees); + FF_DEBUG("ADL2_OverdriveN_Temperature_Get returned %s (%d)", + ffAdlStatusToString(status), status); if (status == ADL_OK) { *result.temp = milliDegrees / 1000.0; - FF_DEBUG("Temperature: %.1f°C", *result.temp); + FF_DEBUG("Temperature: %.1f°C (raw: %d milliC)", *result.temp, milliDegrees); } else { @@ -308,7 +363,82 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu } } } - else + else if (odVersion == 8) + { + FF_DEBUG("Using Overdrive8 API (odVersion=%d)", odVersion); + + if (result.frequency) + { + ADLOD8CurrentSetting currentSetting; + int status = adlData.ffADL2_Overdrive8_Current_Setting_Get(adlData.apiHandle, device->iAdapterIndex, ¤tSetting); + FF_DEBUG("ADL2_Overdrive8_Current_Setting_Get returned %s (%d)", ffAdlStatusToString(status), status); + if (status == ADL_OK) + { + FF_DEBUG("OD8 Settings count: %d", currentSetting.count); + + *result.frequency = (uint32_t) currentSetting.Od8SettingTable[OD8_GFXCLK_FMAX]; + FF_DEBUG("Got max engine clock (OD8 GFXCLK_FMAX): %u MHz", *result.frequency); + } + else + { + FF_DEBUG("Failed to get max frequency information"); + } + } + + if (result.temp || result.coreUsage) + { + ADLPMLogDataOutput pmLogDataOutput; + int status = adlData.ffADL2_New_QueryPMLogData_Get(adlData.apiHandle, device->iAdapterIndex, &pmLogDataOutput); + FF_DEBUG("ADL2_New_QueryPMLogData_Get returned %s (%d)", ffAdlStatusToString(status), status); + if (status == ADL_OK) + { + if (result.temp) + { + ADLSingleSensorData* edge = &pmLogDataOutput.sensors[ADL_PMLOG_TEMPERATURE_EDGE]; + FF_DEBUG("Sensor %d: %s, supported: %d, value: %d", ADL_PMLOG_TEMPERATURE_EDGE, "ADL_PMLOG_TEMPERATURE_EDGE", edge->supported, edge->value); + if (edge->supported) + { + *result.temp = edge->value; + FF_DEBUG("Temperature: %.1f°C", *result.temp); + } + else + { + FF_DEBUG("Sensor %d not supported", ADL_PMLOG_TEMPERATURE_EDGE); + ADLSingleSensorData* hotspot = &pmLogDataOutput.sensors[ADL_PMLOG_TEMPERATURE_EDGE]; + FF_DEBUG("Sensor %d: %s, supported: %d, value: %d", ADL_PMLOG_TEMPERATURE_EDGE, "ADL_PMLOG_TEMPERATURE_EDGE", hotspot->supported, hotspot->value); + if (hotspot->supported) + { + *result.temp = hotspot->value; + FF_DEBUG("Temperature: %.1f°C", *result.temp); + } + else + { + FF_DEBUG("Sensor %d not supported", PMLOG_TEMPERATURE_HOTSPOT); + } + } + } + if (result.coreUsage) + { + ADLSingleSensorData* activity = &pmLogDataOutput.sensors[ADL_PMLOG_INFO_ACTIVITY_GFX]; + FF_DEBUG("Sensor %d: %s, supported: %d, value: %d", ADL_PMLOG_INFO_ACTIVITY_GFX, "ADL_PMLOG_INFO_ACTIVITY_GFX", activity->supported, activity->value); + if (activity->supported) + { + *result.coreUsage = activity->value; + FF_DEBUG("Core usage: %.1f%%", *result.coreUsage); + } + else + { + FF_DEBUG("Sensor %d not supported", ADL_PMLOG_INFO_ACTIVITY_GFX); + } + } + } + else + { + FF_DEBUG("Failed to get temperature / GPU activity"); + } + } + } + else if (odVersion == 6) { FF_DEBUG("Using Overdrive6 API (odVersion=%d)", odVersion); @@ -372,6 +502,11 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu } } } - FF_DEBUG("AMD GPU detection complete"); + else + { + FF_DEBUG("Unknown Overdrive version: %d", odVersion); + return "Unknown Overdrive version"; + } + FF_DEBUG("AMD GPU detection complete - returning success"); return NULL; }