Skip to content

Commit aaabc1b

Browse files
feat(gpu): adding linux-drm
1 parent 23bcce7 commit aaabc1b

File tree

9 files changed

+177
-2
lines changed

9 files changed

+177
-2
lines changed

build.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ pub fn build(b: *std.Build) void {
3030
},
3131
});
3232

33+
if (target.result.os.tag == .linux) {
34+
const libdrm = b.dependency("libdrm", .{
35+
.target = target,
36+
.optimize = optimize,
37+
});
38+
39+
module.addImport("libdrm", libdrm.module("libdrm"));
40+
}
41+
3342
const autodoc_test = b.addObject(.{
3443
.name = "phantom",
3544
.root_module = module,

build.zig.zon

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
.url = "https://codeberg.org/ifreund/zig-wayland/archive/f3c5d503e540ada8cbcb056420de240af0c094f7.tar.gz",
1616
.hash = "wayland-0.4.0-dev-lQa1kjfIAQCmhhQu3xF0KH-94-TzeMXOqfnP0-Dg6Wyy",
1717
},
18+
.libdrm = .{
19+
.url = "https://github.com/MidstallSoftware/libdrm.zig/archive/d020314c5fcd78d64bdeecda3a42d0e43522f9af.tar.gz",
20+
.hash = "libdrm-0.1.0-iX14LQFJAQAEHpJCxO9os_WFkU-GVD1kuLKkWnGqQRxz",
21+
},
1822
},
1923
.fingerprint = 0x6896f6aeaa10b7f9,
2024
}

lib/phantom/gpu.zig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
pub const backend = @import("gpu/backend.zig");
2+
13
pub const Connector = @import("gpu/Connector.zig");
24
pub const Device = @import("gpu/Device.zig");
35
pub const Provider = @import("gpu/Provider.zig");
46
pub const Texture = @import("gpu/Texture.zig");
57

