Skip to content

Linux vulkan - #1

Open
TheForgotten69 wants to merge 35 commits into
mainfrom
linux-vulkan
Open

TheForgotten69 wants to merge 35 commits into
mainfrom
linux-vulkan

Conversation

@TheForgotten69

Copy link
Copy Markdown
Owner

No description provided.

@TheForgotten69 TheForgotten69 self-assigned this Sep 2, 2026
@TheForgotten69
TheForgotten69 force-pushed the linux-vulkan branch 2 times, most recently from f180044 to 7baf407 Compare September 2, 2026 12:53
feat: add Vulkan depth access on Linux
Reuse the existing ReShade add-on sources on Linux with a small compatibility layer, writable XDG storage paths, and guarded descriptor tracking. Keep Windows code paths unchanged while building the supported native Linux Vulkan add-ons.
Reworked input on different backend
… builds

fc8ce90 added an unguarded IUnknown::Release on the backup-creation
failure path, which breaks the Linux host build. The branch only runs
for D3D devices, so guard it like the neighbouring AddRef/Release.
Configurations used to be keyed on a hash of the executable path, so
every Proton game shared the Wine loader's configuration and emulators
got one per AppImage build.

Resolve a profile name instead: Steam install directory and app ID
(taken from the executable path for native games when Steam does not
provide it), the Wine guest executable and prefix, emulator content
passed on the command line, or RESHADE_PROFILE when set. Each profile
gets its own configuration and preset under
XDG_DATA_HOME/reshade/configurations. Wine helper processes share the
game's profile but write separate logs.

A ReShade.ini next to a native executable is still used in place, and
differently cased file names are accepted like on Windows. New
configurations are written to a temporary file and linked into place,
so Proton processes starting together cannot overwrite each other.
Also create the effect cache directory up front, otherwise the runtime
saves a temporary fallback path.
* linux: show license texts and enable folder, sound and post-save options

The About tab was empty on Linux because only the ImGui shaders were
embedded as data resources. Embed every resource the Linux build uses
from one list, and leave out the licenses of MinHook, OpenVR and OpenXR
which are not part of it. Also keep the line breaks in the hard-coded
license texts, which were joined by the line continuations.

The folder buttons, screenshot sound and post-save command settings were
hidden, although the Linux implementations exist. Show them again and
play the screenshot sound with pw-play, paplay or aplay.

* linux: let the Wayland compositor draw the cursor over the overlay

Over overlay windows the capture layer hid the compositor cursor and
ImGui drew one instead, which only moves once per rendered frame. Use
the cursor shape protocol where the compositor supports it, so the
cursor moves at the display's rate and follows ImGui's cursor type
(text, resize, hand). Without the protocol, or while the application
has locked the pointer, the overlay still draws the cursor.

* linux: use themed cursors over the overlay on X11

Like on Wayland, the X11 capture layer hid the cursor and ImGui drew
one that only moves once per rendered frame. Give the capture window a
cursor from the user's theme instead (loaded with xcb-cursor), matching
ImGui's cursor type. Under Wine's Wayland driver the capture layer is
not visible, so the overlay still draws the cursor there.
Text input translated each key on its own, so dead keys typed nothing
and the following key typed its plain character (no "ê" from "^" and
"e" on AZERTY). Run key presses through the locale's XKB compose table
on both Wayland and X11, like GTK and Qt do. On X11 the shifted keysym
is kept as well, so shifted dead keys compose too.
Build the host, the example add-ons and the portability tests on
Ubuntu 24.04 for pushes and pull requests to linux-vulkan, and attach
the packaged archive to the run. Pushing a vX.Y.Z-beta.N tag also
publishes it as a pre-release, using the annotated tag's message as the
release notes. package.sh assembles the archive in the same layout as
the previous betas, taking the add-on list from install.sh.

Ignore suffixed tags when deriving the version, so that beta tags no
longer break the build without -DRESHADE_VERSION.
The generated Vulkan header includes X11/Xlib.h for the Xlib surface type.
libstdc++ before GCC 14 does not declare the float variants of the math
functions in namespace std.
Same libstdc++ limitation as the previous commit.
* vulkan: import host memory as buffers with resource_flags::shared_host

Enables VK_EXT_external_memory_host when available so add-ons can share
frames with another process through mapped memory, the only transport a
Wine/Proton process can use with a native one.

* vulkan: allow copies into swap chain images

Adds VK_IMAGE_USAGE_TRANSFER_DST_BIT alongside the usage ReShade already
requests, so add-ons can copy results back into the back buffer.

* vulkan: load vkGetMemoryHostPointerPropertiesEXT through the device

The glad loader sends names containing "Properties" to vkGetInstanceProcAddr,
which returned a function that crashed vkCreateDevice for this device-level
entry point. Exclude it like the "Handle" functions.

* linux: look up add-on modules with _dl_find_object

find_addon runs for every add-on callback of every event, and dladdr1
takes the loader lock each time. _dl_find_object is lock-free.
Needs glibc 2.35.

* depth: let unknown compare ops abstain in reversed depth detection

Draws that test with always/equal or have unresolved dynamic depth state
set the unknown bit, and the exact match then discarded every vote. UI and
sky draws made detection fail in most games. Unknown evidence now abstains;
contradicting evidence still blocks the vote.

* depth: keep the shader resource view when the backup texture is reused

fc8ce90 clears the selected view when the previous depth-stencil is
untracked, but the following check skips creating a view if the revived
backup texture is unchanged. A game that alternates between two depth
buffers (RPCS3) ended every second frame without a view and rebound the
effects on every frame. Carry the previous view over in that case.
* Linux Vulkan: add-on device interop and present flushes that wait for the back buffer

