Hold reference for render targets in use (#2156)

This commit is contained in:
gdkchan 2021-04-02 11:33:39 -03:00 committed by GitHub
parent 9ae60207c4
commit f665e1b409
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 29 deletions

View file

@ -73,7 +73,7 @@ namespace Ryujinx.Graphics.Gpu.Image
public bool ChangedSize { get; private set; } public bool ChangedSize { get; private set; }
/// <summary> /// <summary>
/// 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. /// This indicates that the range must be fully checked when matching the texture.
/// </summary> /// </summary>
public bool ChangedMapping { get; private set; } public bool ChangedMapping { get; private set; }
@ -628,7 +628,7 @@ namespace Ryujinx.Graphics.Gpu.Image
} }
/// <summary> /// <summary>
/// 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. /// This will replace the entire texture with the data present in guest memory.
/// </summary> /// </summary>
public void SynchronizeFull() public void SynchronizeFull()
@ -1127,7 +1127,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{ {
TextureCreateInfo createInfo = TextureManager.GetCreateInfo(view.Info, _context.Capabilities, ScaleFactor); 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); view.ReplaceView(parent, view.Info, newView, view.FirstLayer + firstLayer, view.FirstLevel + firstLevel);
} }
@ -1188,6 +1188,15 @@ namespace Ryujinx.Graphics.Gpu.Image
IsModified = true; IsModified = true;
Group.SignalModifying(this, bound, !wasModified); Group.SignalModifying(this, bound, !wasModified);
} }
if (bound)
{
IncrementReferenceCount();
}
else
{
DecrementReferenceCount();
}
} }
/// <summary> /// <summary>

View file

@ -197,6 +197,27 @@ namespace Ryujinx.Graphics.Gpu.Image
return changesScale || (hasValue && color.ScaleMode != TextureScaleMode.Blacklisted && color.ScaleFactor != GraphicsConfig.ResScale); return changesScale || (hasValue && color.ScaleMode != TextureScaleMode.Blacklisted && color.ScaleFactor != GraphicsConfig.ResScale);
} }
/// <summary>
/// Sets the render target depth-stencil buffer.
/// </summary>
/// <param name="depthStencil">The depth-stencil buffer texture</param>
/// <returns>True if render target scale must be updated.</returns>
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);
}
/// <summary> /// <summary>
/// Gets the first available bound colour target, or the depth stencil target if not present. /// Gets the first available bound colour target, or the depth stencil target if not present.
/// </summary> /// </summary>
@ -290,27 +311,6 @@ namespace Ryujinx.Graphics.Gpu.Image
RenderTargetScale = targetScale; RenderTargetScale = targetScale;
} }
/// <summary>
/// Sets the render target depth-stencil buffer.
/// </summary>
/// <param name="depthStencil">The depth-stencil buffer texture</param>
/// <returns>True if render target scale must be updated.</returns>
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);
}
/// <summary> /// <summary>
/// Commits bindings on the compute pipeline. /// Commits bindings on the compute pipeline.
/// </summary> /// </summary>
@ -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 // 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. // 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 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)) !_context.MemoryManager.CompareRange(overlap.Range, info.GpuAddress))
{ {
continue; continue;
@ -775,7 +775,7 @@ namespace Ryujinx.Graphics.Gpu.Image
Array.Resize(ref _overlapInfo, _textureOverlaps.Length); Array.Resize(ref _overlapInfo, _textureOverlaps.Length);
} }
// =============== Find Texture View of Existing Texture =============== // =============== Find Texture View of Existing Texture ===============
int fullyCompatible = 0; int fullyCompatible = 0;
@ -841,7 +841,7 @@ namespace Ryujinx.Graphics.Gpu.Image
if (texture != null) if (texture != null)
{ {
// This texture could be a view of multiple parent textures with different storages, even if it is a view. // 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) // (even if it could be fulfilled without a copy)
for (int index = 0; index < overlapsCount; index++) for (int index = 0; index < overlapsCount; index++)
@ -859,7 +859,7 @@ namespace Ryujinx.Graphics.Gpu.Image
texture.SynchronizeMemory(); texture.SynchronizeMemory();
} }
// =============== Create a New Texture =============== // =============== Create a New Texture ===============
// No match, create a new texture. // No match, create a new texture.
if (texture == null) if (texture == null)
@ -993,7 +993,7 @@ namespace Ryujinx.Graphics.Gpu.Image
overlap.ReplaceView(texture, overlapInfo, newView, oInfo.FirstLayer, oInfo.FirstLevel); overlap.ReplaceView(texture, overlapInfo, newView, oInfo.FirstLayer, oInfo.FirstLevel);
} }
} }
texture.SynchronizeMemory(); texture.SynchronizeMemory();
} }