---@module "utils.gpu" ---@author sravioli ---@license GNU-GPLv3 local wt = require "wezterm" local platform = require("utils.fn").fs.platform() --[[@class Utils.Fn.FileSystem.Platform]] ---see: https://github.com/KevinSilvester/wezterm-config ---@alias WeztermGPUBackend 'Vulkan'|'Metal'|'Gl'|'Dx12' ---@alias WeztermGPUDeviceType 'DiscreteGpu'|'IntegratedGpu'|'Cpu'|'Other' ---@class WeztermGPUAdapter ---@field name string ---@field backend WeztermGPUBackend ---@field device number ---@field device_type WeztermGPUDeviceType ---@field driver? string ---@field driver_info? string ---@field vendor string ---@alias AdapterMap { [WeztermGPUBackend]: WeztermGPUAdapter|nil }|nil ---@class GpuAdapters ---@field __backends WeztermGPUBackend[] ---@field __preferred_backend WeztermGPUBackend ---@field __preferred_device_type WeztermGPUDeviceType ---@field DiscreteGpu AdapterMap ---@field IntegratedGpu AdapterMap ---@field Cpu AdapterMap ---@field Other AdapterMap local GpuAdapters = {} GpuAdapters.__index = GpuAdapters ---See `https://github.com/gfx-rs/wgpu#supported-platforms` for more info on available backends GpuAdapters.AVAILABLE_BACKENDS = { windows = { "Dx12", "Vulkan", "Gl" }, linux = { "Vulkan", "Gl" }, mac = { "Metal" }, } ---@type WeztermGPUAdapter[] GpuAdapters.ENUMERATED_GPUS = wt.gui.enumerate_gpus() ---@return GpuAdapters ---@private function GpuAdapters:init() local initial = { __backends = self.AVAILABLE_BACKENDS[platform.os], __preferred_backend = self.AVAILABLE_BACKENDS[platform.os][1], DiscreteGpu = nil, IntegratedGpu = nil, Cpu = nil, Other = nil, } -- iterate over the enumerated GPUs and create a lookup table (`AdapterMap`) for _, adapter in ipairs(self.ENUMERATED_GPUS) do if not initial[adapter.device_type] then initial[adapter.device_type] = {} end initial[adapter.device_type][adapter.backend] = adapter end local gpu_adapters = setmetatable(initial, self) return gpu_adapters end ---Will pick the best adapter based on the following criteria: --- 1. Best GPU available (Discrete > Integrated > Other (for wgpu's OpenGl --- implementation on Discrete GPU) > Cpu) --- 2. Best graphics API available --- ---Graphics API choices are based on the platform: --- - Windows: Dx12 > Vulkan > OpenGl --- - Linux: Vulkan > OpenGl --- - Mac: Metal ---@see GpuAdapters.AVAILABLE_BACKENDS --- ---If the best adapter combo is not found, it will return `nil` and lets Wezterm decide ---the best adapter. --- ---Please note these are my own personal preferences and may not be the best for your system. ---If you want to manually choose the adapter, use `GpuAdapters:pick_manual(backend, device_type)` ---Or feel free to re-arrange `GpuAdapters.AVAILABLE_BACKENDS` to you liking ---@return WeztermGPUAdapter|nil function GpuAdapters:pick_best() local adapters_options = self.DiscreteGpu if not adapters_options then adapters_options = self.IntegratedGpu end if not adapters_options then adapters_options = self.Other end if not adapters_options then adapters_options = self.Cpu end if not adapters_options then wt.log_error "No GPU adapters found. Using Default Adapter." return nil end local adapter_choice = adapters_options[self.__preferred_backend] if not adapter_choice then wt.log_error "Preferred backend not available. Using Default Adapter." return nil end return adapter_choice end ---Manually pick the adapter based on the backend and device type. ---If the adapter is not found, it will return nil and lets Wezterm decide the best adapter. ---@param backend WeztermGPUBackend ---@param device_type WeztermGPUDeviceType ---@return WeztermGPUAdapter|nil function GpuAdapters:pick_manual(backend, device_type) local adapters_options = self[device_type] if not adapters_options then wt.log_error "No GPU adapters found. Using Default Adapter." return nil end local adapter_choice = adapters_options[backend] if not adapter_choice then wt.log_error "Preferred backend not available. Using Default Adapter." return nil end return adapter_choice end return GpuAdapters:init()