diff options
author | riperiperi <rhy3756547@hotmail.com> | 2023-03-14 20:33:44 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-14 17:33:44 -0300 |
commit | da073fce6127243fcd93b736cde951c4e835e508 (patch) | |
tree | edc9c22d7d35212c3cedc4c00c6acdefbf3b5e21 /Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs | |
parent | 1fc90e57d2e7f7bb6886a58b81bcd1f4cb25f8cf (diff) |
GPU: Fast path for adding one texture view to a group (#4528)1.1.665
* GPU: Fast path for adding one texture view to a group
Texture group handles must store a list of their overlapping views, so they can be properly notified when a write is detected, and a few other things relating to texture readback. This is generally created when the group is established, with each handle looping over all views to find its overlaps. This whole process was also done when only a single view was added (and no handles were changed), however...
Sonic Frontiers had a huge cubemap array with 7350 faces (175 cubemaps * 6 faces * 7 levels), so iterating over both handles and existing views added up very fast. Since we are only adding a single view, we only need to _add_ that view to the existing overlaps, rather than recalculate them all.
This greatly improves performance during loading screens and a few seconds into gameplay on the "open zone" sections of Sonic Frontiers. May improve loading times or stutters on some other games.
Note that the current texture cache rules will cause these views to fall out of the cache, as there are more than the hard cap, so the cost will be repaid when reloading the open zone.
I also added some code to properly remove overlaps when texture views are removed, since it seems that was missing.
This can be improved further by only iterating handles that overlap the view (filter by range), but so can a few places in TextureGroup, so better to do all at once. The full generation of overlaps could probably be improved in a similar way.
I recommend testing a few games to make sure nothing breaks.
* Address feedback
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs b/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs index 1b83cb55..ebb4e9ae 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs @@ -160,6 +160,42 @@ namespace Ryujinx.Graphics.Gpu.Image } /// <summary> + /// Adds a single texture view as an overlap if its range overlaps. + /// </summary> + /// <param name="offset">The offset of the view in the group</param> + /// <param name="view">The texture to add as an overlap</param> + public void AddOverlap(int offset, Texture view) + { + // Overlaps can be accessed from the memory tracking signal handler, so access must be atomic. + + if (OverlapsWith(offset, (int)view.Size)) + { + lock (Overlaps) + { + Overlaps.Add(view); + } + } + } + + /// <summary> + /// Removes a single texture view as an overlap if its range overlaps. + /// </summary> + /// <param name="offset">The offset of the view in the group</param> + /// <param name="view">The texture to add as an overlap</param> + public void RemoveOverlap(int offset, Texture view) + { + // Overlaps can be accessed from the memory tracking signal handler, so access must be atomic. + + if (OverlapsWith(offset, (int)view.Size)) + { + lock (Overlaps) + { + Overlaps.Remove(view); + } + } + } + + /// <summary> /// Registers a sync action to happen for this handle, and an interim flush action on the tracking handle. /// </summary> /// <param name="context">The GPU context to register a sync action on</param> |