68
test {
9+
_ = backend;
710
_ = Connector;
811
_ = Device;
912
_ = Provider;

lib/phantom/gpu/Device.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ const Connector = @import("Connector.zig");
33
const Self = @This();
44

55
pub const VTable = struct {
6-
getConnectors: *const fn (*anyopaque) anyerror![]*Connector,
6+
getConnectors: *const fn (*anyopaque) anyerror![]const *Connector,
77
destroy: *const fn (*anyopaque) void,
88
};
99

1010
ptr: *anyopaque,
1111
vtable: *const VTable,
1212

13-
pub inline fn getConnectors(self: *Self) anyerror![]*Connector {
13+
pub inline fn getConnectors(self: *Self) anyerror![]const *Connector {
1414
return self.vtable.getConnectors(self.ptr);
1515
}
1616

lib/phantom/gpu/backend.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const builtin = @import("builtin");
2+
3+
pub const linux_drm = @import("backend/linux_drm.zig");
4+
5+
test {
6+
if (builtin.os.tag == .linux) {
7+
_ = linux_drm;
8+
}
9+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//! GPU backend for Linux using the Direct Rendering Manager subsystem.
2+
3+
pub const Connector = @import("linux_drm/Connector.zig");
4+
pub const Device = @import("linux_drm/Device.zig");
5+
pub const Provider = @import("linux_drm/Provider.zig");
6+
7+
test {
8+
_ = Connector;
9+
_ = Device;
10+
_ = Provider;
11+
}

lib/phantom/gpu/backend/linux_drm/Connector.zig

Whitespace-only changes.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
const std = @import("std");
2+
const Allocator = std.mem.Allocator;
3+
const libdrm = @import("libdrm");
4+
const Connector = @import("../../Connector.zig");
5+
const Device = @import("../../Device.zig");
6+
const Self = @This();
7+
8+
allocator: Allocator,
9+
node: libdrm.Node,
10+
base: Device,
11+
12+
pub fn create(alloc: Allocator, node: libdrm.Node) !*Device {
13+
const self = try alloc.create(Self);
14+
errdefer alloc.destroy(self);
15+
16+
self.* = .{
17+
.allocator = alloc,
18+
.node = node,
19+
.base = .{
20+
.ptr = self,
21+
.vtable = &.{
22+
.getConnectors = impl_getConnectors,
23+
.destroy = impl_destroy,
24+
},
25+
},
26+
};
27+
return &self.base;
28+
}
29+
30+
pub fn getConnectors(self: *Self) ![]const *Connector {
31+
var list = std.ArrayList(*Connector).init(self.allocator);
32+
defer list.deinit();
33+
34+
const modeCardRes = try self.node.getModeCardRes();
35+
defer modeCardRes.deinit(self.allocator);
36+
37+
if (modeCardRes.connectorIds()) |connectorIds| {
38+
for (connectorIds) |connectorId| {
39+
std.debug.print("{}\n", .{connectorId});
40+
}
41+
}
42+
return try list.toOwnedSlice();
43+
}
44+
45+
pub fn destroy(self: *Self) void {
46+
self.node.deinit();
47+
self.allocator.destroy(self);
48+
}
49+
50+
fn impl_getConnectors(ptr: *anyopaque) anyerror![]const *Connector {
51+
const self: *Self = @alignCast(@ptrCast(ptr));
52+
return self.getConnectors();
53+
}
54+
55+
fn impl_destroy(ptr: *anyopaque) void {
56+
const self: *Self = @alignCast(@ptrCast(ptr));
57+
return self.destroy();
58+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
const std = @import("std");
2+
const Allocator = std.mem.Allocator;
3+
const libdrm = @import("libdrm");
4+
const Provider = @import("../../Provider.zig");
5+
const Device = @import("../../Device.zig");
6+
const LinuxDrmDevice = @import("Device.zig");
7+
const Self = @This();
8+
9+
allocator: Allocator,
10+
base: Provider,
11+
12+
pub fn create(alloc: Allocator) !*Provider {
13+
const self = try alloc.create(Self);
14+
errdefer alloc.destroy(self);
15+
16+
self.* = .{
17+
.allocator = alloc,
18+
.base = .{
19+
.ptr = self,
20+
.vtable = &.{
21+
.getDevices = impl_getDevices,
22+
.destroy = impl_destroy,
23+
},
24+
},
25+
};
26+
return &self.base;
27+
}
28+
29+
pub fn getDevices(self: *Self) anyerror![]const *Device {
30+
var list = std.ArrayList(*Device).init(self.allocator);
31+
defer list.deinit();
32+
33+
var iter = libdrm.Node.Iterator.init(self.allocator, .primary);
34+
while (iter.next()) |node| {
35+
const device = try LinuxDrmDevice.create(self.allocator, node);
36+
errdefer device.destroy();
37+
38+
try list.append(device);
39+
}
40+
41+
return try list.toOwnedSlice();
42+
}
43+
44+
pub fn destroy(self: *Self) void {
45+
self.allocator.destroy(self);
46+
}
47+
48+
fn impl_getDevices(ptr: *anyopaque) anyerror![]const *Device {
49+
const self: *Self = @alignCast(@ptrCast(ptr));
50+
return self.getDevices();
51+
}
52+
53+
fn impl_destroy(ptr: *anyopaque) void {
54+
const self: *Self = @alignCast(@ptrCast(ptr));
55+
return self.destroy();
56+
}
57+
58+
test {
59+
const provider = try create(std.testing.allocator);
60+
defer provider.destroy();
61+
62+
const devices = try provider.getDevices();
63+
defer {
64+
for (devices) |dev| dev.destroy();
65+
std.testing.allocator.free(devices);
66+
}
67+
68+
if (devices.len == 0) return error.SkipZigTest;
69+
70+
std.debug.print("{any}\n", .{devices});
71+
72+
for (devices) |dev| {
73+
const connectors = dev.getConnectors() catch continue;
74+
defer {
75+
for (connectors) |conn| conn.destroy();
76+
std.testing.allocator.free(connectors);
77+
}
78+
79+
std.debug.print("{any}\n", .{connectors});
80+
}
81+
}

0 commit comments

Comments
 (0)