X11 multi-head

Lazyweb, how do I get a Pi 4 running Raspbian 11 into X11 multi-head mode, meaning displays :0.0 and 0.1, rather than display :0.0 spanning both monitors?

If you answer, "Here's something that works on my machine that is not a Pi 4" that will not help me.

I gather that the video driver I want is called "modesetting", but if I use that, I can only ever get a single spanning screen that is 3200x1200x24. If I use the "fbdev" driver, I can get 2 screens, but both are 640x480x16.

Here's some crap that does not work when dropped into /usr/share/X11/xorg.conf.d:

Section "ServerLayout"
 Identifier "Dual"
 Screen 0 "Screen0" 0 0
 Screen 1 "Screen1" RightOf "Screen0"
EndSection

Section "Monitor"
 Identifier "Monitor0"
EndSection

Section "Monitor"
 Identifier "Monitor1"
EndSection

Section "Device"
 Identifier "Card0"
 Driver "modesetting"
#  Driver "fbdev"
 Option "Monitor-HDMI-1" "Monitor0"
 Option "Monitor-HDMI-2" "Monitor1"
 Option "ZaphodHeads" "HDMI-1,HDMI-2"
EndSection

Section "Screen"
 Identifier "Screen0"
 Device "Card0"
 Monitor "Monitor0"
#  DefaultDepth 24
#  SubSection "Display"
#    Modes "1920x1080"
#    Modes "1280x720"
#    Depth 24
#  EndSubSection
EndSection

Section "Screen"
 Identifier "Screen1"
 Device "Card0"
 Monitor "Monitor1"
#  DefaultDepth 24
#  SubSection "Display"
#    Modes "640x480"
#    Depth 24
#  EndSubSection
EndSection

(Why someone would voluntarily run X11 this way in this modern world I cannot fathom, but here we are.)

Update: I have reached the conclusion that it is not possible to make X11 do this on Raspberry Pi 4 hardware. However, I was able to debug the thing I was trying to debug by running a nested server with:

    Xephyr :1 -ac -screen 1280x720 -screen 640x480x8
Tags: , ,

