feat(macos): add gpu freq

This commit is contained in:
utox39
2025-03-25 01:10:01 +01:00
parent 1d989a1919
commit 443e9b9985

View File

@@ -15,6 +15,7 @@ pub const CpuInfo = struct {
pub const GpuInfo = struct { pub const GpuInfo = struct {
gpu_name: []u8, gpu_name: []u8,
gpu_cores: i32, gpu_cores: i32,
gpu_freq: f64,
}; };
pub const RamInfo = struct { pub const RamInfo = struct {
@@ -146,6 +147,7 @@ pub fn getGpuInfo(allocator: std.mem.Allocator) !GpuInfo {
var gpu_info = GpuInfo{ var gpu_info = GpuInfo{
.gpu_name = try allocator.dupe(u8, "Unknown"), .gpu_name = try allocator.dupe(u8, "Unknown"),
.gpu_cores = 0, .gpu_cores = 0,
.gpu_freq = 0.0,
}; };
// https://developer.apple.com/documentation/iokit/1514687-ioservicematching // https://developer.apple.com/documentation/iokit/1514687-ioservicematching
@@ -216,9 +218,85 @@ pub fn getGpuInfo(allocator: std.mem.Allocator) !GpuInfo {
} }
} }
const gpu_freq_mhz = try getGpuFreq();
const gpu_freq_ghz = @floor(gpu_freq_mhz) / 1000;
gpu_info.gpu_freq = gpu_freq_ghz;
return gpu_info; return gpu_info;
} }
fn getGpuFreq() !f64 {
// https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/gpu/gpu_apple.c
// Retrieve the matching service for "pmgr"
// https://developer.apple.com/documentation/iokit/1514535-ioservicegetmatchingservice
const service = c_iokit.IOServiceGetMatchingService(c_iokit.kIOMasterPortDefault, c_iokit.IOServiceNameMatching("pmgr"));
if (service == c_iokit.FALSE) return error.NoMatchingService;
defer _ = c_iokit.IOObjectRelease(service);
// Check that the service conforms to "AppleARMIODevice"
// https://developer.apple.com/documentation/iokit/1514505-ioobjectconformsto
if (c_iokit.IOObjectConformsTo(service, "AppleARMIODevice") == c_iokit.FALSE) {
return error.NotAppleARMIODevice;
}
// CFSTR is a macro and can't be translated by Zig
// The CFString is created "manually"
const vs9s_key = c_iokit.CFStringCreateWithCString(c_iokit.kCFAllocatorDefault, "voltage-states9-sram", c_iokit.kCFStringEncodingUTF8);
if (vs9s_key == null) {
return error.FailedToCreateCFKey;
}
defer c_iokit.CFRelease(vs9s_key);
// Retrieve the property from the registry entry
// https://developer.apple.com/documentation/iokit/1514293-ioregistryentrycreatecfproperty
const freq_property = c_iokit.IORegistryEntryCreateCFProperty(service, vs9s_key, c_iokit.kCFAllocatorDefault, 0);
if (freq_property == null) return error.PropertyNotFound;
defer c_iokit.CFRelease(freq_property);
// Ensure the property is a CFData object
if (c_iokit.CFGetTypeID(freq_property) != c_cf.CFDataGetTypeID())
return error.InvalidPropertyType;
const freq_data = @as(*const c_iokit.__CFData, @ptrCast(freq_property));
// Get the length of the CFData
const freq_data_length = c_iokit.CFDataGetLength(freq_data);
// voltage-states9-sram stores supported <frequency / voltage> pairs of pcores from the lowest to the highest
if (freq_data_length == 0 or @as(u32, @intCast(freq_data_length)) % (@sizeOf(u32) * 2) != 0)
return error.InvalidVoltageStates5SramLength;
// Get data pointer
const freq_data_ptr = c_iokit.CFDataGetBytePtr(freq_data);
if (freq_data_ptr == null)
return error.InvalidVoltageStates5SramData;
const freq_array = @as([*]const u32, @ptrCast(@alignCast(freq_data_ptr)));
// The first element contains the minimum freq
var p_max: u32 = freq_array[0];
const total_elements = @as(u32, @intCast(freq_data_length)) / @sizeOf(u32);
// Iterate on values, starting at index 2, skipping voltage (each pair is <frequency, voltage>)
var i: usize = 2;
while (i < total_elements) : (i += 2) {
const current = freq_array[i];
if (current == 0) break;
if (current > p_max) {
p_max = current;
}
}
// Assume that p_max is in Hz, M1~M3
if (p_max > 100_000_000) {
return @as(f64, @floatFromInt(p_max)) / 1_000 / 1_000;
} else { // Assume that p_max is in kHz, M4 and later
return @as(f64, @floatFromInt(p_max)) / 1_000;
}
}
pub fn getRamInfo() !RamInfo { pub fn getRamInfo() !RamInfo {
// -- RAM SIZE -- // -- RAM SIZE --
var ram_size: u64 = 0; var ram_size: u64 = 0;