Commit Graph
25 Commits
Author SHA1 Message Date
Neo 52c6a1890e Improve "Add raw copy dependencies for incompatible textures"
Initial PR was made by Avan for Ryubing.

This allows for Trails in the Sky 1st Chapter (and by extension Trails through Daybreak, Trails through Daybreak II, Trails Beyond the Horizon, and the future Trails in the Sky 2nd Chapter – tested via demo – to be fully playable.

Initial PR caused issues on macOS devices, specifically crashing in certain games (such as Mario Kart 8 Deluxe and the aforementioned Trails games). It was reverted on the original Ryubing project (at the time of writing this description) for causing small rendering issues on The Legend of Zelda: Breath of the Wild.

The rendering issues do not appear on macOS.

This commit improves the original PR by eliminating said macOS crash.

Trails in the Sky 1st writes its exposure/brightness value through an R32G32Float 1x1 texture and later reads the raw bits back through an R32Uint 2x1 texture mapped to the same guest memory. The two texture formats/dimensions are fully incompatible as texture views, so they end
up as separate host textures, and nothing kept their contents coherent - the reader saw stale zeroed data, making the exposure calculation (and the rendered image) too dark. (This is the initial fix for the game)

TextureGroup already had a raw-copy dependency mechanism intended to
handle this class of alias (TextureDependency, TextureGroupHandle
raw-copy plumbing), gated by CanCreateRawCopyDependency's strict same-guest-memory checks. This commit fixes three bugs that kept that mechanism from working correctly (and thus crashing Trails and other games, such as Mario Kart 8 Deluxe):

(1) TextureGroup.InitializeOverlaps() and TextureGroup.RegisterIncompatibleOverlap() only forwarded overlaps to CreateCopyDependency() when compatibility was LayoutIncompatible or better, silently excluding the fully Incompatible case the raw-copy path exists for. Widened both guards to let Incompatible overlaps through so CanCreateRawCopyDependency actually gets a chance to run.

(2) Once Incompatible overlaps were allowed through, CreateCopyDependency(TextureGroup, ...) could still fall back to a regular, non-raw textureCopy for such pairs, since ViewLayoutCompatible/CopySizeMatches only check byte size and were never meant to reason about fully incompatible pairs (e.g. a depth format aliasing a color format with the same byte size). On Vulkan running through MoltenVK on macOS, that non-raw copy path requires a pixel-format-reinterpreting texture view, and MoltenVK/Metal refuses to create any view onto a depth-format texture ("not castable"), aborting emulation. textureCopy is now forced false for Incompatible pairs, leaving raw copy (which already excludes depth/stencil formats) as the only route for that severity level.

(3) TextureGroupHandle.Inherit() copied a handle's pending DeferredCopy to the new handle when a view was recreated, but did not copy DeferredCopyRaw alongside it. A handle that inherited a pending raw copy would then execute it through the regular (non-raw) CopyTo path once acknowledged, reinterpreting the source bytes with the wrong row layout and corrupting the image - visible as vertical flickering stripes whenever a view happened to be recreated with a raw copy still pending. DeferredCopyRaw is now carried over together with DeferredCopy.

(As mentioned earlier, vertical stripes aren't present on macOS, so (3) doesn't negatively have an effect on macOS in any way).
2026-08-29 10:00:58 -05:00
KeatonTheBot 76a123b81d misc: chore: Use explicit types & fix object creation 2026-05-30 16:26:50 -05:00
gdkchanandKeatonTheBot 812cecd713 Initial texture replacement implementation
Unmerged PR #5632, originally by @gdkchan

* Add mod manager support - @KeatonTheBot

* Remove redundant code - @KeatonTheBot

* Optimize, modernize code to newer C# standards where appropriate - @KeatonTheBot

Co-authored-by: KeatonTheBot <keaton@ryujinx.app>
2025-12-19 17:49:02 -06:00
LotP e3ee28605d Memory changes 3
General memory improvements to decrease GC pressure and frequency.

Pool big arrays and objects that are created and deleted often.

Skip data copies when they aren't needed.

Inline flag checks to skip unneeded allocations.

From my testing the performance is about the same, but the GC frequency is much lower and collection is faster causing less and smaller spikes.
2025-10-30 23:25:51 -05:00
KeatonTheBot fa682d406e misc: chore: Merge into pattern 2025-09-24 13:51:15 -05:00
KeatonTheBot 9c37a557dd misc: chore: Merge duplicated 'if' branches 2025-09-24 13:26:50 -05:00
KeatonTheBot 340ec79e9f misc: chore: Use collection expressions (part 2) 2025-03-10 21:32:01 -05:00
jhorv 73f985d27c Replace passing by IMemoryOwner<byte> with passing by concrete MemoryOwner<byte> (#7171)
* refactor(perf): pass MemoryOwner<byte> around as itself rather than IMemoryOwner<byte>

* fix(perf): get span via MemoryOwner<byte>.Span property instead of through Memory property

* fix: incorrect comment change
2024-09-18 23:00:54 -03:00
jhorv 59ddb26628 replace ByteMemoryPool usage in Ryujinx.Graphics (#7129)
* chore: replace `ByteMemoryPool` usage with `MemoryOwner<byte>`

* refactor: `PixelConverter.ConvertR4G4ToR4G4B4A4()` - rename old `outputSpan` to `outputSpanUInt16`, reuse same output `Span<byte>` as newly-freed name `outputSpan`

* eliminate temporary buffer allocations

* chore, perf: use MemoryOwner<byte> instead of IMemoryOwner<byte>
2024-08-03 19:50:53 +01:00
gdkchan 2ef4f92b07 Make TextureGroup.ClearModified thread safe (#6686) 2024-05-14 17:06:36 +02:00
jhorv 268c9aecf8 Texture loading: reduce memory allocations (#6623)
* rebase

* add methods Ryyjinx.Common EmbeddedResources and SteamUtils

* GAL changes - change SetData() methods and ThreadedTexture commands to use IMemoryOwner<byte> instead of SpanOrArray<byte>

* Ryujinx.Graphics.Texture: change texture conversion methods to return IMemoryOwner<byte> and allocate from ByteMemoryPool

* Ryujinx.Graphics.OpenGL: update ITexture and Texture-like types with SetData() methods to take IMemoryOwner<byte> instead of SpanOrArray<byte>

* Ryujinx.Graphics.Vulkan: update ITexture and Texture-like types with SetData() methods to take IMemoryOwner<byte> instead of SpanOrArray<byte>

* Ryujinx.Graphics.Gpu: update ITexture and Texture-like types with SetData() methods to take IMemoryOwner<byte> instead of SpanOrArray<byte>

* Remove now-unused SpanOrArray<T>

* post-rebase cleanup

* PixelConverter: remove unsafe modifier on safe methods, and remove one unnecessary cast

* use ByteMemoryPool.Rent() in GetWritableRegion() impls

* fix formatting, rename `ReadRentedMemory()` to `ReadFileToRentedMemory()``

* Texture.ConvertToHostCompatibleFormat(): dispose of `result` in Astc decode branch
2024-04-14 17:06:14 -03:00
gdkchan 8e74fa3456 Stop clearing Modified flag on DiscardData (#6591) 2024-04-03 21:30:46 -03:00
gdkchan dcf10561b9 Fix missing texture flush for draw then DMA copy sequence without render target change (#5933)
* Unbind render targets before DMA copy

* Move DirtyAction to TextureGroupHandle

* Fix lost copy dependency bug

* XML doc
2023-11-15 21:36:25 -03:00
gdkchan 1329c47ea4 Work around issue apparently caused by 5909 (#5926) 2023-11-14 22:24:54 -03:00
gdkchan e6e5838916 Do not set modified flag again if texture was not modified (#5909)
* Do not set modified flag again if texture was not modified

* Formatting

* Fix copy dep regression
2023-11-13 18:07:05 -03:00
gdkchan 9ef0be477b Skip some invalid texture flushes (#5755) 2023-10-30 23:18:28 +01:00
riperiperi f6c3f1cdfd GPU: Discard data when getting texture before full clear (#5719)
* GPU: Discard data when getting texture before full clear

* Fix rules and order of clear checks

* Fix formatting
2023-09-25 23:07:03 +02:00
gdkchan 9c6071a645 Move support buffer update out of the backends (#5411)
* Move support buffer update out of the backends

* Fix render scale init and remove redundant state from SupportBufferUpdater

* Stop passing texture scale to the backends

* XML docs for SupportBufferUpdater
2023-07-11 14:07:41 -03:00
TSRBerry 3b46bb73f7 [Ryujinx.Graphics.Gpu] Address dotnet-format issues (#5367)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1069 warnings

* Address or silence dotnet format CA2211 warnings

* Address remaining dotnet format analyzer warnings

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Another rebase, another dotnet format run

* Run dotnet format style after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Remove a few unused parameters

* Replace MmeShadowScratch with Array256<uint>

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Run dotnet format after rebase

* Address IDE0251 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First pass of dotnet format

* Add unsafe dotnet format changes

* Fix typos

* Add trailing commas

* Disable formatting for FormatTable

* Address review feedback
2023-07-02 02:47:54 +02:00
riperiperi 95c06de4c1 GPU: Remove swizzle undefined matching and rework depth aliasing (#4896)
* GPU: Remove swizzle undefined matching and rework depth aliasing

@gdkchan pointed out that UI textures in TOTK seemed to be setting their texture swizzle incorrectly (texture was RGB but was sampling A, swizzle for A was wrong), so I determined that SwizzleComponentMatches was the problem and set on eliminating it. This PR combines existing work to select the most recently modified texture (now used when selecting which aliased texture to use) with some additional changes to remove the swizzle check and support aliased view creation.

The original observation (#1538) was that we wanted to match depth textures for the purposes of aliasing with color textures, but they often had different swizzle from what was sampled (as it's generally the identity swizzle once rendered). At the time, I decided to allow swizzles to match if only the defined components matched, which fixed the issue in all known cases but could easily be broken by a game _expecting_ a given swizzle, such as a 1/0 value on a component.

This error case could also occur in textures that don't even depth alias, such as R11G11B10, as the rule was created to generally apply to all cases.

The solution is now to fail this exact match test, and allow the search for an R32 texture to create a swizzled view of a D32 texture (and other such cases). This allows the creation of a view that mismatches the requested format, which wasn't present before and was the reason for the swizzle matching approach.

The exact match and view creation rules now follow the same rules over what textures to select when there are multiple options (such as a "perfect" match and an "aliased" match at the same time). It now selects the most recently modified texture, which is done with a new sequence number in the GpuContext (because we don't have enough of these).

Reportedly fixes UI having weird coloured backgrounds in TOTK. This also fixes an issue in MK8D where returning from a race resulted in the character selection cubemaps being broken. May work around issues introduced by the "short texture cache" PR due to modification ordering, though they won't be truly fixed.

Should allow (#4365) to avoid copies in more cases. Need to test that.

I tested a bunch of games #1538 originally affected and they seem to be fine. This change affects all games so it would be good to get some wide testing on it.

* Address feedback 1, fix an issue

* Workaround: Do not allow copies for format alias.

These should be removed when D32<->R32 copy dependencies become legal
2023-05-11 21:30:47 -03:00
gdkchan 4d1579acbf Fix some invalid blits involving depth textures (#4723) 2023-05-03 21:20:12 -03:00
riperiperi 2c94ac455e GPU: Keep rendered textures without any pool references alive (#4662)
* GPU: Keep sampled textures without any pool references alive

Occasionally games are very wasteful and clear/write to a texture without ever sampling it. As rendered textures in NVN games seem to all have overlapping memory ranges, the texture will eventually get overwritten.

Normally, this would trigger a removal from the auto delete cache, but a pool entry would keep the texture alive. However, with these textures that are never used, they will get deleted immediately and recreated on the next frame.

This change makes it so the ShortTextureCache can keep textures that have naver had a pool reference alive for a few frames, so they're not constantly being created and deleted.

This improves performance in Zelda BOTW a little.

* Cleanup
2023-05-01 16:27:51 -03:00
riperiperi e18d258fa0 GPU: Pre-emptively flush textures that are flushed often (to imported memory when available) (#4711)
* WIP texture pre-flush

Improve performance of TextureView GetData to buffer

Fix copy/sync ordering

Fix minor bug

Make this actually work

WIP host mapping stuff

* Fix usage flags

* message

* Cleanup 1

* Fix rebase

* Fix

* Improve pre-flush rules

* Fix pre-flush

* A lot of cleanup

* Use the host memory bits

* Select the correct memory type

* Cleanup TextureGroupHandle

* Missing comment

* Remove debugging logs

* Revert BufferHandle _value access modifier

* One interrupt action at a time.

* Support D32S8 to D24S8 conversion, safeguards

* Interrupt cannot happen in sync handle's lock

Waitable needs to be checked twice now, but this should stop it from deadlocking.

* Remove unused using

* Address some feedback

* Address feedback

* Address more feedback

* Address more feedback

* Improve sync rules

Should allow for faster sync in some cases.
2023-05-01 16:05:12 -03:00
riperiperi 36f10df775 GPU: Fix errors handling texture remapping (#4745)
* GPU: Fix errors handling texture remapping

- Fixes an error where a pool entry and memory mapping changing at the same time could cause a texture to rebind its data from the wrong GPU VA (data swaps)
- Fixes an error where the texture pool could act on a mapping change before the mapping has actually been changed ("Unmapped" event happens before change, we need to signal it changed _after_ it completes)

TODO: remove textures from partially mapped list... if they aren't.

* Add Remap actions for handling post-mapping behaviours

* Remove unused code.

* Address feedback

* Nit
2023-05-01 15:32:32 -03:00
TSR Berry cee7121058 Move solution and projects to src 2023-04-27 23:51:14 +02:00