Three monitors with Linux (Slackware)

Created: 2022-08-03
Updated: 2023-03-06

There’s a lot of badly outdated information out there about "multi-head" Linux systems. In fact, multiple monitors on a single graphics card usually works quite well in X11 (aka "X" or "X Window System").

one landscape and two portrait monitors

(The window manager in use here is dwm, specifically I talk about this setup at the bottom of How I use dwm.) page).)

I’m going to present this saga in reverse, starting with what worked. If you scroll all the way down, you’ll get to my first attempt.

First, what works

two cards that didn’t work great together

I finally broke down and bought a brand new VisionTek Radeon RX 550 4GB GDDR5 for $250. It has four DisplayPort ports and it just works right out of the box with Slackware 15.0. My the three monitors start working as soon as the drivers/modules load while Linux is booting.

(This card is what’s shown at the far right under the green check mark in the above image. It’s so much slimmer than the other two monster cards in the middle.)

Once in X11, I just needed to tell it to rotate two of the monitors and in which order.

Here’s my .xinitrc. The if statement lets me share the same file across computers and detect hosts for specific configuration like this. Also, check out that sweet ASCII art so I remember what the setup looks like (I’m so good to my future self):

if [[ 'callisto' == $host ]]
    #         +---+ +---+
    # +-----+ |   | |   |
    # | dp0 | |dp4| |dp3|
    # +-----+ |   | |   |
    #         +---+ +---+
    xrandr --output DisplayPort-4 --right-of DisplayPort-0 --rotate left
    xrandr --output DisplayPort-3 --right-of DisplayPort-4 --rotate left
    echo "Hi Callisto"

(By the way, if you ever wonder how to stop X from mirroring the same content on two screens, the answer might be to use --right-of and --left-of until they display separate content. It seems you can also use these directives to make mirroring happen.)

What probably would have worked, but…​

The big video card under the gravestone in the picture above is a Visiontek Radeon RX 470 4GB Reference Edition. I bought it for $60 on eBay. The seller tested it and it worked.

I tested it and it worked (well, first I had to upgrade from ancient Slackware 14.2 to Slackware 15.0 to get a modern kernel with modern Radeon support).

And then it died one morning. Blank screens. Nothing. Opened the computer and saw that the fans weren’t even spinning on it. Dangit! I had to put my old card back in and live with two monitors for a while longer ("woe is me," I know).

I suppose the visible rust around the ports on the back of the card were a bad sign?

Anyway, I’m sure it would have been a great card if it had lived longer.

What worked, but had horrible cursor jittering

This pair is pictured under the barfing face in the video card picture above:

Sapphire Radeon HD 6900 running two monitors

  • DisplayPort (monitor in landscape orientation)

  • HDMI (monitor in portrait orientation).

XFX Radeon HD 6450 running one monitor

  • HDMI (another portrait monitor)

(The 6900 has two unused DVI ports and the 6450 has unused VGA and DVI ports.)

Apparently "all" I needed to get this working was:

$ xrandr --setprovideroutputsource 1 0
$ xrandr --auto
$ xrandr --output HDMI-1-0 --right-of HDMI-1 --rotate left

The key being the first two commands. The third is only because I have that monitor in portrait orientation.

The cursor is jerky and has artifacts and "dragging" anything in any application is pretty bad. Luckily I don’t need to do that a lot in my programming job. (Also, the cursor gets visibly redrawn every time that portion of the screen is refreshed - to the point where it practically disappears when I hover over a web page with an animation on it!)

I wish I understood why I need to do the --setprovideroutputsource. I feel like it’s pushing stuff THROUGH one of the cards to the other? Just a guess. Grrr. I understand words like "provider" and "source" and "sink", but what does it mean in this context? Why do I need to do this before anything shows up on my screen?

It turns out, nobody knows why. Nobody knows how X works. Prove me wrong.

I ran this for about half a year and it worked reliably (other than the terrible cursor flickering).

Here’s what I put in my .xinitrc (note the shared "dotfile" only runs these commands on that specific machine):

# rotate two right portrait screens on callisto
if [[ 'callisto' == $host ]]
    # 0 is the Sapphire Radeon 6900, 1 is the Radeon 6459 "CAICOS"
    xrandr --setprovideroutputsource 1 0
    xrandr --auto
    xrandr --output HDMI-1 --rotate left
    xrandr --output HDMI-1-0 --right-of HDMI-1 --rotate left
    xrandr --output HDMI-1-0 --right-of HDMI-1 --rotate left

