RHI Switcher
RHI SWITCHER 2.0.0
Unreal Engine 5.7 and 5.8 | Windows Win64
PURPOSE
Let players choose DirectX 11, DirectX 12 or Vulkan in your graphics settings menu. Applying a different API saves a trial preference and restarts the packaged game. The graphics API cannot change inside the running rendering session. The selected API is applied before graphics initialization on subsequent launches.
PROJECT GRAPHICS REQUIREMENTS
Open Project Settings > Platforms > Windows. Configure Default RHI and the Targeted RHIs / targeted shader formats for every API you intend to offer. Package those shader targets with your game. DX11 uses PCD3D_SM5; DX12 supports PCD3D_SM5 or PCD3D_SM6; Vulkan uses SF_VULKAN_SM5 or SF_VULKAN_SM6. The plugin's desktop availability checks cover these SM5/SM6 targets. It does not add missing shaders or driver support to an existing package.
Rendering features differ between APIs and shader models. Test your actual scenes, materials and graphics options on the APIs you expose. Switching to DX11 does not make DX12-only features available there.
CREATE YOUR OWN GRAPHICS MENU
Use your own UMG widget and input system. After gameplay BeginPlay:
1. Call Get Available RHIs once to populate your dropdown. Keep the returned internal values: DX11, DX12, Vulkan.
2. Use Get RHI Display Name for the visible labels.
3. Use Get Current RHI to display the active API.
4. Call Get RHI Switcher Subsystem and check Is Valid. Can Switch RHI tells you whether this game instance can perform a restart.
5. Before applying a different API, save player progress and show your own restart confirmation prompt.
6. Pass the selected internal value to Switch RHI And Restart. A true result means Windows created the replacement process and the current game requested exit. It does not prove that the new process initialized its graphics API successfully.
7. If false, read Get Last Error on the subsystem and show an appropriate message.
Use a Level Blueprint, PlayerController, manager Actor or widget initialized from an existing gameplay world. GameInstance Init occurs before subsystem initialization finishes; obtain this subsystem from a ready gameplay object after BeginPlay.
Restart is deliberately unavailable in editor/PIE, editor-launched standalone sessions, commandlets, dedicated servers and NullRHI runs. Test the restart workflow in a Windows packaged game. Read-only queries can help build your editor UI, but they do not prove a packaged game's shader targets are complete.
SUPPORT AND RECOMMENDATION
Get Available RHIs filters project-targeted desktop shader formats through the corresponding RHI module's support checks. Get RHI Support Reason explains why a requested API is excluded; an empty reason means those checks passed. Hardware/driver checks cannot certify every rendering feature or prevent every driver failure. Validate the packaged game on representative hardware.
Get Recommended RHI prefers the current working API, then the last known good API, then another supported target. It is not a GPU performance benchmark. Avoid repeatedly probing available RHIs from a per-frame widget binding; populate the menu when you open it.
Names are case-insensitive and surrounding whitespace is ignored. D3D11/D3D12 aliases are accepted and normalized to DX11/DX12. Unknown values are rejected. Selecting the already active API returns false without restarting.
TRIAL CONFIRMATION AND RECOVERY
A successful restart request first records the current actual API as the fallback. The replacement process marks the new trial as started before initializing its RHI. It remains pending during the safety interval, normally 30 seconds after gameplay starts. When that interval completes, the active API must match the requested one before it becomes the confirmed preference and last known good API.
For a custom "Keep these graphics settings?" interface, use:
- Is RHI Change Pending: whether a requested trial is awaiting confirmation.
- Get Confirmation Seconds Remaining: time remaining before automatic confirmation; initial normal launches also establish their working API after this interval.
- Confirm Current RHI: confirm a visibly working API immediately. Only call this after your player or your own checks accept the result.
- Get Last Known Good RHI: the fallback that was recorded before the trial.
If the process exits before confirming a started trial, the next normal launch selects the saved fallback before RHI initialization. This includes an early normal close, forced termination, power interruption or crash. The plugin does not identify the underlying cause or restart a dead process by itself. Recovery cannot guarantee that a fallback still works after hardware/driver changes.
Another switch is rejected while a trial is pending. Confirm a working trial first, or close and relaunch before the timer expires to recover the previous API. Once the timer or explicit confirmation commits the trial, later exits do not roll it back.
Get Startup Status exposes a cached state so menus created after startup can inspect the result:
- Ready: normal startup under plugin management.
- Recovered: an interrupted trial or unavailable saved target was replaced by a fallback/project default.
- Override: an explicit launch override cancelled an unconfirmed saved trial.
- Confirmed: the active API has been confirmed and saved in this session.
- Mismatch: the running API differs from the pending trial; confirmation was refused.
- AnotherInstance: another process owns the settings file; this instance cannot restart or write preferences.
- SettingsError: reading or saving startup state failed.
- NotManaged: editor, server, NullRHI or the ignore-saved-preference flag bypassed management.
Bind On RHI Change Detected after BeginPlay if you need notifications. Recovery broadcasts false once gameplay is ready; successful confirmation broadcasts true. Use Get Startup Status when binding late. The event does not certify that a driver crash occurred.
SAVED SETTINGS
Get Config File Path returns the absolute path used by the plugin:
Project Saved/RHISwitcher/Settings.ini
The actual Project Saved location depends on Unreal's packaged-game user-directory settings. Prefer this node over hardcoded installation paths. When the new file is absent, existing settings are read from the old Saved/Config/Windows/RHISwitcher.ini location and saved to the new store. The new location avoids Unreal's generated-config cleanup overwriting or deleting trial state during a restart. The plugin uses a temporary sibling file and atomic replacement; failed writes prevent restart and preserve the prior file where replacement fails.
The settings section is [/Script/RHISwitcher.RHISwitcherSettings]. SafeModeTimeoutSeconds defaults to 30 and is clamped to 1-600 seconds. To change it manually, close the game and edit that value in the saved file. Other fields record PreferredRHI, LastKnownGoodRHI and internal trial state. Do not manually set pending/attempt flags during a running game.
A named process lock prevents two running copies sharing the same settings path from competing over recovery and writes. Another instance can still render using the project's normal launch selection. Separate user-directory profiles have separate preference files and locks.
COMMAND-LINE OVERRIDES AND RESET
Explicit graphics API or feature-level launch options take precedence over the saved preference. A plugin-managed restart removes existing API and feature-level selectors while preserving other arguments, including quoted values. It then lets early startup select the saved trial.
Get Preferred RHI Command Line remains available for custom launchers, but normal launches no longer need a batch file just to restore the saved preference.
-RHISwitcherResetToDefault
Discard saved RHI/trial state and use the project's default graphics selection for this launch. This also resets the safety timeout to 30 seconds. Remove the flag after recovery if you want future saved preferences to apply.
-RHISwitcherIgnoreSavedRHI
Temporarily bypass saved-preference management and writes. Project defaults or explicit engine RHI flags control that session; switching is unavailable in this bypass mode.
For launchers, stores and anti-cheat systems that require their own relaunch handoff, validate the automatic executable relaunch with your integration. The plugin relaunches the current executable; it does not implement a store-specific launch API.
BLUEPRINT NODE REFERENCE
Existing function-library nodes:
Get Current RHI; Get Available RHIs; Get Recommended RHI; Is RHI Supported; Get Last Known Good RHI; Switch RHI And Restart; Get RHI Display Name; Get Preferred RHI Command Line; Is Launched With Correct RHI; Get Config File Path.
New function-library access node:
Get RHI Switcher Subsystem.
Additional subsystem controls:
Can Switch RHI; Get RHI Support Reason; Confirm Current RHI; Is RHI Change Pending; Get Confirmation Seconds Remaining; Get Startup Status; Get Last Error.
TROUBLESHOOTING
Missing dropdown option: inspect Get RHI Support Reason, Windows shader targets and the final package's cooked formats.
Restart returns false: inspect Get Last Error; check packaged context, file permissions, another running instance, current API and pending-trial state.
Preference seems ignored: check explicit launch API/feature-level options and the reset/ignore flags. Get Current RHI reports the actual API; the saved name alone is not proof.
Trial rolls back after a normal close: the process closed before confirmation. Wait for the interval or explicitly confirm a working API.
Game cannot open with a saved preference: try -RHISwitcherResetToDefault or an explicit supported engine API option. The project default must itself work on that hardware.
DEPENDENCIES AND SUPPORT
No additional Unreal plugins are required. Core, CoreUObject, Engine and RHI are bundled engine modules; process and file operations use Windows system APIs. No Blueprint assets or example project are included. Production C++ classes: 4. This is a local graphics-preference system and does not provide network replication.
Fab: https://www.fab.com/listings/4aa0c6c4-e6cb-49ce-ad1d-f4a677ce607c
Support: https://discord.gg/9Zc4wbwqG9