39 Responses:

  1. pakraticus says:

    Shouldn't there be a second "Device" section for Card1?
    And shouldn't there be an explicit Screen for each device?
    That's my guess looking at the logs on my rpi4 and reading https://man.archlinux.org/man/extra/xorg-server/modesetting.4.en and https://nouveau.freedesktop.org/MultiMonitorDesktop.html

    The rpi4 is in a horrible location for adding a second monitor and testing so... I can't check it.

  2. John Shaw says:

    There is probably more to it than just the X configuration. I don't have a Pi 4, but I have messed around with resolutions on a 3. I think if you're using fbdev you need to set the resolutions separately. This can kind of be done at the command line with fbset but it's messy. On pre-4 Pis this involves some setting in the /boot/config.txt.

    I had to set something like
    hdmi_drive=2
    hdmi_group=2
    hdmi_mode=82

    for 1080p on a 3.

    For a 4 that's separate. I think for 1600x1200 @60hz on two monitors that should be something like

    hdmi_drive:0=2
    hdmi_group:0=2
    hdmi_mode:0=51
    hdmi_drive:1=2
    hdmi_group:1=2
    hdmi_mode:1=51

    Of course, it might just completely fail to work.
    https://github.com/raspberrypi/firmware/issues/1470

  3. seth says:

    I have never used a Pi or modesetting, but I have used ZaphodHeads on CentOS. Working syntax was different than the current manpages suggest (maybe because it was older?), so try specifying in the "Device" sections as follows:

    Section "ServerLayout"
      Identifier "dualhead"
      Screen 0 "First"
      Screen 1 "Second" RightOf "First"
    EndSection
    Section "Screen"
      Identifier "First"
      Device "HDMI"
    EndSection
     Section "Screen"
      Identifier "Second"
      Device "DVI"
    EndSection
    Section "Device"
      Identifier "HDMI"
      Driver "nouveau"
      Option "ZaphodHeads" "HDMI-1"
      Screen 0
    EndSection
    Section "Device"
      Identifier "DVI"
      Driver "nouveau"
      Option "ZaphodHeads" "DVI-I-1"
      Screen 1
    EndSection

    But my experience is not all drivers can actually do Zaphod mode successfully, even if the docs list the option.

    • Bill Paul says:

      I second this suggestion. Evidence suggests that the modesetting driver does support the ZaphodHeads option.

      X11 seems to be very firmly of the opinion that the configuration you want only works if you have completely independent "Devices," i.e. multiple different graphics cards. This agrees with my experience way back in the day, when I had a Sun SPARCStation IPX on my desk with a triple-headed setup with X11R5, using three separate SBus graphics adapters: the integrated cgsix color adapter, and two plug-in bwtwo black and white cards. Each adapter was a separate sub-display.

      The ZaphodHeads option allows you to take one physical graphics adapter (the modesetting one in this case) and define it several times over, each time with just one display output selected. This fakes the rest of the X server code into thinking there are five lights -- er, two cards -- to produce the same result.

      • jwz says:

        Adding a second Device and pointing Screen1 at it still gets me a single 3200x1200 screen.

        Section "Device"
          Identifier "Card0"
          Driver "modesetting"
          Option "Monitor-HDMI-1" "Monitor0"
          Option "ZaphodHeads" "HDMI-1"
        EndSection

        Section "Device"
          Identifier "Card1"
          Driver "modesetting"
          Option "Monitor-HDMI-2" "Monitor1"
          Option "ZaphodHeads" "HDMI-2"
        EndSection

        Amongst the diarrhea in Xorg.0.log is this, which I don't understand:

        (II) modeset(0): Output HDMI-1 using monitor section Monitor0
        (II) modeset(0): Output HDMI-2 has no monitor section

        • Bill Paul says:

          I think the problem here is you forgot to add the lines that say:

          Screen 0

          and

          Screen 1

          to the Device blocks.

          I created a sample configuration below which works with a machine I have here in the office. It's running FreeBSD instead of Linux, but that should not make much of a difference. Feel free to season to taste.

          In case it gets mangled, you can download a copy from here:

          http://people.freebsd.org/~wpaul/w00t/xorg-zaphod.conf


          Section "Device"
          Identifier "Device0"
          Driver "modesetting"
          BusID "PCI:0:2:0"
          Option "ZaphodHeads" "HDMI-1"
          Screen 0
          EndSection

          Section "Device"
          Identifier "Device1"
          Driver "modesetting"
          BusID "PCI:0:2:0"
          Option "ZaphodHeads" "HDMI-2"
          Screen 1
          EndSection

          Section "Screen"
          Identifier "Screen0"
          Device "Device0"
          SubSection "Display"
          Viewport 0 0
          Depth 1
          EndSubSection
          SubSection "Display"
          Viewport 0 0
          Depth 4
          EndSubSection
          SubSection "Display"
          Viewport 0 0
          Depth 8
          EndSubSection
          SubSection "Display"
          Viewport 0 0
          Depth 15
          EndSubSection
          SubSection "Display"
          Viewport 0 0
          Depth 16
          EndSubSection
          SubSection "Display"
          Viewport 0 0
          Depth 24
          EndSubSection
          EndSection

          Section "Screen"
          Identifier "Screen1"
          Device "Device1"
          SubSection "Display"
          Viewport 0 0
          Depth 1
          EndSubSection
          SubSection "Display"
          Viewport 0 0
          Depth 4
          EndSubSection
          SubSection "Display"
          Viewport 0 0
          Depth 8
          EndSubSection
          SubSection "Display"
          Viewport 0 0
          Depth 15
          EndSubSection
          SubSection "Display"
          Viewport 0 0
          Depth 16
          EndSubSection
          SubSection "Display"
          Viewport 0 0
          Depth 24
          EndSubSection
          EndSection

          Section "InputDevice"
          Identifier "Keyboard0"
          Driver "kbd"
          EndSection

          Section "InputDevice"
          Identifier "Mouse0"
          Driver "mouse"
          Option "Protocol" "auto"
          Option "Device" "/dev/sysmouse"
          Option "ZAxisMapping" "4 5 6 7"
          EndSection

          Section "Files"
          ModulePath "/usr/local/lib/xorg/modules"
          FontPath "/usr/local/share/fonts/misc/"
          FontPath "/usr/local/share/fonts/TTF/"
          FontPath "/usr/local/share/fonts/OTF/"
          FontPath "/usr/local/share/fonts/Type1/"
          FontPath "/usr/local/share/fonts/100dpi/"
          FontPath "/usr/local/share/fonts/75dpi/"
          FontPath "catalogue:/usr/local/etc/X11/fontpath.d"
          EndSection

          Section "Module"
          Load "glx"
          EndSection

          Section "ServerLayout"
          Identifier "default"
          Screen "Screen0" 0 0
          Screen "Screen1" RightOf "Screen0"
          InputDevice "Mouse0" "CorePointer"
          InputDevice "Keyboard0" "CoreKeyboard"
          EndSection

          • jwz says:

            Nope. Adding Screen 0 and 1 makes X fail to start with "modeset(1): No modes" and "Screen(s) found, but none have a usable configuration".

            • Bill Paul says:

              I have to ask: did you try with the example I provided? (You'll probably have to change the BusID part and maybe the Mouse device path for setup. I'm not sure how that works for the Pi since the graphics controller likely isn't connected via PCI.)

              If that still doesn't work, we'd need more info, particularly:

              - the output of X -configure (to get an idea of what the X server thinks it wants for the Pi)
              - the output of the Xorg.log.0 file when you run the X server so we can get an idea of what it thinks it finds (what actual outputs are present, can it actually detect both monitors, what modes does it find, etc...)

              I suspect it should be possible to make this work, but I can't say why it's not working now without being able to see over your shoulder.

              • jwz says:

                I did. I also tried it after removing the inputdevice stuff, and busID. lspci on this box doesn't list a video driver, only a PCI bridge and a USB controller, so if that's required I don't know what it should be. Even when it fails to launch, it still shows that it got EDID data from both monitors so it knows they're there even in the bad configurations.

                "X -configure" and "Xorg :1 -configure" no longer work, so that's fun. "No devices to configure. Configuration failed."

                This is what X logs with the default configuration, none of my mods. It comes up with a single screen spanning both monitors, so it's not like the frame buffer isn't big enough or something. With this in /usr/share/X11/xorg.conf.d/30-jwz.conf, this is logged and X doesn't start.

                • Bill Paul says:

                  Well, in your custom config file, you have the ZaphodHeads option lines commented out. Also you're using HDMI-1,HDMI-1 and HDMI-2,HDMI-2 instead of just HDMI-1 and HDMI-2. what if you fix those two things?

                  You should see a reference to the ZaphodHeads option in the log file when it's properly enabled (it should show up for both modest instances).

                  It looks like it is autoprobing the supported monitor modes so I don't know why it's saying "no modes."

                  • jwz says:

                    conf 2, log 2. It's coming up with a single 3200x1200x24 screen.

                    I guess ZaphodHeads needs to be "HDMI-1,HDMI-2" on both of them; if each only lists one, X doesn't come up.

                  • Bill Paul says:

                    Humor me:

                    1) Get rid of the Monitor specifications (if you look at my example I don't use then). This includes the Monitor options in the Devices blocks.

                    2) Please just use HDMI-1 and HDMI-2 (along with the above change)

                    3) If the server still won't start, show me the log.

                    4) I don't suppose this hardware is at DNA is it? Because I'm headed home from work and will pass close by.

                  • jwz says:

                    Doesn't start. conf 3, log 3.

                  • Bill Paul says:

                    Hm. Well, that last sample config file actually worked for me on my machine, so I'm a bit confused. I don't get the "No modes." error from the modesetting driver. But this is an X86 system with Intel 4000 graphics.

                    I modified the sample to include explicit mode lines in the Display sections, and this also works: the primary display is set to 1920x1080 and the secondary is set to 640x480 (which is weird, but that seems to be what you were aiming for). This means it is trying to parse the Modes entries in the configuration file, at least for me.

                    You can give this a try:

                    http://people.freebsd.org/~wpaul/w00t/xorg-conf-jwz.txt

                    The resulting log when I run this on my machine is here:

                    http://people.freebsd.org/~wpaul/w00t/xorg1log.txt

                    Note: for my system, the output names are eDP-1 and HDMI-1 instead of HDMI-1 and HDMI-2, but I used HDMI-1 and HDMI-2 in the file above to match your configuration.

                    If this doesn't work then I'm a bit stumped, unless there's something funny going on with the underlying RPi4 graphics driver.

                    Oh, also, as a test, I tried using "eDP-1,HDMI-1" and "HDMI-1,eDP-1" with the ZaphodHeads options, and this also worked for me, however in the log file I can see that it probed the mode lines for both displays for both the modeset(0) and modeset(1) instances. It still ended up choosing the correct displays though. I'm not exactly what, if anything, that syntax is supposed to accomplish though.

                  • jwz says:

                    Nope, still "Screen(s) found, but none have a usable configuration."

                    I suppose it's possible that this just doesn't work at all on a Pi 4, but since xinerama/randr works fine, I can't fathom why that would be.

    • jwz says:

      So your answer is "Here's something that works on my machine that is not a Pi 4".

      • seth says:

        Yes, because it doesn't use the documented options in the manpages and doesn't set anything about monitors. I never got Zaphod working the way you had it configured even though that's what the docs suggest.

        I realize that's useless if your problem is Pi specific and not xorg.

  4. Eric TF Bat says:

    When I was messing around with Linux and dual monitors years ago, I remember something like your configuration file for convincing X to talk to two screens, but also xrandr for telling it how big those screens are. Maybe the partial success of the fbdev driver suggests that the problem of screen resolutions is outside the scope of that configuration file. I have no idea if this is old news to you.

    • jwz says:

      The problem is not "get X to talk to two monitors", that's working fine. The problem is "get xdpyinfo to say that there are 2 screens instead of a single screen that spans both monitors." That is at a lower level than xrandr.

      • k3ninho says:

        File this under 'Linux remaking things' and say they've fucked about with it: I don't think xdpyinfo is lower-level than xrandr when you're using Linux Kernel Modesetting (KMS) because KMS imported the patterns from xrandr in its handling of data flowing from framebuffers to (things known as but not at all controlling x-ray guns) CRTC's. xdpyinfo may an old tool in a new world.

        The xrandr spec says that using KMS will only one have one framebuffer that you set up crtc views on. If xdpyinfo is unable to report two screens, you need to use the offset positions within the main framebuffer. There are extensions to Multi-Pointer X and other approaches to multi-seat to isolate these xrandr-controlled slices of the KMS framebuffer.

        Atomic mode setting design overview, part 1
        Atomic mode setting design overview, part 2
        Kernel Mode Setting (KMS) docs

        K3n.

  5. vc says:

    Glancing at the modesetting(4) man page's description of the "ZaphodHeads" option leaves me with the impression that you're expected to create multiple driver instances for the same driver, all using the "ZaphodHeads" option.

    In the example you've pasted, you have a single Device section enumerating the two outputs via "ZaphodHeads". But if I'm understanding the man page correctly, this will assign those outputs to the single driver instance. That is not what you want.

    ZaphadHeads is a sort of hack, so you need to create a duplicate Device section having the same driver, with ZaphodHeads assigning the other output in the other instance.

    Something like https://russ.garrett.co.uk/2013/04/15/driving-monitoring-displays-in-linux/ but omitting the BusId, and s/radeon/modesetting/ I imagine.

  6. Alasdair says:

    I'll preface this by saying I have not tried to run my Pi4 dual-screen with X11, but I did have to mess around with /boot/config.txt options to get my Pi4 to output 720p on my 4K TV (RetroPie in 4k was unusable).

    There are lots of HDMI related settings which may be applicable:

    https://www.raspberrypi.com/documentation/computers/config_txt.html#hdmi-mode

    I suspect you may need to set hdmi_group and hdmi_mode for the individual displays, but I'm not sure if the Pi will still merge them into one big display. There are also some kind of limitations that I'm not sure I understand:

    https://www.raspberrypi.com/documentation/computers/config_txt.html#raspberry-pi-4-hdmi-pipeline

    I also found the "tvservice" command fairly helpful. Messing with this helped me figure out what was going on display-wise (I figured out I was plugged into the wrong HDMI port the whole time).

    • jwz says:

      Right now I am looking at monitors plugged into both HDMI ports of the Pi and they are both working. One is running in 1920x1080 and the other maxes out at 1600x900. So it has been demonstrated that the Pi's hardware, kernel and HDMI drivers are capable of pushing different video out each of these ports at the same time.

      What I'm having is an Xorg configuration issue, where it's willing to drive them both as a single monitor-spanning X11 "Screen", but not as two.

      On this Pi 4, "tvservice" says "not supported when using the vc4-kms-v3d driver" and says to use "modetest", which.... prints 2,003 lines of crap that means nothing to me.

  7. Lloyd says:

    The Pi has two HDMI ports! Not a single port using the rare HDMI type B dual connector?

    That's a lost opportunity for progress.

  8. noname.c says:

    sudo startx 'cinnamon-session' -- :1
    just an example, there's other than cinnamon DMs.

    • noname.c says:

      without quotes that is
      if needed, the whole path to DMs's exec may be given

      • noname.c says:

        Also sudo isn't needed if there is another user account. Login that account and run without sudo whichever Desktop Manager session you want.

        • noname.c says:

          Totally forgot. This has to be started on a tty. Not inside some Desktop Manager. So that means Alt+F[1-6] tty logins.

  9. pakraticus says:

    So, nothing shows up in lspci because of the system on chip device hell that is ARM.
    Instead they have device tree overlays... https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README
    Which then leads to
    https://www.raspberrypi.com/documentation/computers/config_txt.html#max_framebuffers

    And for reasons I don't understand my /boot/config.txt has [pi4]max_framebuffers=1.
    And I can't check dmesg output with [pi4]max_framebuffers=2 because I lack a second display cable. And the docs say it won't enable the second frame buffer if it doesn't see a device.

    Anyways, I'm curious what appears in dmesg if you change max_framebuffers and reboot. I'm also curious if you have max_framebuffers in the pi4 section of your config.txt.

    • jwz says:

      It's already set to 2, so it seems unlikely that reducing it would make things better.

      • Christopher Dukes says:

        I didn't see dmesg output in the thread and I'm curious if you see a 'fb1' in addition to the 'fb0' I see. Do you mind posting dmesg output?

        And the X11 dual screen without xinerama/xrandr crud seems like the only option to switch desktops on one monitor and not the other. And that seems like a win for video editing and digital audio workstation work. I am curious as to your use case. Do you mind sharing?

        I'll poke at it again when another HDMI cable for the pi4 is delivered.

        • jwz says:

          dmesg does not seem to mention fb1.

          There is absolutely nothing to recommend dual-head without xinerama/randr unless you really enjoy not being able to drag a window from one screen to the other. I don't know exactly what you mean by "switch desktops" but I'm sure that's orthogonal. Xorg should have dropped support for 80s-style multi-screen decades ago, but they didn't, which means there are one or two lunatics in the world who still use it for no reason I have heard adequately explained, and one of those people reported an XScreenSaver oddity that I would like to try and reproduce.

          • pakraticus says:

            Thank you, that scratches that hypothesis. And it scratches using a rpi4 as my digital audio workstation machine.
            The inability to move a window between monitors is desirable when I want a screen dedicated to audio/midi routing and audio monitors.
            And many physical design folks learned the software with the old X can't drag a window between multiple screens model.
            I may poke at using virtualbox and kvm to validate such an Xorg config.
            I'll probably punt to running those in a xephyr display.

            For your use case... 'xephyr -screen 1920x1080 -screen 1920x1080 -ac :1' passes the 'xdpyinfo | grep -i screen' test.
            And 'Xephyr +extension RANDR +xinerama -screen 1920x1080 -screen 1920x1080 -ac :1' fails it.

            All bets are off if they also have DPMS + Display Port + Active Display Port to HDMI dongles.

            As for the other lunatics... Most of mine were folks doing Physical Design for Integrated Circuits... and this end of life letter shows how long they'll linger.
            https://www.cadence.com/content/dam/cadence-www/global/en_US/documents/support/red-hat-enterprise-linux5-eol.pdf

            • jwz says:

              You're right, Xephyr will let me debug this. I should have thought of that, but... I 100% forgot that it existed at all. Thanks for the reminder!

          • Denilson says:

            Have you tried asking that person for a copy of their xorg.conf?

            • jwz says:

              Yes, I did that before posting this. See the part where I said,

              If you answer, "Here's something that works on my machine that is not a Pi 4" that will not help me.

              There was a reason I said that. Really and truly.

              From all of the other comments on this post, I have concluded that a Pi 4 simply cannot do this.

              But hey, thanks for asking me "did you try turning it off and on again".

              • Walex says:

                «From all of the other comments on this post, I have concluded that a Pi 4 simply cannot do this»

                Most of the other comments are based on a set of common misunderstandings about the Xorg server, all courtesy of Keith Packard. The situation is explained here:

                http://www.sabi.co.uk/blog/12-thr.html?121019#121019

                The tl;dr is that the Xorg server can handle multiple monitor is two completely different modes using different configuration syntax, "new" with all mapped into a single "X screen" or "legacy" with each as its own "x Screen", and some drivers support only one mode, some both.

                Unfortunately I don't know which RPi4 Xorg driver supports which mode.

                • jwz says:

                  Ok, well, you're wrong. Prove it.

                  Once you prove it -- by giving me a config that works on a Pi 4 -- I will retract my claim. But at this point the onus is on you to back up your unsupported assertion.