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,