Finger info for flibitijibibo@icculus.org...


D3D11 Support for FNA3D Linux

I just pushed an fnalibs update that builds the Linux version of FNA's graphics library to include the Direct3D 11 renderer! Before you get too excited I have even better news: It doesn't work at all! Not even close!

As far as new announcements go this might sound like the worst one possible. And you may very well be in the right neighborhood. So why are we doing this at all?

For the past couple years we've been working on our own Vulkan renderer in FNA. It's taking a while to finish, but it's not super urgent since our OpenGL renderer is very competitive with both our D3D11 renderer and even XNA's D3D9 renderer nowadays. But while that's been going on, Joshua Ashton has been maintaining a version of dxvk suitable for native applications. You probably know about this because of the numerous Source 1 updates leading up to Steam Deck, or possibly one of the Ys games on Stadia. As far as I know, dxvk-native and the Source 1 updates are being done entirely by Josh independently and completely separate from the entire rest of Valve (contractor life), so particularly under the circumstances his work should be commended.

When the project first came up I decided to try and wire FNA3D to it. I didn't get very far at the time, and FNA3D was still moving very quickly so I needed to focus on getting that out the door. Fast forward 2 years, and thanks to so much being in the waiting room I finally had time to actually explore this properly. Fast forward again a few days and we have FNA3D Linux running on D3D11. Almost.

While we have a proper Vulkan renderer, dxvk-native is still interesting to us, for two reasons:

FNA3D Vulkan is written to target FNA's rendering system. We can be very detailed with things like memory allocation, command submission, and most importantly, hardware compatibility. We target a very low Vulkan spec, only using extensions when necessary. That doesn't mean we refuse to use extensions (for example, we're looking into using KHR_dynamic_rendering when available), but for us as application developers we really want as many people to run on Vulkan as possible, only falling back to D3D and GL when absolutely necessary. This comes at the cost of needing more developer resources to maintain, and also might come at the cost of potential performance improvements if some bleeding-edge extension would be faster, but isn't broadly available yet.

DXVK is the opposite: It has to be a fully-conformant Direct3D implementation for all input data it ever gets, and to achieve this it is very aggressive with hardware support - I haven't checked the logs but I imagine Vulkan 1.3 is a mandatory minimum requirement now. It's not totally unjustified, as the aggressive feature requirements does mean the driver runs really damn well, and Valve has the money to give it all the resources it wants to achieve that goal. However, while Valve can get away with bugs pretty easily (I mean, who's going to get in trouble if some no-name game on slightly older hardware doesn't work, right?), it doesn't work well for small developers with small applications that need to have broad support. But if it does work, that could be cool to have...

So dxvk-native support is in and all is well, right? As far as the runtime goes, yes. But the core runtime isn't the only part that we care about.

The way FNA D3D11 works is by taking in DX9-era effects, which contain DX9-era bytecode (DXBC), and emitting DX10-era HLSL, which then gets compiled to DX10-era DXBC which is completely different from the other DXBC. It's not pretty, but for FNA it works; AAA games might take 15+ minutes to compile all their shaders and pipeline objects, but you may be shocked to discover that the XNA catalog isn't terribly shader-heavy, so surprisingly we can have HLSL compilation in the pipeline and have it go largely unnoticed. This falls apart outside of Windows, because we still don't have an HLSL->DXBC10 compiler! Yes, we have DXC and glslang now, but those go straight to either DXIL or SPIR-V, neither of which we can use. So what can we do?

This is where we're stuck right now. We have two possible routes:

  1. Write a DXBC10 emitter in MojoShader (signing with DxbcSigner if needed)
  2. Write an HLSL->DXBC compiler

The first is the ideal path, but we have almost nothing to work with right now, so it's entirely unstarted. The second path, while not ideal, is still interesting because even if it gets obsoleted by path 1, it still seems like a good idea to have and support Free HLSL compilers, if only for preservation purposes. Problem is, this is not an area with a lot of investors; Valve likely has zero interest in HLSL compilers because they can just use Microsoft's proprietary binaries (though the argument could be made that having your own HLSL compiler would give you even more control of the pipeline, which Valve 100% needs to be able to do stuff like the Elden Ring performance improvements), and I doubt others in the business are clamoring for this either, even though long-term it's something we're probably all going to need some day.

That doesn't mean it's not being worked on, thankfully: The WineD3D team has a new shader system in vkd3d, and it's split up in a way that we can use it in native applications without dragging in all the D3D12 stuff. The result is this thing I totally did not take from one of Zebediah Figura's Wine patches and slap together into a binary that FNA3D can now consume: d3dcompiler-native!

So we have a D3D11 runtime, and we have something that looks like an HLSL compiler. Unfortunately, as you'd expect, the compiler is far from done - it can't even compile the basic SpriteBatch shader yet. So that's pretty much where we're at: Everything works except for shaders but unfortunately this does not have the resources it needs to be production-ready.

So, if you happen to like shaders, D3D, compilers, HLSL, graphics in general, or anything in between, there are a few things that might be of interest to you:

On FNA3D's end we're tracking all of this here. This is a very undersupported component of multiplatform D3D rendering, so if this sounds remotely interesting I would get involved ASAP (especially if this is on the vkd3d side)! For now, the FNA team will remain focused on the native Vulkan renderer instead.

How to Make Deck Verified Cert Good

A much nicer version of this is now available at GamingOnLinux!

dyld Bug!

This has been fixed in macOS 12.3! The original post has been archived.

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/lib/libdecor-0.so.0
ln -s libdecor-0.so.0 /usr/local/lib/libdecor-0.so

# Fake libdecor pkgconfig
cat <<ENDOFFAKELIBDECOR > /usr/lib64/pkgconfig/libdecor-0.pc
prefix=/usr/local
libdir=${prefix}/lib
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
ENDOFFAKELIBDECOR

# PipeWire 0.3.42 (Highest version usable with meson)
# https://gitlab.freedesktop.org/pipewire/pipewire/-/archive/0.3.42/pipewire-0.3.42.tar.bz2
meson setup .. -Dsession-managers= -Dpipewire-v4l2=disabled -Dv4l2=disabled -Draop=disabled
ln -s /usr/local/lib/pkgconfig/libpipewire-0.3.pc /usr/lib64/pkgconfig/libpipewire-0.3.pc
ln -s /usr/local/lib/pkgconfig/libspa-0.2.pc /usr/lib64/pkgconfig/libspa-0.2.pc

# 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
    Fixing a million bullshit Deck cert results instead of the stuff below
    Codename B

Waiting Room
    Super Hexagon "Neo" Rewrite
        - Waiting on Android stuff
    Codename MissedOne
        - Waiting for an RC to come in
    Codename DanishBootleg
        - Port is done, content is not
    flibitEffect
        - Waiting for the client to generate a header for me
    Codename Devolution Assessment
        - Waiting for a source drop
    Proteus "Neo" Rewrite
        - Not actually a thing, I just wish it was
        - Pending some replies
    Coding History
        - On call throughout development
    VVVVVV FAudio
        - Got pushed back by other things, abstraction is done
    VVVVVV 2.4
        - Giving the localization project as much time as it wants
    SDL_ActionSet
        - Needs a pretty big grant
    ScoreRush PC
        - Need AppAdmin for publish, crosshair for mouse
    Anodyne 1
        - Retirement project


When this .plan was written: 2022-03-17 15:12:49
.plan archives for this user are here (RSS here).
Powered by IcculusFinger v2.1.27
You could be playing Pringles for Genesis but instead you're here?