feat(linux): Add Vulkan video encoder#4603
feat(linux): Add Vulkan video encoder#4603ReenigneArcher merged 29 commits intoLizardByte:masterfrom
Conversation
There was a problem hiding this comment.
This is just a preliminary review. On top of the comments below, I think these files will probably need updates.
update dependencies:
- https://github.com/LizardByte/Sunshine/blob/master/scripts/linux_build.sh
- https://github.com/LizardByte/Sunshine/blob/master/packaging/sunshine.rb
- https://github.com/LizardByte/Sunshine/blob/master/packaging/linux/Arch/PKGBUILD
- https://github.com/LizardByte/Sunshine/blob/master/packaging/linux/copr/Sunshine.spec
- https://github.com/LizardByte/Sunshine/blob/master/.github/workflows/ci-freebsd.yml
- and maybe the flatpak
|
I will convert this to draft for now, please change it back when you're ready for a full review. Thanks! |
|
Its ready |
|
I know this PR is about encoding, but I saw changes to capture as well. Do you know if this could support variable framerate capture, similar to how capture works on Windows? In my limited experience Linux always captures at the stream framerate. The ideal capture process would be capturing only when the image has changed (with duplicated frames subject to minimum_fps_target), as well as capturing using a frame interval timer requested by the client or based on the framerate. For example, an Xbox client works best if frames are captured on a timer with an interval of 59.94fps (60000/1001), a desktop client could just use a 60fps interval. One thing you do not want to do is base anything on the host's vsync interval. |
I left a bunch of review comments. |
Yes, the kms_vblank option already behaves this way with variable frame rate similarly to Windows. It encodes that many frames that are generated by a game. It also respects fps frame rate which are set by a client (if the clients sets 60, it won't generate more than 60 fps with some minimal margin) |
|
@ReenigneArcher I made proposed changes. I also added a tiling fix for RNDA 4 when Gnome DE is used. Would be helpful if somebody with Nvidia and Intel GPUs could test the new encoder |
|
@ReenigneArcher I've tested with vulkan ffmpeg build https://github.com/LizardByte/build-deps/actions/runs/21850415771?pr=606 successfully. Tweaked kms_vblank for the game Cronos The New Dawn meanwhile. Tested in many games with various resolutions with and without vsync in-game and kms_vblank enabled and disabled. Tested with vulkan and vaapi encoders. It works solid. |
This comment was marked as off-topic.
This comment was marked as off-topic.
|
This PR needs to be rebased to pick up the right FFmpeg pre-build, before I can run CI. Edit: actually the build-deps commit that added Vulkan hadn't been merged here yet: #4735 |
|
Also, don't forget to verify compatibility with portalgrab when rebasing. This is enough to get started, but you might want to refine/verify: |
|
@XT-Martinez It looks like ffmpeg without built-in vulkan support, you need to build it with ffmpeg vulkan supported binaries (like from link above). @psyke83 will do. I will add vulkan support also for portal grab. Actually I have my portal/pipeware implementation here https://github.com/neatnoise/Sunshine/tree/vulkan%2Bpipewire . So It will be similar. |
The best results on my machine are portal+vulkan (vulkan settings low latency + vbr) and existing portal+vaapi. Portal seems to have a lower latency than KMS. |
|
FWIW I found the vblank option quite interesting. (But I don't have much time right now to actually check it out.) |
|
With the default settings (vbr, ll), the stream is massively violating the target bitrate (70Mbps target is saturating my wifi connection at 250Mbps+). I didn't notice this with prior testing. |
|
This is the issue: Your current PR is assigning VBR as 3 erroneously. When set to 4, I'm not seeing the crazy bitrate overshooting. |
Fixed |
|
|
|
@ReenigneArcher rebased with the current master. It works fine: |
ReenigneArcher
left a comment
There was a problem hiding this comment.
Thank you, I have a review below.
In addition to my review, I have a question. Will there be issues if there is a mismatch in the vulkan header and vulkan loader versions here versus what is used in the build-deps (FFmpeg) repo?
The build-deps repo bundles Vulkan Headers/Loader v1.4.344 (statically linked into FFmpeg), while my Sunshine compiles against the system's v1.4.341 (CachyOS distro). The two |
Sway's GLES2 renderer exports framebuffers in OpenGL's bottom-up convention and signals this via the Y_INVERT flag. The wlroots capture stored this flag but never passed it to the Vulkan encoder, resulting in a mangled picture. Propagate y_invert through img_descriptor_t to the Vulkan compute shader, which now flips the source texture Y coordinate when set.
Force linear GBM buffer allocation to prevent tiling/modifier mismatch when importing DMA-BUF into Vulkan.
… SPIR-V - Move rgb2yuv.comp to src_assets/linux/assets/shaders/vulkan/ - Remove pre-compiled .spv and .spv.h from repo - Add CMake rules to compile .comp -> .spv -> C include at build time - Prefer glslc, fall back to glslangValidator for Ubuntu 22.04 support - Add shader compiler build dependencies for all supported distros
- Use Vulkan headers from build-deps submodule instead of system SDK - Link against system libvulkan.so (loader is version-agnostic) - Guard sys/sysmacros.h for FreeBSD compatibility - Remove redundant glslang-tools from ci-linux.yml - Set RADV_PERFTEST=video_encode for AMD Vulkan video extensions - Add (default) indicators to Vulkan tuning/rc UI labels - Remove leading underscores from cmake variables (cmake-lint)
- Replace find_package(Vulkan COMPONENTS glslc) with find_program() so shader compiler detection works without system Vulkan headers - Move glslc BuildRequires to Fedora-only, add shaderc for OpenSUSE - Add shaderc dependency to Homebrew formula
354c470 to
dac503b
Compare
ReenigneArcher
left a comment
There was a problem hiding this comment.
Thank you @neatnoise! Will merge this soon!
ReenigneArcher
left a comment
There was a problem hiding this comment.
There's a final build issue on openSUSE that wasn't caught yet.
…n on Leap - Move vulkan-loader-devel from common to Fedora-specific section - Add vulkan-devel for openSUSE Tumbleweed - Use libvulkan1 instead of vulkan-loader for openSUSE runtime dep - Disable Vulkan on openSUSE Leap (shaderc/glslang not in official repos) - Skip vulkan/shaderc BuildRequires on Leap via sle_version conditional
|
|
Hi, I tried a test with an RTX 5070 Ti on Bazzite with KDE 6. Here are the logs, in case they're helpful. I didn't create an issue because this isn't typical for a user with an Nvidia GPU, but it might help improve the reliability of the Vulkan encoder. Thanks for your work. |
|
Ah right, while testing I had also noticed that it used the wrong GPU and that I had to specify the correct one in Sunshine's config. (Or was that when I tried portalgrab?) Anyway, if needed I can also test again to confirm. (It might be best to file an actual bug report though.) |
|
I tried this with 2026.403.124357 on cachyOS with an Nvidia GeForce RTX 5090, setting the capture method to KMS and the encoder method to Vulkan, but fails to fully start with the following error: Full log attached. But the way, where would I tweak |
|
@combs-spacier this error comes from FFmpeg library. It seems to be Nvidia driver <-> FFmpeg problem. Do you have the latest Nvidia drivers installed?
|
|
@neatnoise I have the latest Nvidia beta drivers (595) installed, yes. Ah yeah, I’m usually using Portal capture, and am very happy with it, frame pacing really seems great on it. However, it does not support HDR, while KMS does, so I thought I’d give it a try. |
|
Its been running great here after my… ahem initial issues. Thanks everyone, Gaming through sunshine is finally smooth on Linux. ❤️ |
@combs-spacier I was getting the same error on my RTX 4060, and found that adding |


Description
This PR adds Vulkan video encoding support for Linux, providing an alternative to VAAPI encoding.
Changes:
h264_vulkan,hevc_vulkan,av1_vulkan) with zero-copy DMA-BUF import and Vulkan compute RGB-to-YUV conversion — no EGL/GL dependency, all GPU work stays in a single Vulkan queuevulkanencoder options indocs/configuration.mdDependencies:
Requires corresponding PR in LizardByte/build-deps (
ffmpeg-vulkanbranch) to enableBUILD_FFMPEG_VULKANoption, which enables Vulkan encoder support in FFmpeg builds.Testing:
Screenshot
Issues Fixed or Closed
Roadmap Issues
Type of Change
Checklist
AI Usage