Skip to content

fix(linux): auto-detect GPU with connected display for VAAPI and Vulkan#4961

Merged
ReenigneArcher merged 4 commits intoLizardByte:masterfrom
neatnoise:vulkan-default-gpu
Apr 17, 2026
Merged

fix(linux): auto-detect GPU with connected display for VAAPI and Vulkan#4961
ReenigneArcher merged 4 commits intoLizardByte:masterfrom
neatnoise:vulkan-default-gpu

Conversation

@neatnoise
Copy link
Copy Markdown
Contributor

@neatnoise neatnoise commented Apr 8, 2026

Description

On multi-GPU Linux systems, both VAAPI and Vulkan encoders hardcoded /dev/dri/renderD128 (or passed nullptr for FFmpeg auto-detect) as the default render device when adapter_name was not configured. This caused the encoder to use the wrong GPU (e.g. Intel iGPU instead of the Nvidia dGPU driving the display), leading to encode failures or unnecessary cross-GPU copies.

This PR introduces platf::resolve_render_device() which centralizes render device resolution:

  1. User's adapter_name config → used as-is
  2. Auto-detected GPU with connected display (via DRM connector scanning)
  3. /dev/dri/renderD128 if detection fails

The DRM detection logic (find_render_node_with_display()) scans card devices for a connector in DRM_MODE_CONNECTED state and returns the corresponding render node via drmGetRenderDeviceNameFromFd(). This is kept internal to linux/misc.cpp.

All Linux encoder paths now use platf::resolve_render_device() consistently:

  • video.cpp — VAAPI and Vulkan hardware input buffer init
  • vaapi.cpp — encode device creation and error reporting
  • vulkan_encode.cpp — Vulkan hardware device creation

Previously the adapter_name → render_device resolution logic was duplicated across these files. Now it lives in one place, avoiding potential mismatches.

Screenshot

Issues Fixed or Closed

Roadmap Issues

Type of Change

  • feat: New feature (non-breaking change which adds functionality)
  • fix: Bug fix (non-breaking change which fixes an issue)
  • docs: Documentation only changes
  • style: Changes that do not affect the meaning of the code (white-space, formatting, missing semicolons, etc.)
  • refactor: Code change that neither fixes a bug nor adds a feature
  • perf: Code change that improves performance
  • test: Adding missing tests or correcting existing tests
  • build: Changes that affect the build system or external dependencies
  • ci: Changes to CI configuration files and scripts
  • chore: Other changes that don't modify src or test files
  • revert: Reverts a previous commit
  • BREAKING CHANGE: Introduces a breaking change (can be combined with any type above)

Checklist

  • Code follows the style guidelines of this project
  • Code has been self-reviewed
  • Code has been commented, particularly in hard-to-understand areas
  • Code docstring/documentation-blocks for new or existing methods/components have been added or updated
  • Unit tests have been added or updated for any new or modified functionality

AI Usage

  • None: No AI tools were used in creating this PR
  • Light: AI provided minor assistance (formatting, simple suggestions)
  • Moderate: AI helped with code generation or debugging specific parts
  • Heavy: AI generated most or all of the code changes

@neatnoise neatnoise changed the title fix(linux/vulkan): auto-detect GPU with connected display for Vulkan encoder fix(linux): auto-detect GPU with connected display for Vulkan encoder Apr 8, 2026
@ReenigneArcher ReenigneArcher changed the title fix(linux): auto-detect GPU with connected display for Vulkan encoder fix(linux/vulkan): auto-detect GPU with connected display Apr 8, 2026
@ReenigneArcher ReenigneArcher added this to the vulkan milestone Apr 8, 2026
@neatnoise neatnoise force-pushed the vulkan-default-gpu branch 2 times, most recently from a0b3617 to 1e54ff0 Compare April 8, 2026 15:10
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 8, 2026

Bundle Report

Bundle size has no change ✅

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 8, 2026

Codecov Report

