const std = @import("std"); const builtin = @import("builtin"); const mach = @import("../../main.zig"); const gamemode = mach.gamemode; const mach_core = mach.core; const gpu = mach.gpu; pub inline fn printUnhandledErrorCallback(_: void, ty: gpu.ErrorType, message: [*:0]const u8) void { switch (ty) { .validation => std.log.err("gpu: validation error: {s}\n", .{message}), .out_of_memory => std.log.err("gpu: out of memory: {s}\n", .{message}), .device_lost => std.log.err("gpu: device lost: {s}\n", .{message}), .unknown => std.log.err("gpu: unknown error: {s}\n", .{message}), else => unreachable, } std.os.exit(1); } pub fn detectBackendType(allocator: std.mem.Allocator) !gpu.BackendType { const backend = std.process.getEnvVarOwned( allocator, "MACH_GPU_BACKEND", ) catch |err| switch (err) { error.EnvironmentVariableNotFound => { if (builtin.target.isDarwin()) return .metal; if (builtin.target.os.tag == .windows) return .d3d12; return .vulkan; }, else => return err, }; defer allocator.free(backend); if (std.ascii.eqlIgnoreCase(backend, "null")) return .null; if (std.ascii.eqlIgnoreCase(backend, "d3d11")) return .d3d11; if (std.ascii.eqlIgnoreCase(backend, "d3d12")) return .d3d12; if (std.ascii.eqlIgnoreCase(backend, "metal")) return .metal; if (std.ascii.eqlIgnoreCase(backend, "vulkan")) return .vulkan; if (std.ascii.eqlIgnoreCase(backend, "opengl")) return .opengl; if (std.ascii.eqlIgnoreCase(backend, "opengles")) return .opengles; @panic("unknown MACH_GPU_BACKEND type"); } /// Check if gamemode should be activated pub fn wantGamemode(allocator: std.mem.Allocator) error{ OutOfMemory, InvalidUtf8 }!bool { const use_gamemode = std.process.getEnvVarOwned( allocator, "MACH_USE_GAMEMODE", ) catch |err| switch (err) { error.EnvironmentVariableNotFound => return true, else => |e| return e, }; defer allocator.free(use_gamemode); return !(std.ascii.eqlIgnoreCase(use_gamemode, "off") or std.ascii.eqlIgnoreCase(use_gamemode, "false")); } const gamemode_log = std.log.scoped(.gamemode); pub fn initLinuxGamemode() bool { gamemode.start(); if (!gamemode.isActive()) return false; gamemode_log.info("gamemode: activated", .{}); return true; } pub fn deinitLinuxGamemode() void { gamemode.stop(); gamemode_log.info("gamemode: deactivated", .{}); } pub const RequestAdapterResponse = struct { status: gpu.RequestAdapterStatus, adapter: ?*gpu.Adapter, message: ?[*:0]const u8, }; pub inline fn requestAdapterCallback( context: *RequestAdapterResponse, status: gpu.RequestAdapterStatus, adapter: ?*gpu.Adapter, message: ?[*:0]const u8, ) void { context.* = RequestAdapterResponse{ .status = status, .adapter = adapter, .message = message, }; }