FNA's GPU API for SDL3: Now in Alpha!
After many months of crunching, the FNA team is happy to announce our proposal for the SDL GPU API, which is now available in Alpha today! You can find the current revision of the GPU API here.
This is a project being developed in parallel to Ryan's work on the GPU API; while Ryan has been focused more on the shader tooling, we decided that we would take our experience working on FNA3D and Refresh to develop a runtime that said shader tooling could actually run on. That said, while Ryan did get his own runtime started on Metal, we ended up starting from scratch using Refresh as the foundation; the result is a whole new implementation that largely matches Ryan's overall design that should work with just about any shader content pipeline old and new, and to prove it we've been running FNA games with it the whole time:
Using FNA3D's replay tool we've been able to do constant testing with commercial-grade workloads, with MojoShader as an existing shader workflow. And of course, we've also been writing new examples from scratch that make use of modern shader tools, you can find those here. Here's one we recently finished: A SpriteBatch done entirely in compute shaders!
Now, on to the gritty details!
When we say "Alpha", we mean "this works and while we expect to make one or two changes, this should be pretty close to the final thing." The features are all there and are fully implemented for Vulkan (PC/Switch), Metal (macOS/iOS/tvOS), and D3D11 (Windows/DXVK, using deferred contexts), but we still need to write the D3D12 renderer (Windows/Xbox) and port over Refresh's PlayStation 5 renderer. Once we have all possible renderers in place then we'll be in Beta, at which point we only expect to make changes based on what Ryan/Sam might ask for to make an SDL_Render backend possible. We will likely do the PS5 work ourselves, but we're actively seeking a developer with D3D12 experience that is interested in writing an SDL_GPU backend in C. This is of course paid work, so if you'd like to work on this please get in touch!
Interestingly enough the shader support is actually what's closest to complete: Our take on SDL_GPU's shader support is that we get out of the way as much as possible, therefore the API exposes the ability to push native shader formats directly to the device (so Vulkan takes SPIR-V, Metal takes MSL/MetalLib, etc). That said, we also wanted to experiment with supporting standard cross-compilation tools, and since SPIRV-Cross has a frozen C ABI, there's also support for dynamically loading SPIRV-Cross-C as a shared library; whenever this is available and SPIR-V is passed, we translate to the native shader format and pass the result to the GPU backend at runtime. This is actually what we've been using for MojoShader up to this point; we use the MojoShader SPIR-V emitter as a source of truth for all GPU backends both to ensure consistency and to dogfood the idea of using a cross-compiler at runtime, and then for the example code we built an example of offline shader tooling that allows for better load times (and support for precompiled shaders on consoles where runtime compilation is not available).
For the most part we exposed everything we could reasonably expose: We've got compute shaders in addition to vertex/fragment, shader storage resources, multi-draw indirect rendering, first-class support for rendering to multiple windows, and we're even planning to support HDR as a first-class feature (just about the only thing that hasn't been done is exposing a function to send HDR mastering metadata, and that's my fault!). The only hardware feature we ended up dropping was support for hardware occlusion queries; it's possible but everybody decided to reimplement them in their own funky way (long gone are the days of just calling Begin/End), and unfortunately even with FNA's catalog we have virtually no real-world examples of occlusion queries in use, so we've taken it out for now. If you do use this feature, please get in touch and don't hesitate to wedge in a minimal implementation yourself, we'll do our best to review it!
This has been in the works for a very long time, and while we've been super hard at work on this for just about the entire year, we've unfortunately gotten no real reviews on this, so if you were looking forward to this API, please please do not wait to review this as there is very little time between now and the SDL 3.0 freeze, we are currently expecting not to make the cut but your feedback could help turn this around, or at the least make it a high priority for SDL 3.4.
Give it a try and let us know what you think!
How the FNA Project Works
This post has been archived.
flibitBuild
Want to replicate my build machine? Grab a RHEL8-based OS and have a look!
"RHEL-based" OSes include RHEL for Developers, Rocky Linux, and AlmaLinux.
Your OS minimum will be "glibc 2.28+, 64-bit only".
# Update base install before doing anything else
dnf update
# Add EPEL
dnf install epel-release
crb enable
# SDL2 dependencies
dnf builddep SDL2
# All the base build tools!
dnf install bzip2 bzip2-devel chrpath clang cmake freetype-devel gcc-c++ \
git gtk3-devel libstdc++-static libuuid-devel libvorbis-devel \
libxml2-devel meson ninja-build ocl-icd-devel openal-soft-devel \
opencl-headers openssl-devel patch perl-IPC-Cmd svn unix2dos zlib-static
# MinGW toolchain, not available on aarch64
dnf install mingw32-gcc-c++ mingw64-gcc-c++
# libdecor
curl -O https://gitlab.freedesktop.org/libdecor/libdecor/-/archive/0.2.1/libdecor-0.2.1.tar.bz2
tar xvfj libdecor-0.2.1.tar.bz2
mkdir libdecor-0.2.1/flibitBuild
cd libdecor-0.2.1/flibitBuild
meson .. --libdir=lib -Ddemo=false
ninja
su -c 'ninja install'
# PipeWire 0.3.42 (Highest version usable with meson)
curl -O https://gitlab.freedesktop.org/pipewire/pipewire/-/archive/0.3.42/pipewire-0.3.42.tar.bz2
tar xvfj pipewire-0.3.42.tar.bz2
mkdir pipewire-0.3.42/flibitBuild
cd pipewire-0.3.42/flibitBuild
meson setup .. --libdir=lib -Dsession-managers= -Dpipewire-v4l2=disabled -Dv4l2=disabled -Draop=disabled
ninja
su -c 'ninja install'
# Also:
# Configure SDL with PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure
# The CMake config provided by SDL2-mingw is terrible, delete the block
# that starts with "if(NOT TARGET SDL2::SDL2)".
flibitBuild AArch64
This VM works fine on the latest Fedora. The OS installation process is the same as above, except it will be text-based rather than graphical.
# On Fedora...
dnf install qemu-system-aarch64
dnf group install --with-optional virtualization
virt-install --name rocky8_aarch64 --os-variant rhel8.10 --arch aarch64 \
--vcpus 8 --ram 3072 \
--disk path=/home/flibitijibibo/Programming/aarch64/rocky8-aarch64.img,format=raw,size=32 \
--cdrom ~/Downloads/Rocky-8.10-aarch64-minimal.iso
Unity Linux Editor Fix
I keep forgetting to write this down, so I'm putting it here:
./202x.x.x/Editor/Data/Tools/Roslyn/csc.runtimeconfig.json
./202x.x.x/Editor/Data/Tools/Roslyn/VBCSCompiler.runtimeconfig.json
# After System.GC.Server, add "System.Globalization.Invariant": true
Wait, a "plan"?
Well, this is a .plan file, so here's my TODO. Expect nothing from it, ever.
In Progress
Codename a l'Orange
Closure AMD apitrace
TBP load frame refresh
Waiting Room
SDL_ActionSet
- After 3.0 :(
Codename Edible Launch
- Technically out but not announced
Coding History
- On call throughout development
Anodyne FNA Console
- Waiting on a handful of external things
VVVVVV 2.5
- Mostly staying hands-off again