diff options
author | gdkchan <gab.dark.100@gmail.com> | 2021-06-29 14:32:02 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-29 19:32:02 +0200 |
commit | fbb4019ed5c12c4a888c7b09db648ac595366896 (patch) | |
tree | a8be6bf5fc4f8b844683f1ef2ade588f3bb9bb0a /Ryujinx.Graphics.Gpu/Image/TextureCache.cs | |
parent | 8cc872fb60ec1b825655ba8dba06cc978fcd7e66 (diff) |
Initial support for separate GPU address spaces (#2394)
* Make GPU memory manager a member of GPU channel
* Move physical memory instance to the memory manager, and the caches to the physical memory
* PR feedback
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Image/TextureCache.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Image/TextureCache.cs | 86 |
1 files changed, 58 insertions, 28 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureCache.cs b/Ryujinx.Graphics.Gpu/Image/TextureCache.cs index 24fa723a..37a2219f 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureCache.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureCache.cs @@ -32,6 +32,7 @@ namespace Ryujinx.Graphics.Gpu.Image private const int OverlapsBufferMaxCapacity = 10000; private readonly GpuContext _context; + private readonly PhysicalMemory _physicalMemory; private readonly MultiRangeList<Texture> _textures; @@ -44,9 +45,11 @@ namespace Ryujinx.Graphics.Gpu.Image /// Constructs a new instance of the texture manager. /// </summary> /// <param name="context">The GPU context that the texture manager belongs to</param> - public TextureCache(GpuContext context) + /// <param name="physicalMemory">Physical memory where the textures managed by this cache are mapped</param> + public TextureCache(GpuContext context, PhysicalMemory physicalMemory) { _context = context; + _physicalMemory = physicalMemory; _textures = new MultiRangeList<Texture>(); @@ -68,7 +71,7 @@ namespace Ryujinx.Graphics.Gpu.Image lock (_textures) { - overlapCount = _textures.FindOverlaps(_context.MemoryManager.Translate(e.Address), e.Size, ref overlaps); + overlapCount = _textures.FindOverlaps(((MemoryManager)sender).Translate(e.Address), e.Size, ref overlaps); } for (int i = 0; i < overlapCount; i++) @@ -139,13 +142,20 @@ namespace Ryujinx.Graphics.Gpu.Image /// <summary> /// Tries to find an existing texture, or create a new one if not found. /// </summary> + /// <param name="memoryManager">GPU memory manager where the texture is mapped</param> /// <param name="copyTexture">Copy texture to find or create</param> /// <param name="offset">Offset to be added to the physical texture address</param> /// <param name="formatInfo">Format information of the copy texture</param> /// <param name="preferScaling">Indicates if the texture should be scaled from the start</param> /// <param name="sizeHint">A hint indicating the minimum used size for the texture</param> /// <returns>The texture</returns> - public Texture FindOrCreateTexture(CopyTexture copyTexture, ulong offset, FormatInfo formatInfo, bool preferScaling = true, Size? sizeHint = null) + public Texture FindOrCreateTexture( + MemoryManager memoryManager, + CopyTexture copyTexture, + ulong offset, + FormatInfo formatInfo, + bool preferScaling = true, + Size? sizeHint = null) { int gobBlocksInY = copyTexture.MemoryLayout.UnpackGobBlocksInY(); int gobBlocksInZ = copyTexture.MemoryLayout.UnpackGobBlocksInZ(); @@ -184,7 +194,7 @@ namespace Ryujinx.Graphics.Gpu.Image flags |= TextureSearchFlags.WithUpscale; } - Texture texture = FindOrCreateTexture(flags, info, 0, sizeHint); + Texture texture = FindOrCreateTexture(memoryManager, flags, info, 0, sizeHint); texture?.SynchronizeMemory(); @@ -194,12 +204,13 @@ namespace Ryujinx.Graphics.Gpu.Image /// <summary> /// Tries to find an existing texture, or create a new one if not found. /// </summary> + /// <param name="memoryManager">GPU memory manager where the texture is mapped</param> /// <param name="colorState">Color buffer texture to find or create</param> /// <param name="samplesInX">Number of samples in the X direction, for MSAA</param> /// <param name="samplesInY">Number of samples in the Y direction, for MSAA</param> /// <param name="sizeHint">A hint indicating the minimum used size for the texture</param> /// <returns>The texture</returns> - public Texture FindOrCreateTexture(RtColorState colorState, int samplesInX, int samplesInY, Size sizeHint) + public Texture FindOrCreateTexture(MemoryManager memoryManager, RtColorState colorState, int samplesInX, int samplesInY, Size sizeHint) { bool isLinear = colorState.MemoryLayout.UnpackIsLinear(); @@ -263,7 +274,7 @@ namespace Ryujinx.Graphics.Gpu.Image int layerSize = !isLinear ? colorState.LayerSize * 4 : 0; - Texture texture = FindOrCreateTexture(TextureSearchFlags.WithUpscale, info, layerSize, sizeHint); + Texture texture = FindOrCreateTexture(memoryManager, TextureSearchFlags.WithUpscale, info, layerSize, sizeHint); texture?.SynchronizeMemory(); @@ -273,13 +284,20 @@ namespace Ryujinx.Graphics.Gpu.Image /// <summary> /// Tries to find an existing texture, or create a new one if not found. /// </summary> + /// <param name="memoryManager">GPU memory manager where the texture is mapped</param> /// <param name="dsState">Depth-stencil buffer texture to find or create</param> /// <param name="size">Size of the depth-stencil texture</param> /// <param name="samplesInX">Number of samples in the X direction, for MSAA</param> /// <param name="samplesInY">Number of samples in the Y direction, for MSAA</param> /// <param name="sizeHint">A hint indicating the minimum used size for the texture</param> /// <returns>The texture</returns> - public Texture FindOrCreateTexture(RtDepthStencilState dsState, Size3D size, int samplesInX, int samplesInY, Size sizeHint) + public Texture FindOrCreateTexture( + MemoryManager memoryManager, + RtDepthStencilState dsState, + Size3D size, + int samplesInX, + int samplesInY, + Size sizeHint) { int gobBlocksInY = dsState.MemoryLayout.UnpackGobBlocksInY(); int gobBlocksInZ = dsState.MemoryLayout.UnpackGobBlocksInZ(); @@ -306,7 +324,7 @@ namespace Ryujinx.Graphics.Gpu.Image target, formatInfo); - Texture texture = FindOrCreateTexture(TextureSearchFlags.WithUpscale, info, dsState.LayerSize * 4, sizeHint); + Texture texture = FindOrCreateTexture(memoryManager, TextureSearchFlags.WithUpscale, info, dsState.LayerSize * 4, sizeHint); texture?.SynchronizeMemory(); @@ -316,13 +334,20 @@ namespace Ryujinx.Graphics.Gpu.Image /// <summary> /// Tries to find an existing texture, or create a new one if not found. /// </summary> + /// <param name="memoryManager">GPU memory manager where the texture is mapped</param> /// <param name="flags">The texture search flags, defines texture comparison rules</param> /// <param name="info">Texture information of the texture to be found or created</param> /// <param name="layerSize">Size in bytes of a single texture layer</param> /// <param name="sizeHint">A hint indicating the minimum used size for the texture</param> /// <param name="range">Optional ranges of physical memory where the texture data is located</param> /// <returns>The texture</returns> - public Texture FindOrCreateTexture(TextureSearchFlags flags, TextureInfo info, int layerSize = 0, Size? sizeHint = null, MultiRange? range = null) + public Texture FindOrCreateTexture( + MemoryManager memoryManager, + TextureSearchFlags flags, + TextureInfo info, + int layerSize = 0, + Size? sizeHint = null, + MultiRange? range = null) { bool isSamplerTexture = (flags & TextureSearchFlags.ForSampler) != 0; @@ -342,7 +367,7 @@ namespace Ryujinx.Graphics.Gpu.Image } else { - address = _context.MemoryManager.Translate(info.GpuAddress); + address = memoryManager.Translate(info.GpuAddress); if (address == MemoryManager.PteUnmapped) { @@ -371,22 +396,26 @@ namespace Ryujinx.Graphics.Gpu.Image if (matchQuality != TextureMatchQuality.NoMatch) { // If the parameters match, we need to make sure the texture is mapped to the same memory regions. - - // If a range of memory was supplied, just check if the ranges match. - if (range != null && !overlap.Range.Equals(range.Value)) + if (range != null) { - continue; + // If a range of memory was supplied, just check if the ranges match. + if (!overlap.Range.Equals(range.Value)) + { + continue; + } } - - // If no range was supplied, we can check if the GPU virtual address match. If they do, - // we know the textures are located at the same memory region. - // If they don't, it may still be mapped to the same physical region, so we - // do a more expensive check to tell if they are mapped into the same physical regions. - // If the GPU VA for the texture has ever been unmapped, then the range must be checked regardless. - if ((overlap.Info.GpuAddress != info.GpuAddress || overlap.ChangedMapping) && - !_context.MemoryManager.CompareRange(overlap.Range, info.GpuAddress)) + else { - continue; + // If no range was supplied, we can check if the GPU virtual address match. If they do, + // we know the textures are located at the same memory region. + // If they don't, it may still be mapped to the same physical region, so we + // do a more expensive check to tell if they are mapped into the same physical regions. + // If the GPU VA for the texture has ever been unmapped, then the range must be checked regardless. + if ((overlap.Info.GpuAddress != info.GpuAddress || overlap.ChangedMapping) && + !memoryManager.CompareRange(overlap.Range, info.GpuAddress)) + { + continue; + } } } @@ -426,7 +455,7 @@ namespace Ryujinx.Graphics.Gpu.Image if (range == null) { - range = _context.MemoryManager.GetPhysicalRegions(info.GpuAddress, size); + range = memoryManager.GetPhysicalRegions(info.GpuAddress, size); } // Find view compatible matches. @@ -495,7 +524,7 @@ namespace Ryujinx.Graphics.Gpu.Image { // Only copy compatible. If there's another choice for a FULLY compatible texture, choose that instead. - texture = new Texture(_context, info, sizeInfo, range.Value, scaleMode); + texture = new Texture(_context, _physicalMemory, info, sizeInfo, range.Value, scaleMode); texture.InitializeGroup(true, true); texture.InitializeData(false, false); @@ -531,7 +560,7 @@ namespace Ryujinx.Graphics.Gpu.Image // No match, create a new texture. if (texture == null) { - texture = new Texture(_context, info, sizeInfo, range.Value, scaleMode); + texture = new Texture(_context, _physicalMemory, info, sizeInfo, range.Value, scaleMode); // Step 1: Find textures that are view compatible with the new texture. // Any textures that are incompatible will contain garbage data, so they should be removed where possible. @@ -722,14 +751,15 @@ namespace Ryujinx.Graphics.Gpu.Image /// <summary> /// Tries to find an existing texture matching the given buffer copy destination. If none is found, returns null. /// </summary> + /// <param name="memoryManager">GPU memory manager where the texture is mapped</param> /// <param name="tex">The texture information</param> /// <param name="cbp">The copy buffer parameters</param> /// <param name="swizzle">The copy buffer swizzle</param> /// <param name="linear">True if the texture has a linear layout, false otherwise</param> /// <returns>A matching texture, or null if there is no match</returns> - public Texture FindTexture(CopyBufferTexture tex, CopyBufferParams cbp, CopyBufferSwizzle swizzle, bool linear) + public Texture FindTexture(MemoryManager memoryManager, CopyBufferTexture tex, CopyBufferParams cbp, CopyBufferSwizzle swizzle, bool linear) { - ulong address = _context.MemoryManager.Translate(cbp.DstAddress.Pack()); + ulong address = memoryManager.Translate(cbp.DstAddress.Pack()); if (address == MemoryManager.PteUnmapped) { |