- ReShadeVulkanRequestDeviceExtension (include/reshade_vulkan_interop.h): add-ons
  ask, from AddonInit, for device extensions that ReShade enables at
  vkCreateDevice when supported. "VK_KHR_buffer_device_address" also enables the
  feature, editing the game's own feature structure when it has one.
- ReShadeVulkanGetDeviceInterop: the instance, physical device, the next layer's
  vkGet*ProcAddr, the API version and what was enabled, for add-ons that drive
  the game's device natively.
- During the present event, the first flush of the immediate command list waits
  on the present's semaphores, so add-ons can flush and wait for the back buffer
  (ReShadePresentEventFlushWaits).

* Linux Vulkan: queues for add-ons, optical flow, timeline semaphores everywhere

- ReShadeVulkanRequestQueue(flags): add-ons ask, from AddonInit, for a queue of
  their own with the given capabilities. ReShade adds it at vkCreateDevice in
  the family with the fewest other capabilities that has room, after the
  game's queues, and reports it in ReShadeVulkanDeviceInterop::queues together
  with the device's queue families (for concurrent sharing).
- Requesting VK_NV_optical_flow also enables its opticalFlow feature, when
  supported (the bundled headers predate the extension: its constants are
  defined locally).
- Timeline semaphores are enabled on every Vulkan 1.2+ device, not only when the
  game passes VkPhysicalDeviceVulkan12Features: create_fence failed on devices
  such as Dolphin's.

* Linux Vulkan: hooks for what DXVK calls, and hiding device extensions for add-ons

- vkCmdSetViewportWithCount reaches bind_viewports, and viewports bound by
  add-ons use the same call as the application
- vkCmdBindDescriptorSets2 and vkCmdPushDescriptorSet2 reach the descriptor
  events (loaded by hand before Vulkan 1.4, where they are VK_KHR_maintenance6)
- ReShadeVulkanHideDeviceExtension: an add-on can hide a device extension from
  the application, e.g. VK_EXT_descriptor_heap, so that it binds through calls
  the add-on can follow

* Linux: load add-ons from an 'addon' folder too

An add-on can live there together with the files it needs, apart from
ReShade's configuration and logs.

* Linux Vulkan: let an add-on interrupt the application's dynamic rendering

ReShadeVulkanInterruptRendering ends the rendering a command buffer is in and
returns what it was begun with; ReShadeVulkanResumeRendering begins it again
with the attachments loaded. For add-ons that record copies or compute work at
a point of the application's frame (for example between its 3D scene and its
HUD). Rendering with extension structures is refused, except the attachment
flags of VK_KHR_maintenance10, which DXVK chains and which are kept.

* Linux Vulkan: tell add-ons where the application has a buffer mapped

ReShadeVulkanGetMappedBuffer returns the address of a buffer's first byte
while the application has its memory mapped (vkMapMemory and vkMapMemory2 are
followed), for add-ons that read what the application writes to its buffers,
such as the constants of a draw.

* Vulkan: report vkCmdSetStencilTestEnable and vkCmdSetStencilOp to add-ons

As bind_pipeline_states events (stencil_enable; the faces' operations and
comparison), like the stencil masks and reference already are: an add-on that
changes the stencil test for some draws can put the application's back.

* Linux Vulkan: let an add-on draw in the application's command buffer and put its state back

- ReShadeVulkanRestoreState: the graphics pipeline, descriptor sets, vertex
  buffers and dynamic state the application last set on a command buffer are
  followed (viewports and scissors with count, depth bias, culling, front face,
  depth bounds, depth and stencil tests) and set again on request.
- ReShadeVulkanObserveGraphicsPipelines: an add-on is shown each graphics
  pipeline with the create info it was made from, to build pipelines of its
  own like the application's.
- ReShadeVulkanGetShaderModuleCode: the SPIR-V of a shader module.

* Comments removed from the lines this branch adds over upstream

* Vulkan: a swapchain's images are asked for once, at its creation; an object's private data is a short list, not a hash map

Below the Steam overlay's layer, every vkGetSwapchainImagesKHR opens a handle to the GPU device that is never closed, and the driver's answer slows with each one; add-ons asking for the back buffer every present paid for it. The private data of a command buffer is looked up by add-ons on every draw.

* Generic Depth: the depth buffer is copied only while an enabled technique samples it; the per-second reversed-depth log lines are gone

With 44 effects loaded and one sharpening technique enabled, a 4K frame went from 1.29 to 0.78 ms in the test game: a disabled effect declaring a depth texture no longer costs a full-size copy every frame. The runtime answers whether any enabled technique binds a texture of a given semantic.
…rmat-list patches (#14)

- Check add-on format/color space overrides against the surface formats and
  revert to the application's values when unsupported (e.g. scRGB on X11).
- Refuse format overrides the sRGB proxy blit cannot feed (no sRGB/linear pair).
- Clear MUTABLE_FORMAT only when the view format list is dropped, so overrides
  to the sRGB sibling stay valid (VUID-VkSwapchainCreateInfoKHR-pNext-04099).
- Transition proxy present targets from UNDEFINED: the full-extent blit
  overwrites them, and on the first frame they were never presented.
- Restore the application's VkImageFormatListCreateInfo on return instead of
  leaving it pointing at a freed local vector with a modified count.
- Add pure helpers in vulkan_swapchain_override.hpp with unit tests.
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.

1 participant