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
This commit is contained in:
parent
5c1757f7c2
commit
b18ef8e3a0
7 changed files with 222 additions and 119 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue