diff options
| author | riperiperi <rhy3756547@hotmail.com> | 2020-07-07 03:41:07 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-07 04:41:07 +0200 |
| commit | 484eb645ae0611f60fae845ed011ed6115352e06 (patch) | |
| tree | b15972f04dae0b1b6c644cbbbdfcd98856adee15 /Ryujinx.Graphics.OpenGL/Image | |
| parent | 43b78ae157eed5c9436dc19a6d498655891202d8 (diff) | |
Implement Zero-Configuration Resolution Scaling (#1365)
* Initial implementation of Render Target Scaling
Works with most games I have. No GUI option right now, it is hardcoded.
Missing handling for texelFetch operation.
* Realtime Configuration, refactoring.
* texelFetch scaling on fragment shader (WIP)
* Improve Shader-Side changes.
* Fix potential crash when no color/depth bound
* Workaround random uses of textures in compute.
This was blacklisting textures in a few games despite causing no bugs. Will eventually add full support so this doesn't break anything.
* Fix scales oscillating when changing between non-native scales.
* Scaled textures on compute, cleanup, lazier uniform update.
* Cleanup.
* Fix stupidity
* Address Thog Feedback.
* Cover most of GDK's feedback (two comments remain)
* Fix bad rename
* Move IsDepthStencil to FormatExtensions, add docs.
* Fix default config, square texture detection.
* Three final fixes:
- Nearest copy when texture is integer format.
- Texture2D -> Texture3D copy correctly blacklists the texture before trying an unscaled copy (caused driver error)
- Discount small textures.
* Remove scale threshold.
Not needed right now - we'll see if we run into problems.
* All CPU modification blacklists scale.
* Fix comment.
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Image')
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureBase.cs | 11 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs | 8 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureCopyUnscaled.cs | 11 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs | 42 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureView.cs | 15 |
5 files changed, 54 insertions, 33 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs b/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs index a4209ea1..dfb81642 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs @@ -1,5 +1,6 @@ using OpenTK.Graphics.OpenGL; using Ryujinx.Graphics.GAL; +using System; namespace Ryujinx.Graphics.OpenGL.Image { @@ -9,15 +10,19 @@ namespace Ryujinx.Graphics.OpenGL.Image protected TextureCreateInfo Info { get; } - public int Width => Info.Width; - public int Height => Info.Height; + public int Width { get; } + public int Height { get; } + public float ScaleFactor { get; } public Target Target => Info.Target; public Format Format => Info.Format; - public TextureBase(TextureCreateInfo info) + public TextureBase(TextureCreateInfo info, float scaleFactor = 1f) { Info = info; + Width = (int)Math.Ceiling(Info.Width * scaleFactor); + Height = (int)Math.Ceiling(Info.Height * scaleFactor); + ScaleFactor = scaleFactor; Handle = GL.GenTexture(); } diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs b/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs index db9ff41c..e89d5614 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs @@ -33,6 +33,11 @@ namespace Ryujinx.Graphics.OpenGL.Image ClearBufferMask mask = GetMask(src.Format); + if ((mask & (ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit)) != 0 || src.Format.IsInteger()) + { + linearFilter = false; + } + BlitFramebufferFilter filter = linearFilter ? BlitFramebufferFilter.Linear : BlitFramebufferFilter.Nearest; @@ -55,6 +60,9 @@ namespace Ryujinx.Graphics.OpenGL.Image mask, filter); + Attach(FramebufferTarget.ReadFramebuffer, src.Format, 0); + Attach(FramebufferTarget.DrawFramebuffer, dst.Format, 0); + GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle); diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureCopyUnscaled.cs b/Ryujinx.Graphics.OpenGL/Image/TextureCopyUnscaled.cs index 28401138..02ae3b58 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureCopyUnscaled.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureCopyUnscaled.cs @@ -15,15 +15,16 @@ namespace Ryujinx.Graphics.OpenGL.Image int srcLayer, int dstLayer, int srcLevel, - int dstLevel) + int dstLevel, + float scaleFactor = 1f) { - int srcWidth = srcInfo.Width; - int srcHeight = srcInfo.Height; + int srcWidth = (int)Math.Ceiling(srcInfo.Width * scaleFactor); + int srcHeight = (int)Math.Ceiling(srcInfo.Height * scaleFactor); int srcDepth = srcInfo.GetDepthOrLayers(); int srcLevels = srcInfo.Levels; - int dstWidth = dstInfo.Width; - int dstHeight = dstInfo.Height; + int dstWidth = (int)Math.Ceiling(dstInfo.Width * scaleFactor); + int dstHeight = (int)Math.Ceiling(dstInfo.Height * scaleFactor); int dstDepth = dstInfo.GetDepthOrLayers(); int dstLevels = dstInfo.Levels; diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs b/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs index baf8e65d..4fc0a77f 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs @@ -1,12 +1,14 @@ using OpenTK.Graphics.OpenGL; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; +using System; namespace Ryujinx.Graphics.OpenGL.Image { class TextureStorage { public int Handle { get; private set; } + public float ScaleFactor { get; private set; } public TextureCreateInfo Info { get; } @@ -14,12 +16,13 @@ namespace Ryujinx.Graphics.OpenGL.Image private int _viewsCount; - public TextureStorage(Renderer renderer, TextureCreateInfo info) + public TextureStorage(Renderer renderer, TextureCreateInfo info, float scaleFactor) { _renderer = renderer; Info = info; Handle = GL.GenTexture(); + ScaleFactor = scaleFactor; CreateImmutableStorage(); } @@ -32,6 +35,9 @@ namespace Ryujinx.Graphics.OpenGL.Image GL.BindTexture(target, Handle); + int width = (int)Math.Ceiling(Info.Width * ScaleFactor); + int height = (int)Math.Ceiling(Info.Height * ScaleFactor); + FormatInfo format = FormatTable.GetFormatInfo(Info.Format); SizedInternalFormat internalFormat; @@ -52,7 +58,7 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTarget1d.Texture1D, Info.Levels, internalFormat, - Info.Width); + width); break; case Target.Texture1DArray: @@ -60,8 +66,8 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTarget2d.Texture1DArray, Info.Levels, internalFormat, - Info.Width, - Info.Height); + width, + height); break; case Target.Texture2D: @@ -69,8 +75,8 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTarget2d.Texture2D, Info.Levels, internalFormat, - Info.Width, - Info.Height); + width, + height); break; case Target.Texture2DArray: @@ -78,8 +84,8 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTarget3d.Texture2DArray, Info.Levels, internalFormat, - Info.Width, - Info.Height, + width, + height, Info.Depth); break; @@ -88,8 +94,8 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTargetMultisample2d.Texture2DMultisample, Info.Samples, internalFormat, - Info.Width, - Info.Height, + width, + height, true); break; @@ -98,8 +104,8 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTargetMultisample3d.Texture2DMultisampleArray, Info.Samples, internalFormat, - Info.Width, - Info.Height, + width, + height, Info.Depth, true); break; @@ -109,8 +115,8 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTarget3d.Texture3D, Info.Levels, internalFormat, - Info.Width, - Info.Height, + width, + height, Info.Depth); break; @@ -119,8 +125,8 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTarget2d.TextureCubeMap, Info.Levels, internalFormat, - Info.Width, - Info.Height); + width, + height); break; case Target.CubemapArray: @@ -128,8 +134,8 @@ namespace Ryujinx.Graphics.OpenGL.Image (TextureTarget3d)All.TextureCubeMapArray, Info.Levels, internalFormat, - Info.Width, - Info.Height, + width, + height, Info.Depth); break; diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureView.cs b/Ryujinx.Graphics.OpenGL/Image/TextureView.cs index 0b24a296..02353ffa 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureView.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureView.cs @@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureStorage parent, TextureCreateInfo info, int firstLayer, - int firstLevel) : base(info) + int firstLevel) : base(info, parent.ScaleFactor) { _renderer = renderer; _parent = parent; @@ -101,7 +101,7 @@ namespace Ryujinx.Graphics.OpenGL.Image // So we emulate that here with a texture copy (see the first CopyTo overload). // However right now it only does a single copy right after the view is created, // so it doesn't work for all cases. - TextureView emulatedView = (TextureView)_renderer.CreateTexture(info); + TextureView emulatedView = (TextureView)_renderer.CreateTexture(info, ScaleFactor); emulatedView._emulatedViewParent = this; @@ -122,10 +122,10 @@ namespace Ryujinx.Graphics.OpenGL.Image { if (_incompatibleFormatView == null) { - _incompatibleFormatView = (TextureView)_renderer.CreateTexture(Info); + _incompatibleFormatView = (TextureView)_renderer.CreateTexture(Info, ScaleFactor); } - TextureCopyUnscaled.Copy(_parent.Info, _incompatibleFormatView.Info, _parent.Handle, _incompatibleFormatView.Handle, FirstLayer, 0, FirstLevel, 0); + TextureCopyUnscaled.Copy(_parent.Info, _incompatibleFormatView.Info, _parent.Handle, _incompatibleFormatView.Handle, FirstLayer, 0, FirstLevel, 0, ScaleFactor); return _incompatibleFormatView.Handle; } @@ -137,7 +137,7 @@ namespace Ryujinx.Graphics.OpenGL.Image { if (_incompatibleFormatView != null) { - TextureCopyUnscaled.Copy(_incompatibleFormatView.Info, _parent.Info, _incompatibleFormatView.Handle, _parent.Handle, 0, FirstLayer, 0, FirstLevel); + TextureCopyUnscaled.Copy(_incompatibleFormatView.Info, _parent.Info, _incompatibleFormatView.Handle, _parent.Handle, 0, FirstLayer, 0, FirstLevel, ScaleFactor); } } @@ -145,7 +145,7 @@ namespace Ryujinx.Graphics.OpenGL.Image { TextureView destinationView = (TextureView)destination; - TextureCopyUnscaled.Copy(Info, destinationView.Info, Handle, destinationView.Handle, 0, firstLayer, 0, firstLevel); + TextureCopyUnscaled.Copy(Info, destinationView.Info, Handle, destinationView.Handle, 0, firstLayer, 0, firstLevel, ScaleFactor); if (destinationView._emulatedViewParent != null) { @@ -157,7 +157,8 @@ namespace Ryujinx.Graphics.OpenGL.Image 0, destinationView.FirstLayer, 0, - destinationView.FirstLevel); + destinationView.FirstLevel, + ScaleFactor); } } |