❌ Patch coverage is 38.77551% with 30 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (master@b319485). Learn more about missing BASE report.
⚠️ Report is 1 commits behind head on master.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/platform/linux/misc.cpp 48.64% 14 Missing and 5 partials ⚠️
src/video.cpp 0.00% 2 Missing and 2 partials ⚠️
src/platform/linux/vaapi.cpp 33.33% 1 Missing and 1 partial ⚠️
src/platform/macos/misc.mm 0.00% 2 Missing ⚠️
src/platform/windows/misc.cpp 0.00% 2 Missing ⚠️
src/platform/linux/vulkan_encode.cpp 0.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##             master    #4961   +/-   ##
=========================================
  Coverage          ?   18.03%           
=========================================
  Files             ?      108           
  Lines             ?    23464           
  Branches          ?    10363           
=========================================
  Hits              ?     4232           
  Misses            ?    15095           
  Partials          ?     4137           
Flag Coverage Δ
Archlinux 11.62% <16.66%> (?)
FreeBSD-14.3-amd64 13.62% <37.50%> (?)
Homebrew-ubuntu-22.04 14.01% <38.63%> (?)
Linux-AppImage 12.29% <38.63%> (?)
Windows-AMD64 14.90% <0.00%> (?)
Windows-ARM64 13.21% <0.00%> (?)
macOS-arm64 19.02% <0.00%> (?)
macOS-x86_64 18.37% <0.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/platform/common.h 32.40% <ø> (ø)
src/platform/linux/vulkan_encode.cpp 0.34% <0.00%> (ø)
src/platform/linux/vaapi.cpp 2.84% <33.33%> (ø)
src/platform/macos/misc.mm 9.00% <0.00%> (ø)
src/platform/windows/misc.cpp 16.40% <0.00%> (ø)
src/video.cpp 32.35% <0.00%> (ø)
src/platform/linux/misc.cpp 17.63% <48.64%> (ø)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b319485...d56679d. Read the comment docs.

@Clutchnp
Copy link
Copy Markdown
Contributor

instead of using render_device would you be open to using adapter_name itself so we can pass that around and avoid mismatches by running the same logic again and again, @ReenigneArcher @neatnoise

@neatnoise neatnoise changed the title fix(linux/vulkan): auto-detect GPU with connected display fix(linux): auto-detect GPU with connected display for VAAPI and Vulkan Apr 16, 2026
@neatnoise
Copy link
Copy Markdown
Contributor Author

neatnoise commented Apr 16, 2026

instead of using render_device would you be open to using adapter_name itself so we can pass that around and avoid mismatches by running the same logic again and again, @ReenigneArcher @neatnoise

Good point! Done — added platf::resolve_render_device() that resolves it once (user config -> auto-detect -> /dev/dri/renderD128 fallback). All call sites now use it. Went with render_device as the common concept since that's what both VAAPI and the config (adapter_name on Linux is a render device path) naturally work with. Vulkan just has an extra step to map it to a device index. I also changed the description by adding support for VAAPI too.

@neatnoise
Copy link
Copy Markdown
Contributor Author

False sonarqubecloud notification. There isn't sopen for linux

Comment thread src/platform/linux/vaapi.cpp Outdated
neatnoise and others added 4 commits April 17, 2026 13:18
…renderD128

On multi-GPU systems the Vulkan encoder defaulted to /dev/dri/renderD128
which may not be the GPU driving the display. This caused encode failures
or unnecessary cross-GPU copies.

Add platf::find_render_node_with_display() which scans DRM connectors to
find the GPU with a connected monitor and returns its render node path.
Use this as the default when adapter_name is not configured.

Fallback chain: user config > auto-detected GPU > renderD128 > FFmpeg default.
…nder_device()

Replace duplicated adapter_name → render_device resolution logic across
video.cpp, vaapi.cpp, and vulkan_encode.cpp with a single
platf::resolve_render_device() function.

The resolution order is:
1. config::video.adapter_name if set by user
2. Auto-detected GPU with connected display (find_render_node_with_display)
3. /dev/dri/renderD128 fallback

find_render_node_with_display() is now internal to linux/misc.cpp,
removed from the public platf:: API and platform stubs.
@sonarqubecloud
Copy link
Copy Markdown

@ReenigneArcher ReenigneArcher merged commit 3210078 into LizardByte:master Apr 17, 2026
70 of 71 checks passed
Clutchnp pushed a commit to Clutchnp/Sunshine that referenced this pull request Apr 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Black screen when forcing Vulkan encoder – appears to select iGPU instead of Nvidia GPU

3 participants