How to create a virtual monitor/display?

I’m using KDE Wayland and would like to create a virtual monitor to use it while playing games streamed locally (Sunshine)

A common way of doing this in the Sunshine community is to buy a dummy hdmi or display port plugin, but, honestly, I’m using linux, I can’t believe that there isn’t a way to do this via software.

Does anyone knows of any way this can be accomplished?

Seems this is a thing in mutter: Headless native backend and virtual monitors (!1698) · Merge requests · GNOME / mutter · GitLab

Any way to do it in Plasma?

1 Like

The tool in X would be xrandr. You could try to search for “xrandr wayland” (no warranty :slight_smile: ) for similar approaches.

You can create Virtual Monitors when Screen Sharing, as long as the screen sharing app utilizes the Portal for it. ( On Wayland, this is always the case )

I think they added this feature to KDEConnect too, but I have never tested it. ( Somthing along the lines of Screen Sharing )

1 Like

Like @Jack_White already commented, you can create one in the screen share portal.
Sunshine however doesn’t use it and instead relies on kmsgrab. kmsgrab comes with a bunch of problems, the most important one for you is that it can only record physical monitors.
So even if you could create a virtual monitor without the screen share portal, it wouldn’t be useful.

2 Likes

I know that this is a bit of an old thread, but I wanted to reply since I went through the same problem and managed to find a solution that works for me.

I currently have a Linux Mint install on a computer that is acting as a NAS/Home server. While I can do quite a few things through the terminal, there are some occasional things that I need to do that I have an easier time doing through GUIs. I am using the Cinnamon DE, and since Cinnamon added experimental support for Wayland, I setup my server with a monitor attached to auto-login into Wayland Cinnamon. After finishing setup, I detached the monitor. (Since I would only be using GUIs occasionally, I know I could just use X11 Cinnamon, but I wanted Wayland and I was stubborn about it.)

The method I used to get a virtual display working is Kernel mode settings. It can be read more about it here:
wikidotarchlinuxdotorg/title/Kernel_mode_setting

The steps I used to achieve this were:

Step 1: I extracted the edid of the monitor that I would be using on the client into an edid.bin file. Since the monitor I extracted from was 2560x1440@60, I renamed the file qhd.bin.
In addition to extracting edid directly from a monitor, some good edid files can be downloaded from here:
githubdotcom/xi784/EDID-Emulator-Profiles

Step 2: I transferred the qhd.bin file to the headless server and placed it in “/usr/lib/firmware/edid/qhd.bin”. From here on out, the rest of my code was ran on the headless server.

Step 3: Next, I figured out what outputs my gpu on my headless server has by running “ls /sys/class/drm/card*”. This gave the results:
/sys/class/drm/card0@ /sys/class/drm/card0-HDMI-A-1@ /sys/class/drm/card0-HDMI-A-3@ /sys/class/drm/card1-DP-2@ /sys/class/drm/card1-DVI-I-1@
/sys/class/drm/card0-DP-1@ /sys/class/drm/card0-HDMI-A-2@ /sys/class/drm/card1@ /sys/class/drm/card1-DP-3@
I ended up using output “HDMI-A-1” since it was on GPU “card0” ,and from my tests “card1” would not have a visible mouse cursor in Wayland through Moonlight, vs “card0” which did not have this problem. Both cards had visible cursors when using an X11 DE through Moonlight. Having chosen my output, I then ran “sudo nano /etc/default/grub” and changed:
GRUB_CMDLINE_LINUX=“”
to:
GRUB_CMDLINE_LINUX=“drm.edid_firmware=HDMI-A-1:edid/qhd.bin video=HDMI-A-1:1280x720@120e”
The important parts are the last “e” from “video=HDMI-A-1:1280x720@120e” which basically tells the OS to treat the corresponding GPU port as if there is a monitor attached even if a monitor is not attached, and “edid/qhd.bin” from “drm.edid_firmware=HDMI-A-1:edid/qhd.bin” which specifies the edid of the virtual monitor. I also added in “1280x720@120” as an extra resolution and refresh rate.

Step 4: Finally, I ran “sudo update-grub” and then rebooted the headless server. At this point, I head my virtual monitor working, and because of my setup, the virtual monitor was treated as if it was actually hooked up to the GPU. Technically, what I am doing is software edid emulation.

Unfortunate, there is still one last issue that I ran into. The edid I used came from a 2560x1440 monitor, but when using that edid on the HDMI-A or DP GPU outputs, the max resolution of my virtual monitor was 2048x1080. I was able to get 2560x1400 when using the DVI output, but since that was on “card1” that would mean no cursor when using Wayland through Moonlight. On the other hand, using the EDIDs from githubdotcom/xi784/EDID-Emulator-Profiles allowed the GPU ports to max out at their maximum settings, which were 3840x2160@30 for the HDMI-A and 3840x2160@60 for the DP.

3 Likes

Wow I just wanted to throw some kuds to @vyacheslavl

This solution completely worked for me! The assigned port on my RX 9070XT immediately “binds” the edid at boot and the monitor is available even if the physical one has turned off. I almost bought a new dummy plug, but this solution has negated the need for that.

I’m also using Bazzite which has an immutable FS, so I needed to create an RPM that could add the EDID to the system firmware directory. I used this guide: wwwdotredditdotcom/r/Fedora/comments/wir3cq/guide_adding_custom_files_to_the_root_filesystem/

Lifesaver. This just works, great find.

This seems like exactly what I have been looking for! My one question is what do I do for the grub part if I use systemd-boot instead?

Hey, a bit late but if you’re still wondering this is how I did it.
Open your loader entry of choice, and add this to the end of your options.

Edit EDID firmware, adapter, and resolution as needed. To make a virtual screen based on my laptop’s 2560x1600 60Hz screen, I use this:

drm.edid_firmware=DP-3:edid/ideapad5-edid.bin video=DP-3:2560x1600@60e

This is what my entire configuration looks like:

title Arch Linux (Virtual DP-3)
linux /vmlinuz-linux
initrd /initramfs-linux.img
options "root=UUID=2dcb8a25-a613-462f-ac58-5842952681de rw amdgpu.gpu_recovery=1 drm.edid_firmware=DP-3:edid/ideapad5-edid.bin video=DP-3:2560x1600@60e"

If you look at the title, you can see I made this its own loader configuration. That’s because I only need this configuration when I’m out & about, so before I travel I set my computer to automatically boot from this configuration. That way it makes the virtual monitor available when I start my computer via WoL.

As an aside, I think this increases the boot time a bit, I can’t tell if it’s because of mode switching or not, but your mileage may vary.

1 Like

in my case, I want to try it on my laptop, which has both VGA and HDMI (both are listed when I do ls /sys/class/drm/card*). but I normally use HDMI, would it be possible to use the same approach you talk about, but using the VGA output listed? would I need a different edid, or would those on that github repo you mentioned there suffice?