From 0a24aa6af26cc55c079e265a071a42569d28d2c0 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 22 Feb 2022 13:34:16 -0300 Subject: Allow textures to have their data partially mapped (#2629) * Allow textures to have their data partially mapped * Explicitly check for invalid memory ranges on the MultiRangeList * Update GetWritableRegion to also support unmapped ranges --- Ryujinx.Memory/Range/MemoryRange.cs | 7 +++++++ Ryujinx.Memory/Range/MultiRangeList.cs | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'Ryujinx.Memory') diff --git a/Ryujinx.Memory/Range/MemoryRange.cs b/Ryujinx.Memory/Range/MemoryRange.cs index ba12bae5..33d2439f 100644 --- a/Ryujinx.Memory/Range/MemoryRange.cs +++ b/Ryujinx.Memory/Range/MemoryRange.cs @@ -50,6 +50,13 @@ namespace Ryujinx.Memory.Range ulong otherAddress = other.Address; ulong otherEndAddress = other.EndAddress; + // If any of the ranges if invalid (address + size overflows), + // then they are never considered to overlap. + if (thisEndAddress < thisAddress || otherEndAddress < otherAddress) + { + return false; + } + return thisAddress < otherEndAddress && otherAddress < thisEndAddress; } diff --git a/Ryujinx.Memory/Range/MultiRangeList.cs b/Ryujinx.Memory/Range/MultiRangeList.cs index 38ca63b4..5131889f 100644 --- a/Ryujinx.Memory/Range/MultiRangeList.cs +++ b/Ryujinx.Memory/Range/MultiRangeList.cs @@ -29,6 +29,12 @@ namespace Ryujinx.Memory.Range for (int i = 0; i < range.Count; i++) { var subrange = range.GetSubRange(i); + + if (IsInvalid(ref subrange)) + { + continue; + } + _items.Add(subrange.Address, subrange.EndAddress, item); } @@ -49,6 +55,12 @@ namespace Ryujinx.Memory.Range for (int i = 0; i < range.Count; i++) { var subrange = range.GetSubRange(i); + + if (IsInvalid(ref subrange)) + { + continue; + } + removed += _items.Remove(subrange.Address, item); } @@ -86,6 +98,12 @@ namespace Ryujinx.Memory.Range for (int i = 0; i < range.Count; i++) { var subrange = range.GetSubRange(i); + + if (IsInvalid(ref subrange)) + { + continue; + } + overlapCount = _items.Get(subrange.Address, subrange.EndAddress, ref output, overlapCount); } @@ -124,6 +142,17 @@ namespace Ryujinx.Memory.Range return overlapCount; } + /// + /// Checks if a given sub-range of memory is invalid. + /// Those are used to represent unmapped memory regions (holes in the region mapping). + /// + /// Memory range to checl + /// True if the memory range is considered invalid, false otherwise + private static bool IsInvalid(ref MemoryRange subRange) + { + return subRange.Address == ulong.MaxValue; + } + /// /// Gets all items on the list starting at the specified memory address. /// -- cgit v1.2.3