From 212e472c9fac8253456d710e0b071579da330c0a Mon Sep 17 00:00:00 2001
From: riperiperi <rhy3756547@hotmail.com>
Date: Sun, 16 May 2021 19:43:27 +0100
Subject: [PATCH] Use copy dependencies for the Intel/AMD view format
 workaround (#2144)

* This might help AMD a bit

* Removal of old workaround.
---
 Ryujinx.Graphics.GAL/Capabilities.cs         |  3 ++
 Ryujinx.Graphics.Gpu/Image/Texture.cs        |  9 +++++
 Ryujinx.Graphics.OpenGL/Framebuffer.cs       | 25 +------------
 Ryujinx.Graphics.OpenGL/HwCapabilities.cs    |  1 +
 Ryujinx.Graphics.OpenGL/Image/TextureView.cs | 38 --------------------
 Ryujinx.Graphics.OpenGL/Pipeline.cs          |  6 ----
 Ryujinx.Graphics.OpenGL/Renderer.cs          |  1 +
 7 files changed, 15 insertions(+), 68 deletions(-)

diff --git a/Ryujinx.Graphics.GAL/Capabilities.cs b/Ryujinx.Graphics.GAL/Capabilities.cs
index d496de67..e388f0e5 100644
--- a/Ryujinx.Graphics.GAL/Capabilities.cs
+++ b/Ryujinx.Graphics.GAL/Capabilities.cs
@@ -5,6 +5,7 @@ namespace Ryujinx.Graphics.GAL
         public bool SupportsAstcCompression          { get; }
         public bool SupportsImageLoadFormatted       { get; }
         public bool SupportsNonConstantTextureOffset { get; }
+        public bool SupportsMismatchingViewFormat    { get; }
         public bool SupportsViewportSwizzle          { get; }
 
         public int   MaximumComputeSharedMemorySize { get; }
@@ -15,6 +16,7 @@ namespace Ryujinx.Graphics.GAL
             bool  supportsAstcCompression,
             bool  supportsImageLoadFormatted,
             bool  supportsNonConstantTextureOffset,
+            bool  supportsMismatchingViewFormat,
             bool  supportsViewportSwizzle,
             int   maximumComputeSharedMemorySize,
             float maximumSupportedAnisotropy,
@@ -23,6 +25,7 @@ namespace Ryujinx.Graphics.GAL
             SupportsAstcCompression          = supportsAstcCompression;
             SupportsImageLoadFormatted       = supportsImageLoadFormatted;
             SupportsNonConstantTextureOffset = supportsNonConstantTextureOffset;
+            SupportsMismatchingViewFormat    = supportsMismatchingViewFormat;
             SupportsViewportSwizzle          = supportsViewportSwizzle;
             MaximumComputeSharedMemorySize   = maximumComputeSharedMemorySize;
             MaximumSupportedAnisotropy       = maximumSupportedAnisotropy;
diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs
index 6d2510f1..4d7e31c5 100644
--- a/Ryujinx.Graphics.Gpu/Image/Texture.cs
+++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs
@@ -1014,6 +1014,15 @@ namespace Ryujinx.Graphics.Gpu.Image
             result = TextureCompatibility.PropagateViewCompatibility(result, TextureCompatibility.ViewTargetCompatible(Info, info));
             result = TextureCompatibility.PropagateViewCompatibility(result, TextureCompatibility.ViewSubImagesInBounds(Info, info, firstLayer, firstLevel));
 
+            if (result == TextureViewCompatibility.Full && Info.FormatInfo.Format != info.FormatInfo.Format && !_context.Capabilities.SupportsMismatchingViewFormat)
+            {
+                // AMD and Intel have a bug where the view format is always ignored;
+                // they use the parent format instead.
+                // Create a copy dependency to avoid this issue.
+
+                result = TextureViewCompatibility.CopyOnly;
+            }
+
             return (Info.SamplesInX == info.SamplesInX &&
                     Info.SamplesInY == info.SamplesInY) ? result : TextureViewCompatibility.Incompatible;
         }
diff --git a/Ryujinx.Graphics.OpenGL/Framebuffer.cs b/Ryujinx.Graphics.OpenGL/Framebuffer.cs
index e6b70376..76b321b7 100644
--- a/Ryujinx.Graphics.OpenGL/Framebuffer.cs
+++ b/Ryujinx.Graphics.OpenGL/Framebuffer.cs
@@ -40,15 +40,7 @@ namespace Ryujinx.Graphics.OpenGL
 
             FramebufferAttachment attachment = FramebufferAttachment.ColorAttachment0 + index;
 
-            if (HwCapabilities.Vendor == HwCapabilities.GpuVendor.Amd ||
-                HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows)
-            {
-                GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.GetIncompatibleFormatViewHandle() ?? 0, 0);
-            }
-            else
-            {
-                GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.Handle ?? 0, 0);
-            }
+            GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.Handle ?? 0, 0);
 
             _colors[index] = color;
         }
@@ -92,21 +84,6 @@ namespace Ryujinx.Graphics.OpenGL
             }
         }
 
