summaryrefslogtreecommitdiff
path: root/src/screen/drm/buffer/raw.zig
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2025-02-02 21:54:14 +0100
committerNathan Reiner <nathan@nathanreiner.xyz>2025-02-02 21:54:14 +0100
commit811a6bd572f4c6b26e99b4e746f5d710947ee934 (patch)
tree3ff6375ce2d7ea13e0d49f7800757a1b42604884 /src/screen/drm/buffer/raw.zig
parent3f4375a14218796cbd7bfff1c8cfff0f7bb1f6df (diff)
screen: drm change struct layout
Diffstat (limited to 'src/screen/drm/buffer/raw.zig')
-rw-r--r--src/screen/drm/buffer/raw.zig109
1 files changed, 109 insertions, 0 deletions
diff --git a/src/screen/drm/buffer/raw.zig b/src/screen/drm/buffer/raw.zig
new file mode 100644
index 0000000..e4674eb
--- /dev/null
+++ b/src/screen/drm/buffer/raw.zig
@@ -0,0 +1,109 @@
+const std = @import("std");
+const os = std.os.linux;
+const drm = @import("../root.zig");
+const cerror = @import("../../cerror.zig");
+
+pub const Raw = struct {
+ const Self = @This();
+
+ card: *drm.Card,
+ id: u32,
+ width: u32,
+ height: u32,
+ bpp: u32,
+ stride: u32,
+ data_size: u64,
+ canvas_size: u64,
+ handle: u32,
+ data: [*]volatile drm.Pixel,
+
+ pub fn init(card: *drm.Card, width: u32, height: u32, bpp: u32) !Self {
+ var create_dumb = std.mem.zeroInit(drm.request.CreateDumb, .{
+ .width = width,
+ .height = height,
+ .bpp = bpp,
+ });
+ try card.request(
+ .create_dumb,
+ &create_dumb
+ );
+
+ var fb = Self {
+ .id = 0,
+ .width = create_dumb.width,
+ .height = create_dumb.height,
+ .bpp = create_dumb.bpp,
+ .stride = create_dumb.pitch,
+ .data_size = create_dumb.size,
+ .canvas_size = create_dumb.size / (bpp / 8),
+ .handle = create_dumb.handle,
+ .data = undefined,
+ .card = card,
+ };
+
+ var buffer_cmd = drm.request.FrameBufferCmd2 {
+ .id = 0,
+ .width = fb.width,
+ .height = fb.height,
+ .pixel_format = drm.Pixel.Format.xrgb8888,
+ .flags = 0,
+ .handles = [_] u32 { fb.handle, 0, 0, 0 },
+ .pitches = [_] u32 { fb.stride, 0, 0, 0 },
+ .offsets = [_] u32 { 0, 0, 0, 0 },
+ .modifier = [_] u32 { 0, 0, 0, 0 },
+ };
+
+ try card.request(
+ .add_frame_buffer2,
+ &buffer_cmd
+ );
+
+ fb.id = buffer_cmd.id;
+
+ var map_dumb = std.mem.zeroInit(drm.request.MapDumb, .{ .handle = fb.handle });
+
+ try card.request(
+ .map_dumb,
+ &map_dumb
+ );
+
+ const address = os.mmap(
+ null,
+ fb.data_size,
+ os.PROT.READ | os.PROT.WRITE,
+ .{ .TYPE = os.MAP_TYPE.SHARED },
+ card.file.handle,
+ map_dumb.offset
+ );
+
+ try cerror.from_usize(address);
+
+ fb.data = @ptrFromInt(address);
+
+ return fb;
+ }
+
+ pub fn set(self: *Self, x: u32, y: u32, p: drm.Pixel) void {
+ self.data[x + self.width * y] = p;
+ }
+
+ pub fn fill(self: *Self, p: drm.Pixel) void {
+ @memset(self.data[0..self.canvas_size], p);
+ }
+
+ pub fn deinit(self: *Self) void {
+ cerror.from_usize(
+ os.munmap(@ptrCast(@volatileCast(self.data)), self.data_size)
+ ) catch |err| std.debug.panic("munmap failed in frame-buffer: {}", .{err});
+
+ self.card.request(
+ .remove_frame_buffer,
+ &self.id
+ ) catch @panic("failed to remove frame-buffer");
+
+ self.card.request(
+ .destroy_dumb,
+ &self.handle
+ ) catch @panic("failed to destroy dumb-buffer");
+ }
+};