diff options
author | gdkchan <gab.dark.100@gmail.com> | 2020-03-29 09:48:39 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-29 23:48:39 +1100 |
commit | b18ef8e3a00980595f45c7fe184dcb160dcc3cb9 (patch) | |
tree | 9d9b3fea4d7822d548878988c12c18e23a72bb52 /Ryujinx.Graphics.OpenGL/TextureView.cs | |
parent | 5c1757f7c29fc06577b5fc551dd3d76b12b281d3 (diff) |
Workaround for AMD and Intel view format bug (#1050)
* Workaround for Intel view format bug
* Dispose of the intermmediate texture aswell
* Apply workaround on AMD aswell
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/TextureView.cs')
-rw-r--r-- | Ryujinx.Graphics.OpenGL/TextureView.cs | 83 |
1 files changed, 59 insertions, 24 deletions
diff --git a/Ryujinx.Graphics.OpenGL/TextureView.cs b/Ryujinx.Graphics.OpenGL/TextureView.cs index 8fa78e5b..cb872880 100644 --- a/Ryujinx.Graphics.OpenGL/TextureView.cs +++ b/Ryujinx.Graphics.OpenGL/TextureView.cs @@ -14,24 +14,19 @@ namespace Ryujinx.Graphics.OpenGL private TextureView _emulatedViewParent; + private TextureView _incompatibleFormatView; + private readonly TextureCreateInfo _info; - private int _firstLayer; - private int _firstLevel; + public int FirstLayer { get; private set; } + public int FirstLevel { get; private set; } - public int Width => _info.Width; - public int Height => _info.Height; - public int DepthOrLayers => _info.GetDepthOrLayers(); - public int Levels => _info.Levels; + public int Width => _info.Width; + public int Height => _info.Height; public Target Target => _info.Target; public Format Format => _info.Format; - public int BlockWidth => _info.BlockWidth; - public int BlockHeight => _info.BlockHeight; - - public bool IsCompressed => _info.IsCompressed; - public TextureView( Renderer renderer, TextureStorage parent, @@ -43,8 +38,8 @@ namespace Ryujinx.Graphics.OpenGL _parent = parent; _info = info; - _firstLayer = firstLayer; - _firstLevel = firstLevel; + FirstLayer = firstLayer; + FirstLevel = firstLevel; Handle = GL.GenTexture(); @@ -73,9 +68,9 @@ namespace Ryujinx.Graphics.OpenGL target, _parent.Handle, pixelInternalFormat, - _firstLevel, + FirstLevel, _info.Levels, - _firstLayer, + FirstLayer, _info.GetLayers()); GL.ActiveTexture(TextureUnit.Texture0); @@ -107,8 +102,8 @@ namespace Ryujinx.Graphics.OpenGL { if (_info.IsCompressed == info.IsCompressed) { - firstLayer += _firstLayer; - firstLevel += _firstLevel; + firstLayer += FirstLayer; + firstLevel += FirstLevel; return _parent.CreateView(info, firstLayer, firstLevel); } @@ -123,26 +118,59 @@ namespace Ryujinx.Graphics.OpenGL emulatedView._emulatedViewParent = this; - emulatedView._firstLayer = firstLayer; - emulatedView._firstLevel = firstLevel; + emulatedView.FirstLayer = firstLayer; + emulatedView.FirstLevel = firstLevel; return emulatedView; } } + public int GetIncompatibleFormatViewHandle() + { + // AMD and Intel has a bug where the view format is always ignored, + // it uses the parent format instead. + // As 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); + } + + TextureCopyUnscaled.Copy(_parent.Info, _incompatibleFormatView._info, _parent.Handle, _incompatibleFormatView.Handle, FirstLayer, 0, FirstLevel, 0); + + return _incompatibleFormatView.Handle; + } + + return Handle; + } + + public void SignalModified() + { + if (_incompatibleFormatView != null) + { + TextureCopyUnscaled.Copy(_incompatibleFormatView._info, _parent.Info, _incompatibleFormatView.Handle, _parent.Handle, 0, FirstLayer, 0, FirstLevel); + } + } + public void CopyTo(ITexture destination, int firstLayer, int firstLevel) { TextureView destinationView = (TextureView)destination; - TextureCopyUnscaled.Copy(this, destinationView, firstLayer, firstLevel); + TextureCopyUnscaled.Copy(_info, destinationView._info, Handle, destinationView.Handle, 0, firstLayer, 0, firstLevel); if (destinationView._emulatedViewParent != null) { TextureCopyUnscaled.Copy( - this, - destinationView._emulatedViewParent, - destinationView._firstLayer, - destinationView._firstLevel); + _info, + destinationView._emulatedViewParent._info, + Handle, + destinationView._emulatedViewParent.Handle, + 0, + destinationView.FirstLayer, + 0, + destinationView.FirstLevel); } } @@ -405,6 +433,13 @@ namespace Ryujinx.Graphics.OpenGL public void Dispose() { + if (_incompatibleFormatView != null) + { + _incompatibleFormatView.Dispose(); + + _incompatibleFormatView = null; + } + if (Handle != 0) { GL.DeleteTexture(Handle); |