aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL/TextureView.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-03-29 09:48:39 -0300
committerGitHub <noreply@github.com>2020-03-29 23:48:39 +1100
commitb18ef8e3a00980595f45c7fe184dcb160dcc3cb9 (patch)
tree9d9b3fea4d7822d548878988c12c18e23a72bb52 /Ryujinx.Graphics.OpenGL/TextureView.cs
parent5c1757f7c29fc06577b5fc551dd3d76b12b281d3 (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.cs83
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);