After a while, the cursor flickering was intolerable. The application I work on for my day job (which is what I use this computer for) has animated spinners all over the place and browser repainting causes my cursor to become invisible. I can’t even use the dev tools. :-(

One card with Active DVI to DisplayPort adapter

This machine currently has a Sapphire Radeon HD 6900 series with four output ports.

(This is the big card under the barfing face in the video card picture at the top of the page.)

I wanted to connect my third monitor to one of the two DVI ports.

  • HDMI

  • DisplayPort

  • DVI 1

  • DVI 2

Note that two monitors (hdmi + displayport) works right out of the box with no problems.

I was not able to get a third to display when connecting to either of the DVI ports directly. Internet lore says that it’ll work with three if you use an "active" converter to turn one of the DVI ports to DisplayPort.

a photo of my dvi to displayport table with instruction sheet

So I got one that uses a USB connection to power the active circuitry. It worked…​some of the time. I’d say about half of the time.

So that’s not going to cut it. At least I tried a cheap solution first.

Raw notes from the two-card setup

(I’m including this for posterity and maybe it will somehow help someone else.)

So, hoping for better stability, I’ve popped another low-power (only has a heatsink to cool it) Radeon HD 6450 in there. xrandr sees it, but the monitor doesn’t display the Linux virtual terminal nor does X11 do anything with it.

Doing an xrandr --listproviders displays both cards. But only the first cards shows any displays.

$ xrandr --listproviders
Providers: number : 2
Provider 0: id: 0xb7 cap: 0xf, Source Output, Sink Output, Source Offload,
			Sink Offload crtcs: 6 outputs: 4 associated providers: 0
            name:AMD Radeon HD 6900 Series @ pci:0000:08:00.0
Provider 1: id: 0x56 cap: 0xf, Source Output, Sink Output, Source Offload,
		    Sink Offload crtcs: 4 outputs: 3 associated providers: 0
            name:CAICOS @ pci:0000:03:00.0

I have no idea what I’m doing, but I see that there’s a --setprovideroutputsource option:

$ man xrandr
       --setprovideroutputsource provider source
              Set  source as the source of display output images for provider.
              This is only possible if source and provider have the Source
              Output and Sink Output capabilities, respectively.  If source is
              0x0, then provider is disconnected from its current output source.

If I try it with 0 1, it crashes the display. I can shut down the computer normally with a tap of the hardware on/off button, so it’s not crashed too bad, but I can’t see anything.

I try it with 1 0 and it does something:

$ xrandr --setprovideroutputsource 1 0

Here’s the provider listing after the above command. Note the "associated providers" has changed from 0 to 1 on both cards. I do not understand these systems well enough to know why I need to do this.

$ xrandr --listproviders
Providers: number : 2
Provider 0: id: 0xb7 cap: 0xf, Source Output, Sink Output, Source Offload,
            Sink Offload crtcs: 6 outputs: 4 associated providers: 1
            name:AMD Radeon HD 6900 Series @ pci:0000:08:00.0
Provider 1: id: 0x56 cap: 0xf, Source Output, Sink Output, Source Offload,
            Sink Offload crtcs: 4 outputs: 3 associated providers: 1
            name:CAICOS @ pci:0000:03:00.0

And now the second card shows a connected HDMI display (which is correct):

$ xrandr | grep " connected"
DisplayPort-0 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 527mm x 296mm
HDMI-1 connected 1080x1920+1920+0 left (normal left inverted right x axis y axis) 527mm x 296mm
HDMI-1-0 connected (normal left inverted right x axis y axis)

But the display is still blank (and shows a "no signal").

Furthermore, my cursor still stops at the same edge of both displaying monitors - so I think that tells me that X isn’t using the third display.

I’ll probably screw around with this for another day or so, but then I’m going to consider just getting a card that supports a bunch of monitors. I don’t game on this machine, so I don’t need a powerful GPU. I just need to be able to display lots and lots of text. :-)

Later: Two cards works! I just tried:

$ xrandr --auto

…​and bam! the third monitor just came up!

$ man xrandr
    --auto  For connected but disabled outputs, this will enable them using
            their first preferred mode (or, something close to 96dpi if they
            have no preferred mode).

But it’s just a mirror of the first monitor.

…​Rotating it works.

$ xrandr --output HDMI-1-0 --rotate left

…​And giving it a position (right of another monitor) makes it perfect!

$ xrandr --output HDMI-1-0 --right-of HDMI-1