Fix an "Invalid texture format 0x25A5A (sRGB: True)" error that occurs when running OCTOPATH TRAVELER 0.
The game may leave texture descriptor heap entries filled with 0x5A. Interpreting such uninitialized entries as valid texture descriptors produces an invalid format and causes texture creation to proceed with garbage descriptor data.
Validate the texture address before decoding the descriptor. Descriptors with a zero or unmapped address are marked as invalid and skipped. The invalid state is cleared when the corresponding texture pool entry is modified, allowing the descriptor to be evaluated again.
Incorrect rendering was observed during loading transitions in Trails in the Sky 1st Chapter. Testing showed that routing the first render target's RT0 BlendEnable transition from disabled to enabled through the normal register write path prevented the issue.
Further investigation found that the normal register write was restoring Shadow RAM behavior that was missing from UpdateBlendEnable.
UpdateBlendEnable uses a fast bulk update path instead of issuing a normal register write for each render target. As a result, it bypasses the Shadow RAM handling provided by DeviceStateWithShadow.WriteWithRedundancyCheck.
A normal register write updates both State and ShadowState in MethodTrack and MethodTrackWithFilter modes. In MethodReplay mode, it ignores the incoming value and restores the value previously stored in ShadowState to State.
UpdateBlendEnable must reproduce the same behavior while retaining its bulk comparison and copy path. In track modes, copy the incoming enable values to shadowState. In replay mode, copy shadowState to the incoming enable span, then let the existing comparison and copy logic update state and mark BlendState dirty when necessary.
The original implementation incorrectly used state for both track and replay handling. This prevented Shadow RAM from correctly recording or replaying BlendEnable values, which could cause rendering state synchronization errors.
Correct the bulk update path to use ShadowState for tracking and replay. This preserves the optimized bulk operation while addressing the underlying issue without requiring an RT0-specific compatibility workaround.
(cherry picked from commit 733bd0951b)
Trails in the Sky 1st uses texture descriptors with different formats and dimensions that map to the same region of guest GPU memory. For example, the game interprets the same underlying data as both an R32Uint 2x1 texture and an R32G32Float 1x1 texture. Both textures have an 8-byte logical payload, but their texel formats and dimensions are different.
Ryubing cannot represent these two descriptors as normally compatible texture views, so it creates separate host texture objects for them. Since these host textures represent the same guest memory, a modification made to one of them should become visible to the other before the other texture is read. However, the existing synchronization mechanism does not fully handle this situation.
The game uses this pattern for its exposure or brightness history. A compute shader first writes the updated exposure data to the R32G32Float 1x1 host texture. A later operation then reads the raw bits of the same data through the R32Uint 2x1 host texture. The original Ryubing implementation did not synchronize the contents of these two separate host textures. As a result, the reading texture received stale zero values, which caused the shader to calculate an incorrectly low exposure value and made the rendered image appear too dark.
TextureGroup already has a guest-memory synchronization mechanism for incompatible overlaps. When _flushIncompatibleOverlaps is enabled, the most recent texture contents are written back to guest memory, after which the other texture reloads the data. However, this mechanism was primarily enabled through IsFormatHostIncompatible, which checks whether an individual texture format can be correctly supported by the host GPU.
In this case, both R32Uint and R32G32Float are individually supported by the host GPU. Therefore, IsFormatHostIncompatible does not enable this synchronization path. The issue is not that either format is unsupported. The issue is that two individually supported aliases, represented by separate host textures, do not maintain coherent contents.
In theory, the latest contents could be flushed to guest memory immediately after every GPU write to a host texture, allowing other textures that map to the same guest memory to reload the updated data. However, doing so could frequently trigger expensive operations such as GPU waits, data readbacks, guest texture layout conversions, and memory-tracking updates. This would be particularly costly for textures that are updated every frame or during every compute dispatch.
For this reason, the fix does not require an immediate flush after every write. Instead, it extends Ryubing's existing TextureDependency and TextureGroupHandle mechanisms. When two fully incompatible textures map to exactly the same guest memory and satisfy a strict set of raw-copy requirements, the program creates a raw-copy dependency between them.
When the source texture is modified, the target texture is only marked as requiring a raw copy. The latest logical raw bytes are copied from the source only when the target texture is actually about to be used. This keeps the contents of the separate host texture aliases coherent while avoiding unnecessary round trips through guest memory.
- Downloads updated gamecontrollerdb.txt file on launch, only updates when a new file is available. This keeps the database updated between SDL releases.
(cherry picked from commit 0657b00622)
- downgrade unicorn to last working version
- update to new cp reg struct system
- remove nonexistent register (used to silently continue)
- fix partial unmap tests
- InitializeSignalHandler() was moved out of the translator (almost 2.5 years ago), but the test code was never updated to manually call the function as it was changed to do in the real cpu context, so the tests just started failing.
- by manually initializing the handler we no longer cause tests to fail.
fixes cursor being at 0 position even when text is present, especially annoying for handheld devices with kde virtual keyboard, which is pretty bad, with no way to move the cursor or delete text backward
This PR is the first in a batch of structural changes to Ryujinx.
**Changes**
- Added `ProcessIdentity` and `ProcessKind` to describe loaded programs by:
- PID, program ID, application ID, program index, display version, process kind
- Stored identity metadata on `ProcessResult`.
- Added PID-based process lookup helpers to `ProcessLoader`.
- Updated HLE services to resolve application metadata through the caller PID instead of `Processes.ActiveApplication`.
- Added PTC/JIT disk cache initialization logging with PID, title ID, display version, selector, and enabled state.
- Added `ClientProcessId` property to ServiceCtx (/src/Ryujinx.HLE/HOS/ServiceCtx.cs) that uses the handle descriptor PId when available, falling back to `Process.Pid`.
- Updated 15 HLE service files to use `context.ClientProcessId` instead of `context.Process.Pid` for client process access, ensuring services correctly identify the calling process even when invoked via IPC with handle descriptors.
These changes make service metadata resolution more explicit and prepare the emulator for other structural changes later on.
This PR fixes several validation errors caused by invalid Vulkan usage. These validation errors often end up invoking Undefined Behavior on the driver side, which can lead to artifacts or crashes which are driver specific and otherwise incredibly hard to track. I don't think it should have any impact on performance, but it would be good to test it with as many games as possible (maybe a bug in a game was fixed?).
Each commit fixes an error. I added to each a description with the validation error that was fixed and a small explanation on what was causing it and how I fixed it.
Co-authored-by: AsperTheDog <guillerman0000@gmail.com>
The previous fix for Tomodachi Life (#91) included the extension to all shaders, independently on if it was needed or not. This PR fixes that by lazily adding the extension only when it is actually needed.
This change should not be noticed by anyone, but it avoids having to modify shaders that do not perform any type of dynamic indexing, which apparently is something some modders care about.
Co-authored-by: AsperTheDog <guillerman0000@gmail.com>
This PR marks ALL texture indexes as nonuniform to fix an issue with the paths in Tomodachi Life: Living the Dream on AMD cards. It should have a negligible impact on performance (and it should not have an impact at all on NVIDIA cards!)
It's caused by what is called 'implicit non-uniform sampler array indexing'. The idea is basically that some GPUs optimize texture lookups from indexed texture arrays, by assuming that you are never going to index different textures within a single workgroup. What this causes is that visual glitch where a subgroup is tasked with rendering a block of the screen, and in the boundaries some cores are indexing the wrong texture.
Co-authored-by: AsperTheDog <guillerman0000@gmail.com>
This PR addresses [this issue](https://github.com/Ryubing/Issues/issues/231) and implements HD Rumble for compatible Nin devices.
## New Features
- Add the option for Gamepads to implement HD Rumble
- Add the HD rumble capability to SDL3Gamepad and SDL3JoyCon when they meet certain requirements
## Description
~~Fixes a fatal CLR crash when `caps` screenshot saving receives an input buffer larger than `0x384000`.~~
~~Resolves a crash in Tomodachi Life: Living the Dream where saving the pictures to the system's album crashes with 0x80131506.~~
Follow up to #18. This PR adjusts the validation and copy behavior to better match real hardware, and adds logging to make invalid screenshot buffer cases easier to diagnose.
Real hardware accepts screenshot buffers with a size greater than or equal to `0x384000`, but only `0x384000` bytes are needed for the 1280x720 RGBA image.
This changes screenshot saving to:
- reject buffers smaller than `0x384000`
- accept buffers equal to or larger than `0x384000`
- copy only the first `0x384000` bytes into the 1280x720 bitmap
## Testing
Tested with a real Switch NRO using `capssuSaveScreenShotEx0`, `capssuSaveScreenShotEx1`, and `capssuSaveScreenShotEx2`.
Observed hardware behavior:
```text
0x384000 => OK
0x384000 - 1 => NullInputBuffer
0x384000 + 1 => OK
0x3C0000 => OK // Tomo life picture size
```
Co-authored-by: yell0wsuit <5692900+yell0wsuit@users.noreply.github.com>
- Fixes `StoreData` layout/update handling so `UpdateLatest` returns the stored Mii data correctly.
- Implements `IDatabaseService.Append` (https://switchbrew.org/wiki/Shared_Database_services#IDatabaseService)
Also adds regression tests for `UpdateLatest` and `Append`.
(Might) fix Mario Kart 8 Deluxe crashing on first boot due to failed Mii verification check (due to custom Mii from emulator), and potentially Tomodachi Life: Living the Dream for the "Import Mii from system" option.
Co-authored-by: yell0wsuit <5692900+yell0wsuit@users.noreply.github.com>
When connecting multiple controllers of the same model, the first device's name ends with (0), the second with (1), the third with (1), the fourth with (1), and so on. To ensure these names are truly unique, GetUniqueGamepadName is now called recursively.
Fixed LoadGuestApplication hanging when cancelled.
Since startup procedure has technically changed, we should consider testing this with a variety of game formats to ensure regressions do not occur.
no way this was working before, and if it did, just pure luck, unsafe blind copy of bytes as is and zero checks.
i only tested tomodachi, but should fix all games that were crashing on saving screenshots
the crash was happening because the screenshot buffer was bigger than the bitmap buffer, so marshall.copy() was raising an unhandhled expection crashing the emu.
on top of this, because the data was just copied as is, the result image was garbled.
- Fix: Crash when connecting a JoyCon
- Fix: Make controller GUIDs match old SDL2 GUIDs
- Fix: Detect face button layout for gamepads
Co-authored-by: Maki <77-maki@users.noreply.git.ryujinx.app>
- Services now use their actual names when creating processes instead of the generic "Service".
- Services now use their names encapsulated in curly brackets for threads, e.g. {HID}, instead of the default "HLE.OsThread", making it easier to see what is actually happening behind the scenes. Client threads should use <> and host threads should use {}.
- Fixed a bug where initiating services would create extra unneeded servers.
This is part 1 of a series of service and Horizon changes i'm working on. More will follow at a later date.
* Avalonia to 11.3.13
* Svg.Controls.Avalonia group to 11.3.9.5
* FluentAvalonia to 2.5.0
* DynamicData to 9.4.31
* Gommon to 2.8.1.1
* Humanizer to 3.0.10
* Microsoft.NET.Test.Sdk to 18.3.0
* NUnit to 4.5.1
* NUnit3TestAdapter to 6.2.0
* Rxmxnx.PInvoke.Extensions to 2.9.0
Implement nn::ssl::sf::ISslServiceForSystem -> CreateContextForSystem (100)
Ryujinx implements both ISslService and ISslServiceForSystem in one class so we can just return new ISslContext.
Also fixed the incorrect parameter reading order. (CreateContextForSystem basically has same params as CreateContext)