generated from general-packages/pika-pkg-template
Fix GPU detection for NVIDIA and AMD; improve model name retrieval and memory reporting in gpu.zig
. Update changelog version
All checks were successful
PikaOS Package Build & Release (amd64-v3) / build (push) Successful in 53s
All checks were successful
PikaOS Package Build & Release (amd64-v3) / build (push) Successful in 53s
This commit is contained in:
parent
f118503903
commit
21e4af01c5
2
.github/release-nest-v3
vendored
2
.github/release-nest-v3
vendored
@ -1 +1 @@
|
|||||||
3
|
1
|
@ -1,4 +1,4 @@
|
|||||||
pikafetch (0.1.0-101pika3) pika; urgency=medium
|
pikafetch (0.1.0-101pika4) pika; urgency=medium
|
||||||
|
|
||||||
* Initial release.
|
* Initial release.
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ pub fn getGPUInfo(allocator: mem.Allocator) ![][]const u8 {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
VendorId.AMD, VendorId.AMD_2 => {
|
VendorId.AMD, VendorId.AMD_2 => {
|
||||||
if (try detectAMDGPU(allocator, entry.name)) |gpu| {
|
if (try detectAMDGPU(allocator, entry.name, vendor_id)) |gpu| {
|
||||||
try gpus.append(gpu);
|
try gpus.append(gpu);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -124,67 +124,128 @@ pub fn getGPUInfo(allocator: mem.Allocator) ![][]const u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn detectNvidiaGPU(allocator: mem.Allocator, card_name: []const u8) !?[]const u8 {
|
fn detectNvidiaGPU(allocator: mem.Allocator, card_name: []const u8) !?[]const u8 {
|
||||||
|
// First try to get device ID for PCI lookup
|
||||||
|
const device_path = try allocPrint(allocator, "/sys/class/drm/{s}/device/device", .{card_name});
|
||||||
|
defer allocator.free(device_path);
|
||||||
|
|
||||||
|
const device_file = fs.openFileAbsolute(device_path, .{}) catch return null;
|
||||||
|
defer device_file.close();
|
||||||
|
|
||||||
|
var device_buf: [32]u8 = undefined;
|
||||||
|
const device_len = device_file.readAll(&device_buf) catch return null;
|
||||||
|
const device_str = mem.trim(u8, device_buf[0..device_len], "\n\r \t0x");
|
||||||
|
|
||||||
|
const device_id = std.fmt.parseInt(u32, device_str, 16) catch return null;
|
||||||
|
|
||||||
|
// Try /proc/driver/nvidia first
|
||||||
const proc_path = try allocPrint(allocator, "/proc/driver/nvidia/gpus/{s}/information", .{card_name});
|
const proc_path = try allocPrint(allocator, "/proc/driver/nvidia/gpus/{s}/information", .{card_name});
|
||||||
defer allocator.free(proc_path);
|
defer allocator.free(proc_path);
|
||||||
|
|
||||||
const info_file = fs.openFileAbsolute(proc_path, .{}) catch return null;
|
|
||||||
defer info_file.close();
|
|
||||||
|
|
||||||
var buf: [1024]u8 = undefined;
|
|
||||||
const bytes_read = info_file.readAll(&buf) catch return null;
|
|
||||||
const content = buf[0..bytes_read];
|
|
||||||
|
|
||||||
var model_name: ?[]const u8 = null;
|
var model_name: ?[]const u8 = null;
|
||||||
var vbios_version: ?[]const u8 = null;
|
var vbios_version: ?[]const u8 = null;
|
||||||
var memory_size: ?u64 = null;
|
var memory_size: ?u64 = null;
|
||||||
|
|
||||||
var lines = mem.split(u8, content, "\n");
|
// Try to read from nvidia proc
|
||||||
while (lines.next()) |line| {
|
const info_file = fs.openFileAbsolute(proc_path, .{}) catch null;
|
||||||
if (mem.indexOf(u8, line, "Model:")) |_| {
|
if (info_file) |file| {
|
||||||
const start = mem.indexOf(u8, line, ":").? + 1;
|
defer file.close();
|
||||||
model_name = mem.trim(u8, line[start..], " \t\r\n");
|
var buf: [1024]u8 = undefined;
|
||||||
} else if (mem.indexOf(u8, line, "Video BIOS:")) |_| {
|
const bytes_read = file.readAll(&buf) catch 0;
|
||||||
const start = mem.indexOf(u8, line, ":").? + 1;
|
if (bytes_read > 0) {
|
||||||
vbios_version = mem.trim(u8, line[start..], " \t\r\n");
|
const content = buf[0..bytes_read];
|
||||||
} else if (mem.indexOf(u8, line, "Video Memory:")) |_| {
|
|
||||||
const start = mem.indexOf(u8, line, ":").? + 1;
|
var lines = mem.split(u8, content, "\n");
|
||||||
const mem_str = mem.trim(u8, line[start..], " \t\r\nMB");
|
while (lines.next()) |line| {
|
||||||
memory_size = std.fmt.parseInt(u64, mem_str, 10) catch null;
|
if (mem.indexOf(u8, line, "Model:")) |_| {
|
||||||
|
const start = mem.indexOf(u8, line, ":").? + 1;
|
||||||
|
model_name = mem.trim(u8, line[start..], " \t\r\n");
|
||||||
|
} else if (mem.indexOf(u8, line, "Video BIOS:")) |_| {
|
||||||
|
const start = mem.indexOf(u8, line, ":").? + 1;
|
||||||
|
vbios_version = mem.trim(u8, line[start..], " \t\r\n");
|
||||||
|
} else if (mem.indexOf(u8, line, "Video Memory:")) |_| {
|
||||||
|
const start = mem.indexOf(u8, line, ":").? + 1;
|
||||||
|
const mem_str = mem.trim(u8, line[start..], " \t\r\nMB");
|
||||||
|
memory_size = std.fmt.parseInt(u64, mem_str, 10) catch null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model_name) |model| {
|
// If we couldn't get model name from nvidia proc, try product name
|
||||||
const gpu_info = GPUInfo{
|
if (model_name == null) {
|
||||||
.vendor = "NVIDIA",
|
const product_path = try allocPrint(allocator, "/sys/class/drm/{s}/device/product_name", .{card_name});
|
||||||
.model = model,
|
defer allocator.free(product_path);
|
||||||
.driver = vbios_version,
|
|
||||||
.memory = memory_size,
|
const product_file = fs.openFileAbsolute(product_path, .{}) catch null;
|
||||||
};
|
if (product_file) |file| {
|
||||||
const formatted = try gpu_info.format(allocator);
|
defer file.close();
|
||||||
return formatted;
|
var product_buf: [256]u8 = undefined;
|
||||||
|
const len = file.readAll(&product_buf) catch 0;
|
||||||
|
if (len > 0) {
|
||||||
|
model_name = mem.trim(u8, product_buf[0..len], "\n\r \t");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
// If still no model name, try PCI lookup
|
||||||
|
if (model_name == null) {
|
||||||
|
model_name = if (findPCIName(VendorId.NVIDIA, device_id)) |name|
|
||||||
|
name
|
||||||
|
else
|
||||||
|
try allocPrint(allocator, "NVIDIA GPU (0x{x:0>4})", .{device_id});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get driver info if not already found from nvidia proc
|
||||||
|
if (vbios_version == null) {
|
||||||
|
const driver_path = try allocPrint(allocator, "/sys/class/drm/{s}/device/driver", .{card_name});
|
||||||
|
defer allocator.free(driver_path);
|
||||||
|
|
||||||
|
vbios_version = blk: {
|
||||||
|
var dir_handle = fs.openDirAbsolute(driver_path, .{}) catch break :blk null;
|
||||||
|
defer dir_handle.close();
|
||||||
|
|
||||||
|
var path_buf: [256]u8 = undefined;
|
||||||
|
const path = dir_handle.readLink("driver", &path_buf) catch break :blk null;
|
||||||
|
break :blk std.fs.path.basename(path);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const gpu_info = GPUInfo{
|
||||||
|
.vendor = "NVIDIA",
|
||||||
|
.model = model_name.?, // Safe because we always set it above
|
||||||
|
.driver = vbios_version,
|
||||||
|
.memory = memory_size,
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatted = try gpu_info.format(allocator);
|
||||||
|
return formatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn detectAMDGPU(allocator: mem.Allocator, card_name: []const u8) !?[]const u8 {
|
fn detectAMDGPU(allocator: mem.Allocator, card_name: []const u8, vendor_id: u32) !?[]const u8 {
|
||||||
const product_path = try allocPrint(allocator, "/sys/class/drm/{s}/device/product_name", .{card_name});
|
// Get device ID
|
||||||
defer allocator.free(product_path);
|
const device_path = try allocPrint(allocator, "/sys/class/drm/{s}/device/device", .{card_name});
|
||||||
|
defer allocator.free(device_path);
|
||||||
|
|
||||||
var product_name: []const u8 = undefined;
|
const device_file = fs.openFileAbsolute(device_path, .{}) catch return null;
|
||||||
if (fs.openFileAbsolute(product_path, .{})) |product_file| {
|
defer device_file.close();
|
||||||
defer product_file.close();
|
|
||||||
var product_buf: [256]u8 = undefined;
|
|
||||||
const product_len = product_file.readAll(&product_buf) catch return null;
|
|
||||||
product_name = mem.trim(u8, product_buf[0..product_len], "\n\r \t");
|
|
||||||
} else |_| {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const driver_path = try allocPrint(allocator, "/sys/class/drm/{s}/device/driver", .{card_name});
|
var device_buf: [32]u8 = undefined;
|
||||||
defer allocator.free(driver_path);
|
const device_len = device_file.readAll(&device_buf) catch return null;
|
||||||
|
const device_str = mem.trim(u8, device_buf[0..device_len], "\n\r \t0x");
|
||||||
|
|
||||||
|
const device_id = std.fmt.parseInt(u32, device_str, 16) catch return null;
|
||||||
|
|
||||||
|
// Get model name from PCI database
|
||||||
|
const model_name = if (findPCIName(vendor_id, device_id)) |name|
|
||||||
|
name
|
||||||
|
else
|
||||||
|
try allocPrint(allocator, "GPU (0x{x:0>4})", .{device_id});
|
||||||
|
|
||||||
|
// Get driver info
|
||||||
const driver = blk: {
|
const driver = blk: {
|
||||||
|
const driver_path = try allocPrint(allocator, "/sys/class/drm/{s}/device/driver", .{card_name});
|
||||||
|
defer allocator.free(driver_path);
|
||||||
|
|
||||||
var dir_handle = fs.openDirAbsolute(driver_path, .{}) catch break :blk null;
|
var dir_handle = fs.openDirAbsolute(driver_path, .{}) catch break :blk null;
|
||||||
defer dir_handle.close();
|
defer dir_handle.close();
|
||||||
|
|
||||||
@ -193,11 +254,27 @@ fn detectAMDGPU(allocator: mem.Allocator, card_name: []const u8) !?[]const u8 {
|
|||||||
break :blk std.fs.path.basename(path);
|
break :blk std.fs.path.basename(path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get VRAM info
|
||||||
|
var memory: ?u64 = null;
|
||||||
|
const vram_path = try allocPrint(allocator, "/sys/class/drm/{s}/device/mem_info_vram_total", .{card_name});
|
||||||
|
defer allocator.free(vram_path);
|
||||||
|
|
||||||
|
if (fs.openFileAbsolute(vram_path, .{})) |vram_file| {
|
||||||
|
defer vram_file.close();
|
||||||
|
var vram_buf: [32]u8 = undefined;
|
||||||
|
if (vram_file.readAll(&vram_buf)) |len| {
|
||||||
|
const vram_str = mem.trim(u8, vram_buf[0..len], "\n\r \t");
|
||||||
|
if (std.fmt.parseInt(u64, vram_str, 10)) |vram_bytes| {
|
||||||
|
memory = vram_bytes / (1024 * 1024); // Convert to MB
|
||||||
|
} else |_| {}
|
||||||
|
} else |_| {}
|
||||||
|
} else |_| {}
|
||||||
|
|
||||||
const gpu_info = GPUInfo{
|
const gpu_info = GPUInfo{
|
||||||
.vendor = "AMD",
|
.vendor = "AMD",
|
||||||
.model = product_name,
|
.model = model_name,
|
||||||
.driver = driver,
|
.driver = driver,
|
||||||
.memory = null,
|
.memory = memory,
|
||||||
};
|
};
|
||||||
|
|
||||||
const formatted = try gpu_info.format(allocator);
|
const formatted = try gpu_info.format(allocator);
|
||||||
@ -247,26 +324,25 @@ fn findPCIName(vendor_id: u32, device_id: u32) ?[]const u8 {
|
|||||||
var current_vendor: ?u32 = null;
|
var current_vendor: ?u32 = null;
|
||||||
|
|
||||||
while (lines.next()) |line| {
|
while (lines.next()) |line| {
|
||||||
const trimmed = mem.trim(u8, line, " \t\r");
|
const trimmed = mem.trim(u8, line, " \r\n");
|
||||||
if (trimmed.len == 0 or trimmed[0] == '#') continue;
|
if (trimmed.len == 0 or trimmed[0] == '#') continue;
|
||||||
|
|
||||||
// Check if this is a vendor line (no tabs at start)
|
// Count leading tabs
|
||||||
if (trimmed[0] != '\t') {
|
const tab_count = for (trimmed, 0..) |c, i| {
|
||||||
// Parse vendor ID
|
if (c != '\t') break @as(usize, @intCast(i));
|
||||||
|
} else trimmed.len;
|
||||||
|
|
||||||
|
// No tabs = vendor line
|
||||||
|
if (tab_count == 0) {
|
||||||
const space_idx = mem.indexOf(u8, trimmed, " ") orelse continue;
|
const space_idx = mem.indexOf(u8, trimmed, " ") orelse continue;
|
||||||
const vendor_str = trimmed[0..space_idx];
|
const vendor_str = trimmed[0..space_idx];
|
||||||
current_vendor = std.fmt.parseInt(u32, vendor_str, 16) catch continue;
|
current_vendor = std.fmt.parseInt(u32, vendor_str, 16) catch continue;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we found our vendor, look for the device
|
// One tab = device line
|
||||||
if (current_vendor) |vendor| {
|
if (tab_count == 1 and current_vendor != null and current_vendor.? == vendor_id) {
|
||||||
if (vendor != vendor_id) continue;
|
const device_line = trimmed[tab_count..];
|
||||||
|
|
||||||
// Device lines have one tab
|
|
||||||
if (trimmed[0] != '\t' or trimmed.len < 2) continue;
|
|
||||||
const device_line = mem.trim(u8, trimmed[1..], " \t");
|
|
||||||
|
|
||||||
const space_idx = mem.indexOf(u8, device_line, " ") orelse continue;
|
const space_idx = mem.indexOf(u8, device_line, " ") orelse continue;
|
||||||
const device_str = device_line[0..space_idx];
|
const device_str = device_line[0..space_idx];
|
||||||
const found_device = std.fmt.parseInt(u32, device_str, 16) catch continue;
|
const found_device = std.fmt.parseInt(u32, device_str, 16) catch continue;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user