Startx failing with intel graphics

Hello! I’m trying to get nvidia/intel hybrid graphics working on NixOS. I followed the directions on the nvidia wiki page and running $ primerun.sh emacs is working fine (my display manager is exwm via emacs). Unfortunately, I’m unable to get the intel half working. I’m using startx rather than a display manager. Here’s the relevant part of my config:

  environment.systemPackages = with pkgs; [
    # ...
    mesa
    xorg.xorgserver
    xorg.xf86inputlibinput
    xorg.xf86videointel
  ];

  services = {
    # Enable the X11 windowing system.
    xserver = {
      # Enable touchpad support.
      libinput.enable = true;

      enable = true;
      layout = "us";
      autorun = false;
      exportConfiguration = true;

      # manually start exwm with a startx script. this is only for
      # using the builtin intel GPU. To use the NVIDIA GPU use
      # primerun.
      displayManager.startx = {
        enable = true;
      };
      desktopManager.default = "none";
    };
  };

  hardware = {
    nvidiaOptimus.disable = true;

    opengl = {
      enable = true;

      extraPackages = with pkgs; [
        linuxPackages.nvidia_x11.out
        vaapiIntel
        vaapiVdpau
        libvdpau-va-gl
      ];
      driSupport = true;
      driSupport32Bit = true;

      extraPackages32 = with pkgs; [
        linuxPackages.nvidia_x11.lib32
      ];
    };
  };

My xinitrc is just exec emacs although I’ve also tried unsuccessfully with the full xinitrc provided by exwm.

When I run $ startx the computer freezes and I have to coldboot. Additionally there are no logs I can look at (journalctl is empty for the timeframe when i ran startx and the xorg log files are never written). I’ve also tried using lightdm to test if this is a problem with startx (displayManager.lightdm.enable = true; and take out the displayManager.startx and desktopManager parts). But when I run sudo systemctl start display-manager.service my computer also freezes and needs a coldboot.

I’m not sure I’ll be able to help you because I’m not experienced with Nvidia hardware, I have only Intel hardware. I’d suggest you to follow the instructions here as well: https://nixos.wiki/wiki/Accelerated_Video_Playback

Besides that, here are my 2 cents on your configuration.nix:

  1. I don’t think you need to (or that there will be any value in) add the xorg packages to environment.systemPackages. Adding the necessary services.xserver settings and optionally hardware.opengl should suffice (according to my experience).
  2. You don’t need exportConfiguration and autorun set to false under services.xserver because setting displayManager.startx.enable to true should suffice as well. A personal note here: A few days ago I’ve edited (improved IMO) the Wiki page: https://nixos.wiki/wiki/Using_X_without_a_Display_Manager and I think displayManager.startx.enable = true is the recommended method of achieving your goal.

Besides that, I noticed you mention that you need to cold-boot everytime your startx or whatever freezes. I think you can always switch to a different TTY using CTRL-ALT-F# and kill the X related process from there.

I’m not sure what’s display-manager.service is supposed to do, on my machine it’s masked (i.e symlinked to /dev/null (I guess because services.xserver.displayManager.startx.enable is true)).

Additional information which may help me help you:

  1. What’s inside the xinitrc provided by exwm?
  2. With displayManager.startx.enable = true, what’s the output of systemctl cat display-manager.service?
  3. What happens when you put nothing in / delete your ~/.xinitrc and run startx? Or alternatively, put there only exec xterm?
The other help I may give you is just share my own xserver and hardware related settings from my configuration.nix :
  hardware.opengl = {
    enable = true;
    extraPackages = with pkgs; [
      vaapiIntel
      vaapiVdpau
      libvdpau-va-gl
      intel-media-driver # only available starting nixos-19.03 or the current nixos-unstable
    ];
  };
  ...
  services.xserver.enable = true;
  services.xserver.displayManager.startx.enable = true;
  services.xserver.videoDrivers = [ "intel" ];
  services.xserver.layout = "us,il";

That solved it! Thanks so much for the help. The missing piece seemed to be

services.xserver.videoDrivers = [ "intel" ];

Which btw doesn’t cause problems when using primerun.

My pleasure.

Please mark my comment as the one that solved the issue for you.