SDL 2.0.16
A new SDL release is about to be tagged, meaning new fixes and features will be available to stable users. This cycle was particularly busy for me as I ended up implementing a whole new feature to the audio subsystem (at last, you can now query device formats before creating the device, 5.1 users rejoice!) as well as borderline rewriting the Wayland video subsystem.
Wayland support is the really big change (as many of you may remember) and so it's probably worth getting into where that's at and what's left before we can put X11 behind us once and for all.
Up until 2.0.16 Wayland support was, at the absolute most, experimental. It had a lot of missing features and the features that were present just hadn't been given the gruesome rounds of testing that every major change needs, so it was mostly something you tried just to see what native Wayland might be like. Because it's now far more urgent to support it properly, a bunch of work went into this release and it's now much more accurate to say that it's in an Alpha state. This might be sort of disappointing for those who were expecting it to be done-done, but I always laid stages out like this (at least for my projects):
- Experimental: Basically doesn't work and if it does it's coincidental
- Alpha: Should work in 90% of cases, won't work on the other 90% of cases
- Beta: Every feature is there, just needs a lot of testing
- RC1: It's done, everything's been checked, last call for emergency reports
So in my mind, Alpha's where it's at now. If you're on a system with server-side decorations, or you have a very very new version of GNOME (we're talking "latest from Git" new), odds are the experience will be pretty good. Client-side decorations still need a lot of testing, and as it turns out if you're on a stable release of GNOME they don't even work correctly anyway, since we ended up finding a big hole in Mutter which has a fix that will be shipping next week. Similarly, while we're feeling pretty good about the SDL side of things, testing the catalog showed that we will need a few things from the OS beyond SDL's control:
1. When you run OpenGL applications with Wayland, there's an extremely good chance that you're going to see a bunch of weird smearing and possibly whatever is behind the window. This is because developers, myself included, used a backbuffer format with an alpha channel, and wouldn't you know it, Wayland treats it as transparency. I know! The audacity of a compositor to treat alpha as transparent!
This is being investigated by Mesa developers in collaboration with NVIDIA, the likely path forward is a new EGL extension that informs the implementation that we want our alpha to be composited as opaque. A prototype already exists, but as you might expect there's a lot of red tape and QA involved with new features, so it won't be out tomorrow. I do expect that there will be something in time for 2.0.18 though, since it's not a huge feature or anything. Really we just need the formal extension in the registry, the drivers can use it afterward.
2. When you run Vulkan applications on NVIDIA, it will crash right away. Turns out something in the NVIDIA driver really doesn't like VkSurfaceKHR objects that are anything but X11 surfaces. Typically you would just not advertise the Wayland extension and then return VK_FALSE for vkGetPhysicalDeviceSurfaceSupportKHR, but even checking for the support crashes completely. We can't check it at instance creation time because other drivers including lavapipe do support Wayland surfaces, and unfortunately Vulkan instances don't differentiate driver-specific support at that level, so you have to query at the device level instead.
This has been reported to NVIDIA but has not been fixed yet, the recent beta driver does not fix it either as far as I know.
UPDATE (August 10): Driver 470.63.01 adds KHR_wayland_surface support!
3. In rare cases the program will hang indefinitely while waiting for Wayland events. Okay, so you're probably wondering where I'll start complaining about Wayland being busted by design or whatever. Truth is, some of Wayland while not easy to support at least makes some sense. Not having mousewarp is fine now that we have relative pointer support, which was always what we actually wanted; literally nobody in their right mind likes having their cursor arbitrarily taken away, or likes having windows steal focus and grab your input totally unprompted. That stuff always sucked, and the Wayland protocols group should be applauded for rejecting bad ideas and digging into what the legitimate uses for old features were instead.
Surface suspension is probably the latest example of this kind of contention between developers and the protocols group. As it turns out, when a compositor decides that a window does not need to be rendered, either because it's hidden, minimized, whatever, it will simply block the program's presentation engine completely. So for example, if your window is behind another window, eglSwapBuffers will just never return, ever, until the window is visible again. In theory this makes sense; other operating systems have started getting into the idea of throttling background applications more aggressively to save power, and improving power efficiency is very important and has been neglected for far too long.
Two problems, however:
Stalling presentation is far too aggressive even for Wayland - this is even admitted via Xwayland where they don't stall indefinitely, but rather throttle to 1Hz. There's some contention as to whether or not that's still too much, but it's better than 0Hz in my book. The problem with 0Hz is that if the window is not accessible to the user, the program is officially deadlocked permanently and the user has to break out kill -9, which isn't remotely in the neighborhood of user-friendly. This isn't an uncommon thing: The test case for this problem on my end was Source engine! Source 1 in particular does some swaps before showing the window, and since the window starts hidden, it just blocks on startup and the user never sees the program start, forcing them to kill the process.
Stalling the presentation thread is not the same as stalling the program itself. It'd be one thing if obscured windows were just given less CPU time, that makes complete sense and I think even game developers would admit that they would prefer that background programs should be given less cycles. Problem is, this just blocks one thread. Have you ever paused a typical game and printed all of its threads at once? For a AAA game,
thr app all bt
will have you pressing Enter for weeks. So in the modern age where most things have more threads than lines of code, stalling one thread doesn't solve the energy problem, it just risks breaking apps completely.
Wayland's reputation would have you believe that this would not be considered a bug and that it wouldn't be fixed. While some might make that argument, the general sentiment is that it is a bug, but how it should be fixed is up in the air right now.
Joshua Ashton of DXVK fame and Simon Ser of wlroots/sway/gamescope fame proposed a simple event, which is fired when the window is suspended and resumed. This pretty much acts like a mobile OS' backgrounded event, or like a generic low-power event, and this is what makes the most sense to me since applications are already used to the idea of low-power modes (again, particularly on mobile platforms including Nintendo Switch), so we may as well capitalize on prior art. This hasn't been agreed on yet, however, and it's still in the evaluation period. Like EGL transparency I do expect this to be solved, but this one will probably take longer. Should suspension events be approved, we'll be ready on day one since we have implementations for Vulkan WSI, EGL, SDL, and even wlroots, so it would hit the ground running for sure. We'll see what happens though.
In the meantime we have a bunch of weird, hacky things in our SwapWindow implementation to try and avoid this, but that's for OpenGL only - Vulkan presentation is totally out of our hands, so odds are most of your hangs will be for Vulkan applications. We were also looking at ways to support timeouts in presentation, which Vulkan already supports but EGL does not. This might get put aside though, since I was basically the only person asking for it and suspension may throw that out anyway.
Aside from the Big Three Blockers, I'm pretty comfortable in saying that SDL Wayland feels more like an upcoming feature rather than just something you can try for fun. I was hoping 2.0.18 would be the one that moved to Wayland by default, but in all likelihood it'll need at least one more cycle because so much of what makes it work has to do with the ecosystem beyond just SDL itself. Additionally, and more importantly, this is work that will probably be done without me involved much, if at all.
This was the last release that I could really focus on, because at this point the work involved goes way over the budget I have; even the crunch leading up to 2.0.16 basically went completely unpaid. Because Steam Deck's advertising and developer documentation really did put two bullets in the back of the head of my business, and nothing has come in to fill that gap, I'm working almost exclusively on GitHub Sponsors, which doesn't cover the expenses. The truth is, GitHub Sponsors shouldn't be a substitute for what I was doing before; the people who put the money in the program just wanted to help out, they don't want to be given the financial responsibility of a big corporate benefactor nor do they want me to stop working on games because of their sponsorship. It's not fair to my sponsors, nor is it good for the work that I do because the games that I used to work on were the reason my stuff even had a chance to be good in the first place!
If you still want to sponsor me, I do appreciate it, since I can still at least try to help by way of reviewing incoming SDL patches and/or test new features that come in. If you really want to help turn things around though, now's the time to try and fight Valve's narrative and start recommending me to developers for native work again. There are still independent developers that care, but just aren't aware of what they can do yet, and customers' voices are always heard even if they're not always listened to. If I don't have supporters, I don't have a job, and we all just lost our biggest supporter of the last decade.
Whether I remain a programmer or not, however, I do hope you'll give the Wayland driver a try via...
SDL_VIDEODRIVER=wayland SDL_DYNAMIC_API=/path/to/your/SDL/build/.libs/libSDL2-2.0.so.0
... and see what it's like to run games on something other than X11, at long last.
Bill's Hat
Turn a minimal Fedora installation into a SteamOS box!
1. Write Fedora Workstation NetInstall ISO to a USB drive
2. Boot USB image, install Minimal configuration with standard partition layout matching SteamOS'
3. Set root password, create a user called 'steam', set a password for it
4. Reboot, log in as root
5. A whole bunch of commands:
dnf group install hardware-support
dnf install Xorg xorg-x11-drv-evdev libglvnd-egl vulkan-loader.x86_64 vulkan-loader.i686 lightdm flatpak NetworkManager-wifi kernel-modules-extra bluez
dnf config-manager --add-repo=https://negativo17.org/repos/fedora-steam.repo
dnf install steam steamos-compositor steamos-modeswitch-inhibitor.x86_64 steamos-modeswitch-inhibitor.i686
setsebool -P allow_execheap 1
systemctl enable sshd.service
systemctl enable lightdm.service
systemctl set-default graphical.target
6. Edit /etc/lightdm/lightdm.conf:
pam-service=lightdm-autologin
pam-autologin-service=lightdm-autologin
user-session=steamos
autologin-user=steam
autologin-session=steamos
7. Create /var/lib/AccountsService/users/steam:
[User]
Session=steamos
XSession=steamos
Icon=/home/steam/.face
SystemAccount=false
8. Reboot, should work now!
9. Additional steps for NVIDIA users:
dnf config-manager --add-repo=https://negativo17.org/repos/fedora-nvidia.repo
dnf install kernel-devel dkms-nvidia nvidia-driver-libs.x86_64 nvidia-driver-libs.i686
reboot # Should be using the NVIDIA driver now!
flibitBuild
Want to replicate my build machine? Grab CentOS 7 and have a look...
# Update base install before doing anything else
yum update
# Add EPEL
yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
# Add SCL
yum install centos-release-scl
# All the base build tools!
yum install bzip2 bzip2-devel chrpath cmake cmake3 freetype-devel gcc-c++ \
git gtk3-devel hg libcxx-devel libstdc++-static libusbx-devel \
libuuid-devel libvorbis-devel libxml2-devel lzma-sdk-devel meson \
ocl-icd-devel openal-soft-devel opencl-headers openssl-devel patch \
perl-IPC-Cmd svn unix2dos yum-utils yum-plugin-copr zlib-static
# SDL2 dependencies
yum-builddep SDL2
# Coprs for MinGW as well as GCC 10, needed to build Clang/LLVM/osxcross
yum copr enable mlampe/devtoolset-10
yum copr enable alonid/mingw-epel7
yum install devtoolset-10 mingw32-* mingw64-*
# CMake3 by default
alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake 10 \
--slave /usr/local/bin/ctest ctest /usr/bin/ctest \
--slave /usr/local/bin/cpack cpack /usr/bin/cpack \
--slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake \
--family cmake
alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake3 20 \
--slave /usr/local/bin/ctest ctest /usr/bin/ctest3 \
--slave /usr/local/bin/cpack cpack /usr/bin/cpack3 \
--slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake3 \
--family cmake
# Fake libdecor, for building with Wayland client decorations
mkdir /usr/local/include/libdecor-0
curl -o /usr/local/include/libdecor-0/libdecor.h \
https://gitlab.gnome.org/jadahl/libdecor/-/raw/0.1.0/src/libdecor.h
touch /usr/local/lib64/libdecor-0.so.0
ln -s libdecor-0.so.0 /usr/local/lib64/libdecor-0.so
# /usr/lib64/pkgconfig/libdecor-0.pc
prefix=/usr/local
libdir=${prefix}/lib64
includedir=${prefix}/include
Name: libdecor-0
Description: library for Wayland client-side window decors
Version: 0.1.0
Libs: -L${libdir} -ldecor-0
Cflags: -I${includedir}/libdecor-0
# Also:
# Modify unistd.h to change __block to anything but __block
# The CMake config provided by SDL2-mingw is terrible, delete the block
# that starts with "if(NOT TARGET SDL2::SDL2)".
# Be prepared to pass -std=gnu99 manually. A LOT.
# To enter Mac building mode (and to build osxcross itself):
# scl enable devtoolset-10 bash
Wait, a "plan"?
Well, this is a .plan file, so here's my TODO. Expect nothing from it, ever.
In Progress
Codename BugBomb
VVVVVV 2.3
Waiting Room
Jackbox Vulkan/SDL2, Codename HM05, Codename Bison
- All are now in cert, on call for failure reports
Star-Twine
- Builds are up, just keeping em refreshed until the big day
Codename FullCircle Returns
- Waiting on external negotiations
Codename Thermonuclear
- After everything above is done
ScoreRush PC
- Need AppAdmin for publish, crosshair for mouse