Need some help with amd+nvidia setup

Hello everyone,

I’m not able to get my new laptop use my external display and the laptop display at the same time. I first thought to make use of the internal gpu when possible, but right now I’d be happy to get back to work. I want the laptop display and the external monitor to work at the same time.

Here are some Infos about my system:

$ inxi -SMGx
System:    Host: kalamos Kernel: 5.10.32 x86_64 bits: 64 compiler: gcc v: 10.2.0 Desktop: herbstluftwm 0.9.2
           Distro: NixOS 21.05.git.4397711c75f (Okapi)
Machine:   Type: Laptop System: Schenker product: XMG CORE 15(M20, GTX 1650xx) v: Standard serial: <superuser required>
           Mobo: Schenker model: GK5NxxO M20 v: Standard serial: <superuser required> UEFI: American Megatrends v: N.1.20.A03
           date: 12/10/2020
Graphics:  Device-1: NVIDIA TU116M [GeForce GTX 1650 Ti Mobile] vendor: Tongfang Hongkong Limited driver: nvidia v: 460.73.01
           bus-ID: 01:00.0
           Device-2: Advanced Micro Devices [AMD/ATI] Renoir vendor: Tongfang Hongkong Limited driver: amdgpu v: kernel
           bus-ID: 06:00.0
           Device-3: Sonix HD Webcam type: USB driver: uvcvideo bus-ID: 3-4:4
           Display: x11 server: X.Org 1.20.11 driver: loaded: amdgpu,nvidia resolution: 1920x1080~144Hz
           OpenGL: renderer: AMD RENOIR (DRM 3.40.0 5.10.32 LLVM 11.1.0) v: 4.6 Mesa 21.0.1 direct render: Yes
$ nix-info -m
  • system: "x86_64-linux"
  • host os: Linux 5.10.32, NixOS, 21.05.git.4397711c75f (Okapi)
  • multi-user?: yes
  • sandbox: yes
  • version: nix-env (Nix) 2.3.10
  • channels(root): "nixos-21.05pre285574.8e4fe32876c"
  • nixpkgs: /nix/var/nix/profiles/per-user/root/channels/nixos

NixOS config (relevant parts):

{ config, pkgs, ... }:
{
  services.openssh.enable = true;
  hardware = {
    enableAllFirmware = true;
    cpu.amd.updateMicrocode = true;  #needs unfree
    opengl.enable = true;
    opengl.driSupport32Bit = true;
  };
  services.xserver = {
    videoDrivers = [ "nvidia" ];
  };
  boot.extraModulePackages =
    [ config.boot.kernelPackages.nvidia_x11
    ];
  hardware.nvidia = {
    prime = {
      #offload.enable = true;
      sync.enable = true;
      amdgpuBusId = "PCI:6:0:0";
      nvidiaBusId = "PCI:1:0:0";
    };
    modesetting.enable = true;
  };
}

I first tried with prime.offload=true with no luck. Offloading worked, but the external display was not working - only the laptop screen. I can give much more detail on what I tried, but I then read somewhere that tihs is not a good approach when using both displays. After a lot of trial&error I installed ubuntu to see if that can make sense where I fail. And surprise, surprise, both displays work out of the box. Here are some infos from Ubuntu:

xrandr --listproviders  #Ubuntu
Providers: number : 2
Provider 0: id: 0x1b8 cap: 0x1, Source Output crtcs: 4 outputs: 5 associated providers: 1 name:NVIDIA-0
Provider 1: id: 0x1fc cap: 0x6, Sink Output, Source Offload crtcs: 4 outputs: 1 associated providers: 1 name:Unknown AMD Radeon GPU @ pci:0000:06:00.0

Here the nvidia card is first provider and the igpu is second. I guessed that this is the way “prime.sync=true” works in nixos? While this worked with Ubuntu, the nvidia card must be marked as “always on”. When setting it to “on demand” in nvidia-settings I can’t get it to work in Ubuntu, either.

Now with NixOS and the above config, the laptop screen is black but the external monitor shows GDM and I can login. The providers look a bit different, though:

xrandr --listproviders  # NixOS 
Providers: number : 2
Provider 0: id: 0x1b8 cap: 0x1, Source Output crtcs: 4 outputs: 5 associated providers: 0 name:NVIDIA-0
Provider 1: id: 0x206 cap: 0x0 crtcs: 4 outputs: 1 associated providers: 0 name:Unknown AMD Radeon GPU @ pci:0000:06:00.0

This looks very similar to the output from ubuntu, but the amd card has no capabilities; so the xrandr commands to set the outputsource is not working. In ubunut it showed two capabilities: Sink Output, Source Offload.

xrandr --setprovideroutputsource 1 0
X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  140 (RANDR)
  Minor opcode of failed request:  35 (RRSetProviderOutputSource)
  Value in failed request:  0x206
  Serial number of failed request:  16
  Current serial number in output stream:  17

So the laptop screen cannot be connected and also does not show up in the output of xrandr.

I read a lot of posts (some were a bit older), some said that the amdgpu doesn’t work and one should use the modesetting driver. So I changed this in nixpkgs’ nvidia.nix where the corresponding changes appear.

With this change (using modesetting instead of amdgpu), the output shows one capapility and I can successfully run the xrandr --setprovideroutputsource command. But the notebook display is all black like not switched on.

I realized that the driver is marked as “Inactive” in the xorg config in nvidia.nix. So I removed this. Then the display stays on showing the boot output. The external display shows X. But xrandr --listproviders shows only one provider - the nvidia card.

I’m glad for any pointers to solve and/or better understand the whole thing. It would be nice to somehow get to the same state as Ubuntu (ubuntu has no xorg.conf to look at).

Thank you in advance and regards
Eike