Improve handling for unmapped GPU resources (#2083)
* Improve handling for unmapped GPU resources - Fixed a memory tracking bug that would set protection on empty PTEs - When a texture's memory is (partially) unmapped, all pool references are forcibly removed and the texture must be rediscovered to draw with it. This will also force the texture discovery to always compare the texture's range for a match. - RegionHandles now know if they are unmapped, and automatically unset their dirty flag when unmapped. - Partial texture sync now loads only the region of texture that has been modified. Unmapped memory tracking handles cause dirty flags for a texture group handle to be ignored. This greatly improves the emulator's stability for newer UE4 games. * Address feedback, fix MultiRange slice Fixed an issue where the size of the multi-range slice would be miscalculated. * Update Ryujinx.Memory/Range/MultiRange.cs (feedback) Co-authored-by: Mary <thog@protonmail.com> Co-authored-by: Mary <thog@protonmail.com>
This commit is contained in:
parent
bab6eedccf
commit
8d36681bf1
11 changed files with 229 additions and 15 deletions
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Memory.Range
|
||||
{
|
||||
|
@ -75,6 +76,53 @@ namespace Ryujinx.Memory.Range
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a slice of the multi-range.
|
||||
/// </summary>
|
||||
/// <param name="offset">Offset of the slice into the multi-range in bytes</param>
|
||||
/// <param name="size">Size of the slice in bytes</param>
|
||||
/// <returns>A new multi-range representing the given slice of this one</returns>
|
||||
public MultiRange GetSlice(ulong offset, ulong size)
|
||||
{
|
||||
if (HasSingleRange)
|
||||
{
|
||||
if (_singleRange.Size - offset < size)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(size));
|
||||
}
|
||||
|
||||
return new MultiRange(_singleRange.Address + offset, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
var ranges = new List<MemoryRange>();
|
||||
|
||||
foreach (MemoryRange range in _ranges)
|
||||
{
|
||||
if ((long)offset <= 0)
|
||||
{
|
||||
ranges.Add(new MemoryRange(range.Address, Math.Min(size, range.Size)));
|
||||
size -= range.Size;
|
||||
}
|
||||
else if (offset < range.Size)
|
||||
{
|
||||
ulong sliceSize = Math.Min(size, range.Size - offset);
|
||||
ranges.Add(new MemoryRange(range.Address + offset, sliceSize));
|
||||
size -= sliceSize;
|
||||
}
|
||||
|
||||
if ((long)size <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
offset -= range.Size;
|
||||
}
|
||||
|
||||
return new MultiRange(ranges.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the physical region at the specified index.
|
||||
/// </summary>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue