From f665e1b40969d1673c7a12c44235aefb2a2ea627 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Fri, 2 Apr 2021 11:33:39 -0300 Subject: [PATCH] Hold reference for render targets in use (#2156) --- Ryujinx.Graphics.Gpu/Image/Texture.cs | 15 ++++-- Ryujinx.Graphics.Gpu/Image/TextureManager.cs | 52 ++++++++++---------- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs index 26e102a9..6d2510f1 100644 --- a/Ryujinx.Graphics.Gpu/Image/Texture.cs +++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs @@ -73,7 +73,7 @@ namespace Ryujinx.Graphics.Gpu.Image public bool ChangedSize { get; private set; } /// - /// Set when a texture's GPU VA has ever been partially or fully unmapped. + /// Set when a texture's GPU VA has ever been partially or fully unmapped. /// This indicates that the range must be fully checked when matching the texture. /// public bool ChangedMapping { get; private set; } @@ -628,7 +628,7 @@ namespace Ryujinx.Graphics.Gpu.Image } /// - /// Fully synchronizes guest and host memory. + /// Fully synchronizes guest and host memory. /// This will replace the entire texture with the data present in guest memory. /// public void SynchronizeFull() @@ -1127,7 +1127,7 @@ namespace Ryujinx.Graphics.Gpu.Image { TextureCreateInfo createInfo = TextureManager.GetCreateInfo(view.Info, _context.Capabilities, ScaleFactor); - ITexture newView = parent.HostTexture.CreateView(createInfo, view.FirstLayer + firstLayer, view.FirstLevel + firstLevel); + ITexture newView = parent.HostTexture.CreateView(createInfo, view.FirstLayer + firstLayer, view.FirstLevel + firstLevel); view.ReplaceView(parent, view.Info, newView, view.FirstLayer + firstLayer, view.FirstLevel + firstLevel); } @@ -1188,6 +1188,15 @@ namespace Ryujinx.Graphics.Gpu.Image IsModified = true; Group.SignalModifying(this, bound, !wasModified); } + + if (bound) + { + IncrementReferenceCount(); + } + else + { + DecrementReferenceCount(); + } } /// diff --git a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs index 2b756e4c..17bb553f 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs @@ -197,6 +197,27 @@ namespace Ryujinx.Graphics.Gpu.Image return changesScale || (hasValue && color.ScaleMode != TextureScaleMode.Blacklisted && color.ScaleFactor != GraphicsConfig.ResScale); } + /// + /// Sets the render target depth-stencil buffer. + /// + /// The depth-stencil buffer texture + /// True if render target scale must be updated. + public bool SetRenderTargetDepthStencil(Texture depthStencil) + { + bool hasValue = depthStencil != null; + bool changesScale = (hasValue != (_rtDepthStencil != null)) || (hasValue && RenderTargetScale != depthStencil.ScaleFactor); + + if (_rtDepthStencil != depthStencil) + { + _rtDepthStencil?.SignalModifying(false); + depthStencil?.SignalModifying(true); + + _rtDepthStencil = depthStencil; + } + + return changesScale || (hasValue && depthStencil.ScaleMode != TextureScaleMode.Blacklisted && depthStencil.ScaleFactor != GraphicsConfig.ResScale); + } + /// /// Gets the first available bound colour target, or the depth stencil target if not present. /// @@ -290,27 +311,6 @@ namespace Ryujinx.Graphics.Gpu.Image RenderTargetScale = targetScale; } - /// - /// Sets the render target depth-stencil buffer. - /// - /// The depth-stencil buffer texture - /// True if render target scale must be updated. - public bool SetRenderTargetDepthStencil(Texture depthStencil) - { - bool hasValue = depthStencil != null; - bool changesScale = (hasValue != (_rtDepthStencil != null)) || (hasValue && RenderTargetScale != depthStencil.ScaleFactor); - - if (_rtDepthStencil != depthStencil) - { - _rtDepthStencil?.SignalModifying(false); - depthStencil?.SignalModifying(true); - - _rtDepthStencil = depthStencil; - } - - return changesScale || (hasValue && depthStencil.ScaleMode != TextureScaleMode.Blacklisted && depthStencil.ScaleFactor != GraphicsConfig.ResScale); - } - /// /// Commits bindings on the compute pipeline. /// @@ -716,7 +716,7 @@ namespace Ryujinx.Graphics.Gpu.Image // 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) && + if ((overlap.Info.GpuAddress != info.GpuAddress || overlap.ChangedMapping) && !_context.MemoryManager.CompareRange(overlap.Range, info.GpuAddress)) { continue; @@ -775,7 +775,7 @@ namespace Ryujinx.Graphics.Gpu.Image Array.Resize(ref _overlapInfo, _textureOverlaps.Length); } - // =============== Find Texture View of Existing Texture =============== + // =============== Find Texture View of Existing Texture =============== int fullyCompatible = 0; @@ -841,7 +841,7 @@ namespace Ryujinx.Graphics.Gpu.Image if (texture != null) { // This texture could be a view of multiple parent textures with different storages, even if it is a view. - // When a texture is created, make sure all possible dependencies to other textures are created as copies. + // When a texture is created, make sure all possible dependencies to other textures are created as copies. // (even if it could be fulfilled without a copy) for (int index = 0; index < overlapsCount; index++) @@ -859,7 +859,7 @@ namespace Ryujinx.Graphics.Gpu.Image texture.SynchronizeMemory(); } - // =============== Create a New Texture =============== + // =============== Create a New Texture =============== // No match, create a new texture. if (texture == null) @@ -993,7 +993,7 @@ namespace Ryujinx.Graphics.Gpu.Image overlap.ReplaceView(texture, overlapInfo, newView, oInfo.FirstLayer, oInfo.FirstLevel); } } - + texture.SynchronizeMemory(); }