From d1e70957f20f4f4b30d4b6145113a92b13049a2f Mon Sep 17 00:00:00 2001 From: ItsDrike Date: Mon, 10 Jun 2024 13:53:12 +0200 Subject: [PATCH 1/5] Fix mistake in cpu type of herugrim host --- hosts/herugrim/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosts/herugrim/default.nix b/hosts/herugrim/default.nix index 5988f22..81c4c9d 100644 --- a/hosts/herugrim/default.nix +++ b/hosts/herugrim/default.nix @@ -58,7 +58,7 @@ type = "laptop"; virtual-machine = false; }; - cpu.type = "intel"; + cpu.type = "amd"; gpu.type = "nvidia"; hasTPM = true; }; From deee4df6539713a29c73d9047356c20ef4777901 Mon Sep 17 00:00:00 2001 From: ItsDrike Date: Mon, 10 Jun 2024 13:54:03 +0200 Subject: [PATCH 2/5] Fix nvidia on hybrid setups --- hosts/herugrim/default.nix | 2 +- hosts/herugrim/hardware-configuration.nix | 7 +++ options/device/hardware.nix | 11 ++++- system/shared/hardware/gpu/nvidia.nix | 56 +++++++++++++++++------ 4 files changed, 60 insertions(+), 16 deletions(-) diff --git a/hosts/herugrim/default.nix b/hosts/herugrim/default.nix index 81c4c9d..6b6beb7 100644 --- a/hosts/herugrim/default.nix +++ b/hosts/herugrim/default.nix @@ -59,7 +59,7 @@ virtual-machine = false; }; cpu.type = "amd"; - gpu.type = "nvidia"; + gpu.type = "hybrid-nvidia"; hasTPM = true; }; diff --git a/hosts/herugrim/hardware-configuration.nix b/hosts/herugrim/hardware-configuration.nix index c785643..28065df 100644 --- a/hosts/herugrim/hardware-configuration.nix +++ b/hosts/herugrim/hardware-configuration.nix @@ -66,4 +66,11 @@ nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + + # Enable prime-offload + # This machine has AMD igpu + nvidia dgpu, so we need hybrid + hardware.nvidia.prime = { + nvidiaBusId = "PCI:1:0:0"; + amdgpuBusId = "PCI:5:0:0"; + }; } diff --git a/options/device/hardware.nix b/options/device/hardware.nix index cddde3f..5b03a78 100644 --- a/options/device/hardware.nix +++ b/options/device/hardware.nix @@ -15,12 +15,21 @@ in }; gpu.type = mkOption { - type = with types; nullOr (enum [ "nvidia" "amd" "intel" ]); + type = with types; nullOr (enum [ "nvidia" "amd" "intel" "hybrid-nvidia" "hybrid-amd" ]); default = null; description = '' The manifaturer/type of the primary system GPU. Allows the correct GPU drivers to be loaded, potentially optimizing video output performance. + + If you're on a hybrid system (intel/amd igpu + nvidia/amd dgpu) make sure to use + the hybrid options, only specifying the dgpu will not work properly. + + Note that if using hybrid-nvidia, you will need to set `hardware.nvidia.prime.nvidiaBusId` + and `intelBusId` (or `amdgpuBusId`) to "PCI:x:y:z". To find the correct bus IDs, you can + use `sudo lshw -c display`. Note that you will need to convert the bus ID format from + hexadecimal to decimal, remove the padding (leading zeroes) and replace the dot with a + colon (so for example 0e:00.0 -> PCI:14:0:0). ''; }; diff --git a/system/shared/hardware/gpu/nvidia.nix b/system/shared/hardware/gpu/nvidia.nix index fed1519..5679760 100644 --- a/system/shared/hardware/gpu/nvidia.nix +++ b/system/shared/hardware/gpu/nvidia.nix @@ -1,29 +1,36 @@ { config, lib, pkgs, ... }: let dev = config.myOptions.device; + isWayland = config.myOptions.home-manager.wms.isWayland; + + inherit (lib) mkIf mkDefault mkMerge; in { - config = lib.mkIf (dev.gpu.type == "nvidia") { + config = mkIf (builtins.elem dev.gpu.type ["nvidia" "hybrid-nvidia"]) { # Nvidia drivers are unfree software nixpkgs.config.allowUnfree = true; # Enable nvidia driver for Xorg and Wayland services.xserver.videoDrivers = ["nvidia"]; + # blacklist nouveau module so that it does not conflict with nvidia drm stuff + # also the nouveau performance is horrible in comparison. + boot.blacklistedKernelModules = ["nouveau"]; + hardware = { nvidia = { # modeestting is required - modesetting.enable = lib.mkDefault true; + modesetting.enable = mkDefault true; # Nvidia power managerment. Experimental, and can cause sleep/suspend to fail. # Enable this if you have graphical corruption issues or application crashes after waking # up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead of just # the bare essentials - powerManagement.enable = lib.mkDefault true; + powerManagement.enable = mkDefault true; # Fine-grained power management. Turns off GPU when not in use. # Experimental and only works on modern Nvidia GPUs (Turing or newer) - powerManagement.finegrained = lib.mkDefault false; + powerManagement.finegrained = mkDefault false; # Use the NVidia open source kernel module (not to be confused with the # independent third-party "nouveau" open source driver). @@ -32,14 +39,27 @@ in # # Enable this by default, hosts may override this option if their gpu is not # supported by the open source drivers - open = lib.mkDefault true; + open = mkDefault true; # Add the Nvidia settings package, accessible via `nvidia-settings`. # (useless on NixOS) - nvidiaSettings = false; + nvidiaSettings = mkDefault false; # This ensures all GPUs stay awake even during headless mode. nvidiaPersistenced = true; + + # On Hybrid setups, using Nvidia Optimus PRIME is necessary + # + # There are various options/modes prime can work in, this will default to + # using the offload mode, which will default to running everything on igpu + # except apps that run with certain environmental variables set. To simplify + # things, this will also enable the `nvidia-offload` wrapper script/command. + prime.offload = let + isHybrid = dev.gpu.type == "hybrid-nvidia"; + in { + enable = isHybrid; + enableOffloadCmd = isHybrid; + }; }; # Enable OpenGL @@ -52,10 +72,6 @@ in }; }; - # blacklist nouveau module so that it does not conflict with nvidia drm stuff - # also the nouveau performance is horrible in comparison. - boot.blacklistedKernelModules = ["nouveau"]; - environment = { systemPackages = with pkgs; [ mesa @@ -67,12 +83,24 @@ in libva libva-utils + + glxinfo ]; - sessionVariables = { - LIBVA_DRIVER_NAME = "nvidia"; - WLR_NO_HARDWARE_CURSORS = "1"; - }; + sessionVariables = mkMerge [ + { LIBVA_DRIVER_NAME = "nvidia"; } + + (mkIf isWayland { + WLR_NO_HARDWARE_CURSORS = "1"; + }) + + # Run the compositor itself with nvidia GPU? + # Currently disabled + (mkIf (isWayland && (dev.gpu == "hybrid-nvidia")) { + #__NV_PRIME_RENDER_OFFLOAD = "1"; + #WLR_DRM_DEVICES = mkDefault "/dev/dri/card1:/dev/dri/card0"; + }) + ]; }; }; } From 54f1c40d61496be889e72db6f11fa41ea4cb3c30 Mon Sep 17 00:00:00 2001 From: ItsDrike Date: Mon, 10 Jun 2024 14:00:02 +0200 Subject: [PATCH 3/5] Run hyprland from profile (without wrapper script) --- home/programs/terminal/shell/zsh/rc/profile.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/home/programs/terminal/shell/zsh/rc/profile.zsh b/home/programs/terminal/shell/zsh/rc/profile.zsh index e13ea2b..de4a41f 100644 --- a/home/programs/terminal/shell/zsh/rc/profile.zsh +++ b/home/programs/terminal/shell/zsh/rc/profile.zsh @@ -12,7 +12,7 @@ fi # Start graphical session automatically on tty1 if Hyprland or startx is available if [ "$(tty)" = "/dev/tty1" ] && [ "$UID" != 0 ]; then if command -v Hyprland >/dev/null; then - ! pidof -s Hyprland >/dev/null 2>&1 && launch-hypr + ! pidof -s Hyprland >/dev/null 2>&1 && Hyprland elif command -v startx >/dev/null; then ! pidof -s Xorg >/dev/null 2>&1 && exec startx "$XINITRC" fi From 9d15387d5ea77da8a3a9db552940cce260e43876 Mon Sep 17 00:00:00 2001 From: ItsDrike Date: Mon, 10 Jun 2024 14:13:39 +0200 Subject: [PATCH 4/5] Add script to swap Hyprland workspaces across monitors This introduces xmonad like workspace swapping, i.e. if the workspaces is already focused on another monitor, a swap will occur, moving the workspace from the other monitor to the currently focused monitor and replacing it with the workspace originally focused on this monitor (i.e. swapping them). If we're only using 1 monitor, or the workspace isn't focused on any monitor, this will behave exactly like regular workspace focus command. --- .../wms/hyprland/config/keybinds.nix | 10 ++++++++- .../graphical/wms/hyprland/default.nix | 4 ++-- .../hyprland/packages/dbus-hyprland-env.nix | 11 ---------- .../wms/hyprland/packages/default.nix | 2 +- .../packages/hyprland-swap-workspace.nix | 4 ++++ .../packages/hyprland-swap-workspace.sh | 22 +++++++++++++++++++ 6 files changed, 38 insertions(+), 15 deletions(-) delete mode 100644 home/programs/graphical/wms/hyprland/packages/dbus-hyprland-env.nix create mode 100644 home/programs/graphical/wms/hyprland/packages/hyprland-swap-workspace.nix create mode 100644 home/programs/graphical/wms/hyprland/packages/hyprland-swap-workspace.sh diff --git a/home/programs/graphical/wms/hyprland/config/keybinds.nix b/home/programs/graphical/wms/hyprland/config/keybinds.nix index 880a730..cd9fc84 100644 --- a/home/programs/graphical/wms/hyprland/config/keybinds.nix +++ b/home/programs/graphical/wms/hyprland/config/keybinds.nix @@ -102,7 +102,15 @@ # # Switch workspace (swapping to current monitor) # - # TODO: requires script (swap-workspace) + "SUPER, 1, exec, hyprland-swap-workspace 1" + "SUPER, 2, exec, hyprland-swap-workspace 2" + "SUPER, 3, exec, hyprland-swap-workspace 3" + "SUPER, 4, exec, hyprland-swap-workspace 4" + "SUPER, 5, exec, hyprland-swap-workspace 5" + "SUPER, 6, exec, hyprland-swap-workspace 6" + "SUPER, 7, exec, hyprland-swap-workspace 7" + "SUPER, 8, exec, hyprland-swap-workspace 8" + "SUPER, 9, exec, hyprland-swap-workspace 9" # # Move window to workspace diff --git a/home/programs/graphical/wms/hyprland/default.nix b/home/programs/graphical/wms/hyprland/default.nix index 43c1e4d..ba062f0 100644 --- a/home/programs/graphical/wms/hyprland/default.nix +++ b/home/programs/graphical/wms/hyprland/default.nix @@ -6,7 +6,7 @@ }: let inherit (lib) mkIf; - inherit (import ./packages {inherit pkgs;}) dbus-hyprland-env; + inherit (import ./packages {inherit pkgs;}) hyprland-swap-workspace; cfg = osConfig.myOptions.home-manager.wms.hyprland; in { @@ -16,7 +16,7 @@ in { config = mkIf cfg.enable { home.packages = with pkgs; [ - dbus-hyprland-env + hyprland-swap-workspace ]; wayland.windowManager.hyprland = { diff --git a/home/programs/graphical/wms/hyprland/packages/dbus-hyprland-env.nix b/home/programs/graphical/wms/hyprland/packages/dbus-hyprland-env.nix deleted file mode 100644 index 8fef3e5..0000000 --- a/home/programs/graphical/wms/hyprland/packages/dbus-hyprland-env.nix +++ /dev/null @@ -1,11 +0,0 @@ -{pkgs, ...}: -pkgs.writeTextFile { - name = "dbus-hyprland-env"; - destination = "/bin/dbus-hyprland-environment"; - executable = true; - text = '' - dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=hyprland - systemctl --user stop pipewire pipewire-media-session xdg-desktop-portal xdg-desktop-portal-wlr - systemctl --user start pipewire wireplumber pipewire-media-session xdg-desktop-portal xdg-desktop-portal-hyprland - ''; -} diff --git a/home/programs/graphical/wms/hyprland/packages/default.nix b/home/programs/graphical/wms/hyprland/packages/default.nix index 36e2305..2679e8c 100644 --- a/home/programs/graphical/wms/hyprland/packages/default.nix +++ b/home/programs/graphical/wms/hyprland/packages/default.nix @@ -3,7 +3,7 @@ ... }: let packages = { - dbus-hyprland-env = pkgs.callPackage ./dbus-hyprland-env.nix {}; + hyprland-swap-workspace = pkgs.callPackage ./hyprland-swap-workspace.nix {}; }; in packages diff --git a/home/programs/graphical/wms/hyprland/packages/hyprland-swap-workspace.nix b/home/programs/graphical/wms/hyprland/packages/hyprland-swap-workspace.nix new file mode 100644 index 0000000..25433db --- /dev/null +++ b/home/programs/graphical/wms/hyprland/packages/hyprland-swap-workspace.nix @@ -0,0 +1,4 @@ +{pkgs, ...}: + pkgs.writeShellScriptBin "hyprland-swap-workspace" '' + ${builtins.readFile ./hyprland-swap-workspace.sh} + '' diff --git a/home/programs/graphical/wms/hyprland/packages/hyprland-swap-workspace.sh b/home/programs/graphical/wms/hyprland/packages/hyprland-swap-workspace.sh new file mode 100644 index 0000000..64030b4 --- /dev/null +++ b/home/programs/graphical/wms/hyprland/packages/hyprland-swap-workspace.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +WORKSPACE="$1" + +monitors_out="$(hyprctl monitors -j)" +focused_mon="$(echo "$monitors_out" | jq '.[] | select(.focused==true) | .id')" +focused_wks="$(echo "$monitors_out" | jq '.[].activeWorkspace.id')" + +# Workspace is already focused, check on which monitor +if echo "$focused_wks" | grep "$WORKSPACE" >/dev/null; then + mon_id="$(echo "$monitors_out" | jq ".[] | select(.activeWorkspace.id==$WORKSPACE) | .id")" + + # If the workspace is focused on the active monitor, don't do anything (we're here). + # Otherwise, swap the workspaces. + if [ "$mon_id" -ne "$focused_mon" ]; then + hyprctl dispatch swapactiveworkspaces "$focused_mon" "$mon_id" + fi +# Switching to an unfocused workspace, always move it to focused monitor +else + hyprctl dispatch moveworkspacetomonitor "$WORKSPACE" "$focused_mon" + hyprctl dispatch workspace "$WORKSPACE" +fi From c5074480ecc6c661897b8fdf1071115123b289be Mon Sep 17 00:00:00 2001 From: ItsDrike Date: Mon, 10 Jun 2024 14:17:48 +0200 Subject: [PATCH 5/5] Update nvim config --- home/programs/terminal/editors/neovim/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/home/programs/terminal/editors/neovim/default.nix b/home/programs/terminal/editors/neovim/default.nix index 1a1a168..2e58c6b 100644 --- a/home/programs/terminal/editors/neovim/default.nix +++ b/home/programs/terminal/editors/neovim/default.nix @@ -26,8 +26,8 @@ source = pkgs.fetchFromGitHub { owner = "ItsDrike"; repo = "AstroNvimUser"; - rev = "v0.1.0"; - sha256 = "sha256-2o25+2CHoDS90kDk5ixiQDE4MHybgvVLL7jr7AHWhqU="; + rev = "v0.1.2"; + sha256 = "sha256-PPejIy8BGxilcFAvBZQVfVDwTNEm1Tu6e0AlzIZbYXY="; }; recursive = true; };