Texture Sync, incompatible overlap handling, data flush improvements. (#2971)

* Initial test for texture sync

* WIP new texture flushing setup

* Improve rules for incompatible overlaps

Fixes a lot of issues with Unreal Engine games. Still a few minor issues (some caused by dma fast path?) Needs docs and cleanup.

* Cleanup, improvements

Improve rules for fast DMA

* Small tweak to group together flushes of overlapping handles.

* Fixes, flush overlapping texture data for ASTC and BC4/5 compressed textures.

Fixes the new Life is Strange game.

* Flush overlaps before init data, fix 3d texture size/overlap stuff

* Fix 3D Textures, faster single layer flush

Note: nosy people can no longer merge this with Vulkan. (unless they are nosy enough to implement the new backend methods)

* Remove unused method

* Minor cleanup

* More cleanup

* Use the More Fun and Hopefully No Driver Bugs method for getting compressed tex too

This one's for metro

* Address feedback, ASTC+ETC to FormatClass

* Change offset to use Span slice rather than IntPtr Add

* Fix this too
This commit is contained in:
riperiperi 2022-01-09 16:28:48 +00:00 committed by GitHub
parent 4864648e72
commit cda659955c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 1453 additions and 329 deletions

View file

@ -135,6 +135,38 @@ namespace Ryujinx.Graphics.Gpu.Memory
return _cpuMemory.GetWritableRegion(address, size, tracked);
}
/// <summary>
/// Gets a writable region from GPU mapped memory.
/// </summary>
/// <param name="range">Range</param>
/// <param name="tracked">True if write tracking is triggered on the span</param>
/// <returns>A writable region with the data at the specified memory location</returns>
public WritableRegion GetWritableRegion(MultiRange range, bool tracked = false)
{
if (range.Count == 1)
{
MemoryRange subrange = range.GetSubRange(0);
return GetWritableRegion(subrange.Address, (int)subrange.Size, tracked);
}
else
{
Memory<byte> memory = new byte[range.GetSize()];
int offset = 0;
for (int i = 0; i < range.Count; i++)
{
MemoryRange subrange = range.GetSubRange(i);
GetSpan(subrange.Address, (int)subrange.Size).CopyTo(memory.Span.Slice(offset, (int)subrange.Size));
offset += (int)subrange.Size;
}
return new WritableRegion(new MultiRangeWritableBlock(range, this), 0, memory, tracked);
}
}
/// <summary>
/// Reads data from the application process.
/// </summary>