-        public void SignalModified()
-        {
-            if (HwCapabilities.Vendor == HwCapabilities.GpuVendor.Amd ||
-                HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows)
-            {
-                for (int i = 0; i < 8; i++)
-                {
-                    if (_colors[i] != null)
-                    {
-                        _colors[i].SignalModified();
-                    }
-                }
-            }
-        }
-
         public void SetDualSourceBlend(bool enable)
         {
             bool oldEnable = _dualSourceBlend;
diff --git a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
index 6795b423..7c2acacd 100644
--- a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
+++ b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
@@ -36,6 +36,7 @@ namespace Ryujinx.Graphics.OpenGL
         public static bool SupportsSeamlessCubemapPerTexture => _supportsSeamlessCubemapPerTexture.Value;
         public static bool SupportsNonConstantTextureOffset  => _gpuVendor.Value == GpuVendor.Nvidia;
         public static bool RequiresSyncFlush                 => _gpuVendor.Value == GpuVendor.Amd || _gpuVendor.Value == GpuVendor.IntelWindows || _gpuVendor.Value == GpuVendor.IntelUnix;
+        public static bool SupportsMismatchingViewFormat     => _gpuVendor.Value != GpuVendor.Amd && _gpuVendor.Value != GpuVendor.IntelWindows;
 
         public static int MaximumComputeSharedMemorySize => _maximumComputeSharedMemorySize.Value;
         public static int StorageBufferOffsetAlignment   => _storageBufferOffsetAlignment.Value;
diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureView.cs b/Ryujinx.Graphics.OpenGL/Image/TextureView.cs
index e8c3e3be..8e8d3c78 100644
--- a/Ryujinx.Graphics.OpenGL/Image/TextureView.cs
+++ b/Ryujinx.Graphics.OpenGL/Image/TextureView.cs
@@ -10,8 +10,6 @@ namespace Ryujinx.Graphics.OpenGL.Image
 
         private readonly TextureStorage _parent;
 
-        private TextureView _incompatibleFormatView;
-
         public ITextureInfo Storage => _parent;
 
         public int FirstLayer { get; private set; }
@@ -102,35 +100,6 @@ namespace Ryujinx.Graphics.OpenGL.Image
             return _parent.CreateView(info, firstLayer, firstLevel);
         }
 
-        public int GetIncompatibleFormatViewHandle()
-        {
-            // AMD and Intel have a bug where the view format is always ignored;
-            // they use the parent format instead.
-            // As a workaround we create a new texture with the correct
-            // format, and then do a copy after the draw.
-            if (_parent.Info.Format != Format)
-            {
-                if (_incompatibleFormatView == null)
-                {
-                    _incompatibleFormatView = (TextureView)_renderer.CreateTexture(Info, ScaleFactor);
-                }
-
-                _renderer.TextureCopy.CopyUnscaled(_parent, _incompatibleFormatView, FirstLayer, 0, FirstLevel, 0);
-
-                return _incompatibleFormatView.Handle;
-            }
-
-            return Handle;
-        }
-
-        public void SignalModified()
-        {
-            if (_incompatibleFormatView != null)
-            {
-                _renderer.TextureCopy.CopyUnscaled(_incompatibleFormatView, _parent, 0, FirstLayer, 0, FirstLevel);
-            }
-        }
-
         public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
         {
             TextureView destinationView = (TextureView)destination;
@@ -634,13 +603,6 @@ namespace Ryujinx.Graphics.OpenGL.Image
 
         private void DisposeHandles()
         {
-            if (_incompatibleFormatView != null)
-            {
-                _incompatibleFormatView.Dispose();
-
-                _incompatibleFormatView = null;
-            }
-
             if (Handle != 0)
             {
                 GL.DeleteTexture(Handle);
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs
index 28478a72..fcb0fdf1 100644
--- a/Ryujinx.Graphics.OpenGL/Pipeline.cs
+++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs
@@ -110,8 +110,6 @@ namespace Ryujinx.Graphics.OpenGL
             GL.ClearBuffer(OpenTK.Graphics.OpenGL.ClearBuffer.Color, index, colors);
 
             RestoreComponentMask(index);
-
-            _framebuffer.SignalModified();
         }
 
         public void ClearRenderTargetDepthStencil(float depthValue, bool depthMask, int stencilValue, int stencilMask)
@@ -154,8 +152,6 @@ namespace Ryujinx.Graphics.OpenGL
             {
                 GL.DepthMask(_depthMask);
             }
-
-            _framebuffer.SignalModified();
         }
 
         public void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size)
@@ -1224,8 +1220,6 @@ namespace Ryujinx.Graphics.OpenGL
 
         private void PostDraw()
         {
-            _framebuffer?.SignalModified();
-
             if (_tfEnabled)
             {
                 for (int i = 0; i < Constants.MaxTransformFeedbackBuffers; i++)
diff --git a/Ryujinx.Graphics.OpenGL/Renderer.cs b/Ryujinx.Graphics.OpenGL/Renderer.cs
index cc8fa195..b909f792 100644
--- a/Ryujinx.Graphics.OpenGL/Renderer.cs
+++ b/Ryujinx.Graphics.OpenGL/Renderer.cs
@@ -97,6 +97,7 @@ namespace Ryujinx.Graphics.OpenGL
                 HwCapabilities.SupportsAstcCompression,
                 HwCapabilities.SupportsImageLoadFormatted,
                 HwCapabilities.SupportsNonConstantTextureOffset,
+                HwCapabilities.SupportsMismatchingViewFormat,
                 HwCapabilities.SupportsViewportSwizzle,
                 HwCapabilities.MaximumComputeSharedMemorySize,
                 HwCapabilities.MaximumSupportedAnisotropy,