feat: get Device from Card.
This commit is contained in:
+6
-4
@@ -5,13 +5,15 @@ pub fn main(init: std.process.Init) !void {
|
|||||||
const io = init.io;
|
const io = init.io;
|
||||||
const gpa = init.gpa;
|
const gpa = init.gpa;
|
||||||
|
|
||||||
const device = drm.Device.getFromDevId(io, gpa, drm.makeDev(226, 0), .{}) catch
|
// const device = drm.Device.getFromDevId(io, gpa, drm.makeDev(226, 0), .{}) catch
|
||||||
try drm.Device.getFromDevId(io, gpa, drm.makeDev(226, 1), .{});
|
// try drm.Device.getFromDevId(io, gpa, drm.makeDev(226, 1), .{});
|
||||||
|
|
||||||
|
// const card = try device.openNode(io);
|
||||||
|
|
||||||
|
const card = try drm.Card.openAuto(io, .primary);
|
||||||
|
const device = try card.getDevice(io, gpa, .{});
|
||||||
std.log.info("Device node path: {s}.", .{device.nodePath()});
|
std.log.info("Device node path: {s}.", .{device.nodePath()});
|
||||||
|
|
||||||
// const card = try drm.Card.openAuto(io);
|
|
||||||
const card = try device.openNode(io);
|
|
||||||
defer card.close(io);
|
defer card.close(io);
|
||||||
const res = try card.getModesettingResources(gpa);
|
const res = try card.getModesettingResources(gpa);
|
||||||
defer res.deinit(gpa);
|
defer res.deinit(gpa);
|
||||||
|
|||||||
+16
-4
@@ -1,11 +1,12 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
const Device = @import("Device.zig");
|
||||||
const drm = @import("drm.zig");
|
const drm = @import("drm.zig");
|
||||||
const fmt = @import("format.zig");
|
const fmt = @import("format.zig");
|
||||||
const sys = @import("sys.zig");
|
const sys = @import("sys.zig");
|
||||||
|
const util = @import("util.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.drm);
|
const log = std.log.scoped(.drm);
|
||||||
|
|
||||||
const Card = @This();
|
const Card = @This();
|
||||||
|
|
||||||
handle: std.Io.File,
|
handle: std.Io.File,
|
||||||
@@ -24,13 +25,15 @@ pub fn open(io: std.Io, path: []const u8) OpenError!Card {
|
|||||||
|
|
||||||
pub const OpenAutoError = OpenError || std.Io.Dir.Iterator.Error || error{NoDevicesFound};
|
pub const OpenAutoError = OpenError || std.Io.Dir.Iterator.Error || error{NoDevicesFound};
|
||||||
|
|
||||||
pub fn openAuto(io: std.Io) OpenAutoError!Card {
|
pub fn openAuto(io: std.Io, target_type: ?drm.Device.NodeType) OpenAutoError!Card {
|
||||||
const dir = try std.Io.Dir.openDirAbsolute(io, "/dev/dri", .{ .iterate = true });
|
const dir = try std.Io.Dir.openDirAbsolute(io, "/dev/dri", .{ .iterate = true });
|
||||||
defer dir.close(io);
|
defer dir.close(io);
|
||||||
|
|
||||||
var it = dir.iterateAssumeFirstIteration();
|
var it = dir.iterateAssumeFirstIteration();
|
||||||
while (try it.next(io)) |entry| if (entry.kind == .character_device)
|
while (try it.next(io)) |entry| if (entry.kind == .character_device) {
|
||||||
return Card{ .handle = try dir.openFile(io, entry.name, .{ .mode = .read_write }) };
|
if (target_type) |t| if (!std.mem.startsWith(u8, entry.name, t.name())) continue;
|
||||||
|
return Card{ .handle = dir.openFile(io, entry.name, .{ .mode = .read_write }) catch continue };
|
||||||
|
};
|
||||||
|
|
||||||
return error.NoDevicesFound;
|
return error.NoDevicesFound;
|
||||||
}
|
}
|
||||||
@@ -39,6 +42,15 @@ pub fn close(self: Card, io: std.Io) void {
|
|||||||
self.handle.close(io);
|
self.handle.close(io);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getDevId(self: Card) !std.posix.dev_t {
|
||||||
|
const stat = try util.statFile(self.handle.handle);
|
||||||
|
return drm.makeDev(stat.rdev_major, stat.rdev_minor);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getDevice(self: Card, io: std.Io, gpa: std.mem.Allocator, flags: Device.Flags) !Device {
|
||||||
|
return .getFromDevId(io, gpa, try self.getDevId(), flags);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn handleEvents(
|
pub fn handleEvents(
|
||||||
self: Card,
|
self: Card,
|
||||||
io: std.Io,
|
io: std.Io,
|
||||||
|
|||||||
+11
-12
@@ -4,6 +4,7 @@ const path_max = std.os.linux.PATH_MAX;
|
|||||||
const Card = @import("Card.zig");
|
const Card = @import("Card.zig");
|
||||||
const drm = @import("drm.zig");
|
const drm = @import("drm.zig");
|
||||||
const sys = @import("sys.zig");
|
const sys = @import("sys.zig");
|
||||||
|
const util = @import("util.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.drm);
|
const log = std.log.scoped(.drm);
|
||||||
const Device = @This();
|
const Device = @This();
|
||||||
@@ -183,6 +184,14 @@ pub const NodeType = enum {
|
|||||||
control,
|
control,
|
||||||
render,
|
render,
|
||||||
pub const max = 3;
|
pub const max = 3;
|
||||||
|
|
||||||
|
pub fn name(self: NodeType) []const u8 {
|
||||||
|
return switch (self) {
|
||||||
|
.primary => drm.primary_minor_name,
|
||||||
|
.control => drm.control_minor_name,
|
||||||
|
.render => drm.render_minor_name,
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn processDevice(
|
fn processDevice(
|
||||||
@@ -202,7 +211,7 @@ fn processDevice(
|
|||||||
if (node.len + 1 > max_node_length)
|
if (node.len + 1 > max_node_length)
|
||||||
return error.NodePathTooLong;
|
return error.NodePathTooLong;
|
||||||
|
|
||||||
const stat = try statx(node);
|
const stat = try util.statPath(node);
|
||||||
const major = stat.rdev_major;
|
const major = stat.rdev_major;
|
||||||
const minor = stat.rdev_minor;
|
const minor = stat.rdev_minor;
|
||||||
|
|
||||||
@@ -375,7 +384,7 @@ fn parseConfigSysfsFile(io: std.Io, major: u32, minor: u32) !PciDeviceInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn hasRdev(dev: Device, rdev: std.posix.dev_t) bool {
|
fn hasRdev(dev: Device, rdev: std.posix.dev_t) bool {
|
||||||
const stat = statx(dev.nodePath()) catch return false;
|
const stat = util.statPath(dev.nodePath()) catch return false;
|
||||||
return drm.makeDev(stat.rdev_major, stat.rdev_minor) == rdev;
|
return drm.makeDev(stat.rdev_major, stat.rdev_minor) == rdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,13 +395,3 @@ fn getNodeType(name: []const u8) !NodeType {
|
|||||||
|
|
||||||
return error.InvalidName;
|
return error.InvalidName;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statx(path: []const u8) !std.os.linux.Statx {
|
|
||||||
const posix_path = try std.posix.toPosixPath(path);
|
|
||||||
var stat_buf: std.os.linux.Statx = undefined;
|
|
||||||
const rc = std.os.linux.statx(std.os.linux.AT.FDCWD, &posix_path, 0, .{}, &stat_buf);
|
|
||||||
return switch (std.posix.errno(rc)) {
|
|
||||||
.SUCCESS => stat_buf,
|
|
||||||
else => |err| std.posix.unexpectedErrno(err),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn statPath(path: []const u8) !std.os.linux.Statx {
|
||||||
|
const posix_path = try std.posix.toPosixPath(path);
|
||||||
|
return statxInner(std.os.linux.AT.FDCWD, &posix_path, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn statFile(fd: std.posix.fd_t) !std.os.linux.Statx {
|
||||||
|
return statxInner(fd, "", std.os.linux.AT.EMPTY_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn statxInner(fd: std.posix.fd_t, path: [*:0]const u8, flags: u32) !std.os.linux.Statx {
|
||||||
|
var stat_buf: std.os.linux.Statx = undefined;
|
||||||
|
const rc = std.posix.system.statx(fd, path, flags, .{}, &stat_buf);
|
||||||
|
return switch (std.posix.errno(rc)) {
|
||||||
|
.SUCCESS => stat_buf,
|
||||||
|
.ACCES => error.PermissionDenied,
|
||||||
|
.LOOP => error.SymLinkLoop,
|
||||||
|
.NAMETOOLONG => error.NameTooLong,
|
||||||
|
.NOENT => error.FileNotFound,
|
||||||
|
.NOMEM => error.SystemResources,
|
||||||
|
.NOTDIR => error.NotADirectory,
|
||||||
|
.BADF => unreachable,
|
||||||
|
.FAULT => unreachable,
|
||||||
|
.INVAL => unreachable,
|
||||||
|
else => |err| std.posix.unexpectedErrno(err),
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user