From e7c2dc8ec3329d50a52c36efeb31019850ce6015 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 19 Dec 2021 11:50:44 -0300 Subject: [PATCH] Fix for texture pool not being updated when it should + buffer texture related fixes (#2911) --- .../Engine/Threed/ThreedClass.cs | 20 +++++ .../Engine/Threed/ThreedClassState.cs | 5 +- .../Image/TextureBindingsManager.cs | 77 ++++++++++--------- .../Image/TextureBuffer.cs | 1 + 4 files changed, 66 insertions(+), 37 deletions(-) diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs index f3061c73..dc458026 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs @@ -34,6 +34,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed { nameof(ThreedClassState.LaunchDma), new RwCallback(LaunchDma, null) }, { nameof(ThreedClassState.LoadInlineData), new RwCallback(LoadInlineData, null) }, { nameof(ThreedClassState.SyncpointAction), new RwCallback(IncrementSyncpoint, null) }, + { nameof(ThreedClassState.InvalidateSamplerCacheNoWfi), new RwCallback(InvalidateSamplerCacheNoWfi, null) }, + { nameof(ThreedClassState.InvalidateTextureHeaderCacheNoWfi), new RwCallback(InvalidateTextureHeaderCacheNoWfi, null) }, { nameof(ThreedClassState.TextureBarrier), new RwCallback(TextureBarrier, null) }, { nameof(ThreedClassState.TextureBarrierTiled), new RwCallback(TextureBarrierTiled, null) }, { nameof(ThreedClassState.DrawTextureSrcY), new RwCallback(DrawTexture, null) }, @@ -227,6 +229,24 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _context.Synchronization.IncrementSyncpoint(syncpointId); } + /// + /// Invalidates the cache with the sampler descriptors from the sampler pool. + /// + /// Method call argument (unused) + private void InvalidateSamplerCacheNoWfi(int argument) + { + _context.AdvanceSequence(); + } + + /// + /// Invalidates the cache with the texture descriptors from the texture pool. + /// + /// Method call argument (unused) + private void InvalidateTextureHeaderCacheNoWfi(int argument) + { + _context.AdvanceSequence(); + } + /// /// Issues a texture barrier. /// This waits until previous texture writes from the GPU to finish, before diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs index 165f5072..9d8ad765 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs @@ -784,7 +784,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed public YControl YControl; public float LineWidthSmooth; public float LineWidthAliased; - public fixed uint Reserved13B8[31]; + public fixed uint Reserved13B8[27]; + public uint InvalidateSamplerCacheNoWfi; + public uint InvalidateTextureHeaderCacheNoWfi; + public fixed uint Reserved142C[2]; public uint FirstVertex; public uint FirstInstance; public fixed uint Reserved143C[53]; diff --git a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs index e7561f7d..dea918cd 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs @@ -377,18 +377,6 @@ namespace Ryujinx.Graphics.Gpu.Image ITexture hostTexture = texture?.GetTargetTexture(bindingInfo.Target); - if (_textureState[stageIndex][index].Texture != hostTexture || _rebind) - { - if (UpdateScale(texture, bindingInfo, index, stage)) - { - hostTexture = texture?.GetTargetTexture(bindingInfo.Target); - } - - _textureState[stageIndex][index].Texture = hostTexture; - - _context.Renderer.Pipeline.SetTexture(bindingInfo.Binding, hostTexture); - } - if (hostTexture != null && texture.Target == Target.TextureBuffer) { // Ensure that the buffer texture is using the correct buffer as storage. @@ -396,16 +384,30 @@ namespace Ryujinx.Graphics.Gpu.Image // to ensure we're not using a old buffer that was already deleted. _channel.BufferManager.SetBufferTextureStorage(hostTexture, texture.Range.GetSubRange(0).Address, texture.Size, bindingInfo, bindingInfo.Format, false); } - - Sampler sampler = samplerPool?.Get(samplerId); - - ISampler hostSampler = sampler?.GetHostSampler(texture); - - if (_textureState[stageIndex][index].Sampler != hostSampler || _rebind) + else { - _textureState[stageIndex][index].Sampler = hostSampler; + if (_textureState[stageIndex][index].Texture != hostTexture || _rebind) + { + if (UpdateScale(texture, bindingInfo, index, stage)) + { + hostTexture = texture?.GetTargetTexture(bindingInfo.Target); + } - _context.Renderer.Pipeline.SetSampler(bindingInfo.Binding, hostSampler); + _textureState[stageIndex][index].Texture = hostTexture; + + _context.Renderer.Pipeline.SetTexture(bindingInfo.Binding, hostTexture); + } + + Sampler sampler = samplerPool?.Get(samplerId); + + ISampler hostSampler = sampler?.GetHostSampler(texture); + + if (_textureState[stageIndex][index].Sampler != hostSampler || _rebind) + { + _textureState[stageIndex][index].Sampler = hostSampler; + + _context.Renderer.Pipeline.SetSampler(bindingInfo.Binding, hostSampler); + } } } } @@ -464,28 +466,31 @@ namespace Ryujinx.Graphics.Gpu.Image _channel.BufferManager.SetBufferTextureStorage(hostTexture, texture.Range.GetSubRange(0).Address, texture.Size, bindingInfo, format, true); } - else if (isStore) + else { - texture?.SignalModified(); - } - - if (_imageState[stageIndex][index].Texture != hostTexture || _rebind) - { - if (UpdateScale(texture, bindingInfo, baseScaleIndex + index, stage)) + if (isStore) { - hostTexture = texture?.GetTargetTexture(bindingInfo.Target); + texture?.SignalModified(); } - _imageState[stageIndex][index].Texture = hostTexture; - - Format format = bindingInfo.Format; - - if (format == 0 && texture != null) + if (_imageState[stageIndex][index].Texture != hostTexture || _rebind) { - format = texture.Format; - } + if (UpdateScale(texture, bindingInfo, baseScaleIndex + index, stage)) + { + hostTexture = texture?.GetTargetTexture(bindingInfo.Target); + } - _context.Renderer.Pipeline.SetImage(bindingInfo.Binding, hostTexture, format); + _imageState[stageIndex][index].Texture = hostTexture; + + Format format = bindingInfo.Format; + + if (format == 0 && texture != null) + { + format = texture.Format; + } + + _context.Renderer.Pipeline.SetImage(bindingInfo.Binding, hostTexture, format); + } } } } diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs b/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs index 8d407ccb..899deedf 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs @@ -56,6 +56,7 @@ namespace Ryujinx.Graphics.OpenGL.Image public void SetStorage(BufferRange buffer) { if (_buffer != BufferHandle.Null && + _buffer == buffer.Handle && buffer.Offset == _bufferOffset && buffer.Size == _bufferSize && _renderer.BufferCount == _bufferCount)