core: revive wayland

This commit is contained in:
Ali Cheraghi 2024-07-13 19:01:22 +03:30 committed by Stephen Gutekanst
parent 0023ab14fb
commit 3fa889b136
6 changed files with 650 additions and 1022 deletions

View file

@ -14,7 +14,7 @@ const Frequency = @import("core/Frequency.zig");
const Platform = switch (build_options.core_platform) { const Platform = switch (build_options.core_platform) {
.x11 => @import("core/X11.zig"), .x11 => @import("core/X11.zig"),
.wayland => @panic("TODO: revive wayland backend"), .wayland => @import("core/Wayland.zig"),
.web => @panic("TODO: revive wasm backend"), .web => @panic("TODO: revive wasm backend"),
}; };
@ -148,7 +148,7 @@ fn init(core: *Mod, entities: *mach.Entities.Mod, options: InitOptions) !void {
state.title[options.title.len] = 0; state.title[options.title.len] = 0;
} }
try Platform.init(&state.platform, options.allocator, options); try Platform.init(&state.platform, options);
state.instance = gpu.createInstance(null) orelse { state.instance = gpu.createInstance(null) orelse {
log.err("failed to create GPU instance", .{}); log.err("failed to create GPU instance", .{});
@ -951,11 +951,11 @@ comptime {
} }
fn assertHasDecl(comptime T: anytype, comptime decl_name: []const u8) void { fn assertHasDecl(comptime T: anytype, comptime decl_name: []const u8) void {
if (!@hasDecl(T, decl_name)) @compileError("Core missing declaration: " ++ decl_name); if (!@hasDecl(T, decl_name)) @compileError(@typeName(T) ++ " missing declaration: " ++ decl_name);
} }
fn assertHasField(comptime T: anytype, comptime field_name: []const u8) void { fn assertHasField(comptime T: anytype, comptime field_name: []const u8) void {
if (!@hasField(T, field_name)) @compileError("Core missing field: " ++ field_name); if (!@hasField(T, field_name)) @compileError(@typeName(T) ++ " missing field: " ++ field_name);
} }
test { test {

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,19 @@
const builtin = @import("builtin"); const builtin = @import("builtin");
const std = @import("std"); const std = @import("std");
const c = @cImport({
@cInclude("X11/Xlib.h");
@cInclude("X11/Xatom.h");
@cInclude("X11/cursorfont.h");
@cInclude("X11/Xcursor/Xcursor.h");
@cInclude("X11/extensions/Xrandr.h");
});
const mach = @import("../main.zig"); const mach = @import("../main.zig");
const gpu = mach.gpu;
const unicode = @import("x11/unicode.zig");
const Core = @import("../Core.zig"); const Core = @import("../Core.zig");
const InputState = @import("InputState.zig");
const Frequency = @import("Frequency.zig");
const unicode = @import("unicode.zig");
const detectBackendType = @import("common.zig").detectBackendType;
const gpu = mach.gpu;
const InitOptions = Core.InitOptions; const InitOptions = Core.InitOptions;
const Event = Core.Event; const Event = Core.Event;
const KeyEvent = Core.KeyEvent; const KeyEvent = Core.KeyEvent;
@ -11,7 +21,6 @@ const MouseButtonEvent = Core.MouseButtonEvent;
const MouseButton = Core.MouseButton; const MouseButton = Core.MouseButton;
const Size = Core.Size; const Size = Core.Size;
const DisplayMode = Core.DisplayMode; const DisplayMode = Core.DisplayMode;
const SizeLimit = Core.SizeLimit;
const CursorShape = Core.CursorShape; const CursorShape = Core.CursorShape;
const VSyncMode = Core.VSyncMode; const VSyncMode = Core.VSyncMode;
const CursorMode = Core.CursorMode; const CursorMode = Core.CursorMode;
@ -19,17 +28,6 @@ const Key = Core.Key;
const KeyMods = Core.KeyMods; const KeyMods = Core.KeyMods;
const Joystick = Core.Joystick; const Joystick = Core.Joystick;
const Position = Core.Position; const Position = Core.Position;
const InputState = @import("InputState.zig");
const Frequency = @import("Frequency.zig");
const detectBackendType = @import("common.zig").detectBackendType;
pub const c = @cImport({
@cInclude("X11/Xlib.h");
@cInclude("X11/Xatom.h");
@cInclude("X11/cursorfont.h");
@cInclude("X11/Xcursor/Xcursor.h");
@cInclude("X11/extensions/Xrandr.h");
});
const log = std.log.scoped(.mach); const log = std.log.scoped(.mach);
@ -171,18 +169,18 @@ const LibGL = struct {
pub const X11 = @This(); pub const X11 = @This();
// Read-only fields
core: *Core,
allocator: std.mem.Allocator, allocator: std.mem.Allocator,
display: *c.Display, core: *Core,
libx11: LibX11, libx11: LibX11,
libxrr: ?LibXRR, libxrr: ?LibXRR,
libgl: ?LibGL, libgl: ?LibGL,
libxcursor: ?LibXCursor, libxcursor: ?LibXCursor,
gl_ctx: ?*LibGL.Context,
display: *c.Display,
width: c_int, width: c_int,
height: c_int, height: c_int,
empty_event_pipe: [2]std.c.fd_t, empty_event_pipe: [2]std.c.fd_t,
gl_ctx: ?*LibGL.Context,
wm_protocols: c.Atom, wm_protocols: c.Atom,
wm_delete_window: c.Atom, wm_delete_window: c.Atom,
net_wm_ping: c.Atom, net_wm_ping: c.Atom,
@ -211,8 +209,7 @@ input_mu: std.Thread.RwLock = .{},
input_state: InputState = .{}, input_state: InputState = .{},
// Mutable state fields; read/write by any thread // Mutable state fields; read/write by any thread
current_title: [:0]const u8, title: [:0]const u8,
current_title_changed: bool = false,
display_mode: DisplayMode = .windowed, display_mode: DisplayMode = .windowed,
vsync_mode: VSyncMode = .triple, vsync_mode: VSyncMode = .triple,
border: bool, border: bool,
@ -233,9 +230,7 @@ pub const EventIterator = struct {
}; };
// Called on the main thread // Called on the main thread
pub fn init(x11: *X11, allocator: std.mem.Allocator, options: InitOptions) !void { pub fn init(x11: *X11, options: InitOptions) !void {
if (!@import("builtin").is_test) _ = mach.sysgpu.sysgpu.Export(mach.sysgpu.Impl);
const libx11 = try LibX11.load(); const libx11 = try LibX11.load();
const libxcursor: ?LibXCursor = LibXCursor.load() catch |err| switch (err) { const libxcursor: ?LibXCursor = LibXCursor.load() catch |err| switch (err) {
error.LibraryNotFound => null, error.LibraryNotFound => null,
@ -317,7 +312,7 @@ pub fn init(x11: *X11, allocator: std.mem.Allocator, options: InitOptions) !void
var window_attrs: c.XWindowAttributes = undefined; var window_attrs: c.XWindowAttributes = undefined;
_ = libx11.XGetWindowAttributes(display, window, &window_attrs); _ = libx11.XGetWindowAttributes(display, window, &window_attrs);
const backend_type = try detectBackendType(allocator); const backend_type = try detectBackendType(options.allocator);
const refresh_rate: u16 = blk: { const refresh_rate: u16 = blk: {
if (libxrr != null) { if (libxrr != null) {
@ -362,7 +357,7 @@ pub fn init(x11: *X11, allocator: std.mem.Allocator, options: InitOptions) !void
// so we anticipate 2x that. If the event rate is higher than this per frame, it will grow to // so we anticipate 2x that. If the event rate is higher than this per frame, it will grow to
// that maximum (we never shrink the event queue capacity in order to avoid allocations causing // that maximum (we never shrink the event queue capacity in order to avoid allocations causing
// any stutter.) // any stutter.)
var events = EventQueue.init(allocator); var events = EventQueue.init(options.allocator);
try events.ensureTotalCapacity(2048); try events.ensureTotalCapacity(2048);
const window_size = Size{ const window_size = Size{
@ -389,7 +384,7 @@ pub fn init(x11: *X11, allocator: std.mem.Allocator, options: InitOptions) !void
x11.* = .{ x11.* = .{
.core = @fieldParentPtr("platform", x11), .core = @fieldParentPtr("platform", x11),
.allocator = allocator, .allocator = options.allocator,
.display = display, .display = display,
.libx11 = libx11, .libx11 = libx11,
.libgl = libgl, .libgl = libgl,
@ -415,7 +410,7 @@ pub fn init(x11: *X11, allocator: std.mem.Allocator, options: InitOptions) !void
.backend_type = backend_type, .backend_type = backend_type,
.refresh_rate = refresh_rate, .refresh_rate = refresh_rate,
.events = events, .events = events,
.current_title = options.title, .title = options.title,
.display_mode = .windowed, .display_mode = .windowed,
.border = options.border, .border = options.border,
.headless = options.headless, .headless = options.headless,
@ -489,8 +484,8 @@ pub inline fn pollEvents(x11: *X11) EventIterator {
// May be called from any thread. // May be called from any thread.
pub fn setTitle(x11: *X11, title: [:0]const u8) void { pub fn setTitle(x11: *X11, title: [:0]const u8) void {
x11.current_title = title; x11.title = title;
_ = x11.libx11.XStoreName(x11.display, x11.window, x11.current_title.ptr); _ = x11.libx11.XStoreName(x11.display, x11.window, x11.title.ptr);
} }
// May be called from any thread. // May be called from any thread.

View file

@ -1,7 +1,6 @@
///! This code is taken from https://github.com/glfw/glfw/blob/master/src/xkb_unicode.c ///! Taken from https://github.com/glfw/glfw/blob/master/src/xkb_unicode.c
const c = @import("../X11.zig").c; const KeySym = c_ulong;
const keysym_table = &[_]struct { KeySym, u21 }{
const keysym_table = &[_]struct { c.KeySym, u21 }{
.{ 0x01a1, 0x0104 }, .{ 0x01a1, 0x0104 },
.{ 0x01a2, 0x02d8 }, .{ 0x01a2, 0x02d8 },
.{ 0x01a3, 0x0141 }, .{ 0x01a3, 0x0141 },
@ -832,7 +831,7 @@ const keysym_table = &[_]struct { c.KeySym, u21 }{
.{ 0xffbd, '=' }, // XKB_KEY_KP_Equal .{ 0xffbd, '=' }, // XKB_KEY_KP_Equal
}; };
pub fn unicodeFromKeySym(keysym: c.KeySym) ?u21 { pub fn unicodeFromKeySym(keysym: KeySym) ?u21 {
var min: usize = 0; var min: usize = 0;
var mid: usize = 0; var mid: usize = 0;
var max = keysym_table.len - 1; var max = keysym_table.len - 1;

View file

@ -135,8 +135,7 @@ pub const Instance = struct {
vk.extensions.khr_surface.name, vk.extensions.khr_surface.name,
vk.extensions.khr_xlib_surface.name, vk.extensions.khr_xlib_surface.name,
vk.extensions.khr_xcb_surface.name, vk.extensions.khr_xcb_surface.name,
// TODO: renderdoc will not work with this extension vk.extensions.khr_wayland_surface.name,
// vk.extensions.khr_wayland_surface.name,
}, },
.windows => &.{ .windows => &.{
vk.extensions.khr_surface.name, vk.extensions.khr_surface.name,
@ -400,17 +399,14 @@ pub const Surface = struct {
null, null,
); );
} else if (utils.findChained(sysgpu.Surface.DescriptorFromWaylandSurface, desc.next_in_chain.generic)) |wayland_desc| { } else if (utils.findChained(sysgpu.Surface.DescriptorFromWaylandSurface, desc.next_in_chain.generic)) |wayland_desc| {
_ = wayland_desc; break :blk try vki.createWaylandSurfaceKHR(
@panic("unimplemented"); vk_instance,
// TODO: renderdoc will not work with wayland &vk.WaylandSurfaceCreateInfoKHR{
// break :blk try vki.createWaylandSurfaceKHR( .display = @ptrCast(wayland_desc.display),
// vk_instance, .surface = @ptrCast(wayland_desc.surface),
// &vk.WaylandSurfaceCreateInfoKHR{ },
// .display = @ptrCast(wayland_desc.display), null,
// .surface = @ptrCast(wayland_desc.surface), );
// },
// null,
// );
} }
return error.InvalidDescriptor; return error.InvalidDescriptor;

View file

@ -17,8 +17,7 @@ pub const InstanceFunctions = vk.InstanceWrapper(&.{
.{ .{
.instance_commands = .{ .instance_commands = .{
.createDevice = true, .createDevice = true,
// TODO: renderdoc will not work with wayland .createWaylandSurfaceKHR = builtin.target.os.tag == .linux,
// .createWaylandSurfaceKHR = builtin.target.os.tag == .linux,
.createWin32SurfaceKHR = builtin.target.os.tag == .windows, .createWin32SurfaceKHR = builtin.target.os.tag == .windows,
.createXlibSurfaceKHR = builtin.target.os.tag == .linux, .createXlibSurfaceKHR = builtin.target.os.tag == .linux,
.destroyInstance = true, .destroyInstance = true,