|
@@ -64,7 +64,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
- /// Handles removal of textures written to a memory region being unmapped.
|
|
|
|
|
|
|
+ /// Handles marking of textures written to a memory region being (partially) remapped.
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
/// <param name="sender">Sender object</param>
|
|
/// <param name="sender">Sender object</param>
|
|
|
/// <param name="e">Event arguments</param>
|
|
/// <param name="e">Event arguments</param>
|
|
@@ -80,26 +80,41 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
overlapCount = _textures.FindOverlaps(unmapped, ref overlaps);
|
|
overlapCount = _textures.FindOverlaps(unmapped, ref overlaps);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- for (int i = 0; i < overlapCount; i++)
|
|
|
|
|
|
|
+ if (overlapCount > 0)
|
|
|
{
|
|
{
|
|
|
- overlaps[i].Unmapped(unmapped);
|
|
|
|
|
|
|
+ for (int i = 0; i < overlapCount; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ overlaps[i].Unmapped(unmapped);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // If any range was previously unmapped, we also need to purge
|
|
|
|
|
- // all partially mapped texture, as they might be fully mapped now.
|
|
|
|
|
- for (int i = 0; i < unmapped.Count; i++)
|
|
|
|
|
|
|
+ lock (_partiallyMappedTextures)
|
|
|
{
|
|
{
|
|
|
- if (unmapped.GetSubRange(i).Address == MemoryManager.PteUnmapped)
|
|
|
|
|
|
|
+ if (overlapCount > 0 || _partiallyMappedTextures.Count > 0)
|
|
|
{
|
|
{
|
|
|
- lock (_partiallyMappedTextures)
|
|
|
|
|
|
|
+ e.AddRemapAction(() =>
|
|
|
{
|
|
{
|
|
|
- foreach (var texture in _partiallyMappedTextures)
|
|
|
|
|
|
|
+ lock (_partiallyMappedTextures)
|
|
|
{
|
|
{
|
|
|
- texture.Unmapped(unmapped);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (overlapCount > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ for (int i = 0; i < overlapCount; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ _partiallyMappedTextures.Add(overlaps[i]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- break;
|
|
|
|
|
|
|
+ // Any texture that has been unmapped at any point or is partially unmapped
|
|
|
|
|
+ // should update their pool references after the remap completes.
|
|
|
|
|
+
|
|
|
|
|
+ MultiRange unmapped = ((MemoryManager)sender).GetPhysicalRegions(e.Address, e.Size);
|
|
|
|
|
+
|
|
|
|
|
+ foreach (var texture in _partiallyMappedTextures)
|
|
|
|
|
+ {
|
|
|
|
|
+ texture.UpdatePoolMappings();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -1135,6 +1150,44 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Queries a texture's memory range and marks it as partially mapped or not.
|
|
|
|
|
+ /// Partially mapped textures re-evaluate their memory range after each time GPU memory is mapped.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="memoryManager">GPU memory manager where the texture is mapped</param>
|
|
|
|
|
+ /// <param name="address">The virtual address of the texture</param>
|
|
|
|
|
+ /// <param name="texture">The texture to be marked</param>
|
|
|
|
|
+ /// <returns>The physical regions for the texture, found when evaluating whether the texture was partially mapped</returns>
|
|
|
|
|
+ public MultiRange UpdatePartiallyMapped(MemoryManager memoryManager, ulong address, Texture texture)
|
|
|
|
|
+ {
|
|
|
|
|
+ MultiRange range;
|
|
|
|
|
+ lock (_partiallyMappedTextures)
|
|
|
|
|
+ {
|
|
|
|
|
+ range = memoryManager.GetPhysicalRegions(address, texture.Size);
|
|
|
|
|
+ bool partiallyMapped = false;
|
|
|
|
|
+
|
|
|
|
|
+ for (int i = 0; i < range.Count; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (range.GetSubRange(i).Address == MemoryManager.PteUnmapped)
|
|
|
|
|
+ {
|
|
|
|
|
+ partiallyMapped = true;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (partiallyMapped)
|
|
|
|
|
+ {
|
|
|
|
|
+ _partiallyMappedTextures.Add(texture);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ _partiallyMappedTextures.Remove(texture);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return range;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// Adds a texture to the short duration cache. This typically keeps it alive for two ticks.
|
|
/// Adds a texture to the short duration cache. This typically keeps it alive for two ticks.
|
|
|
/// </summary>
|
|
/// </summary>
|