From 423da5cc911bf7545746ad4fd184eff42f32dd9b Mon Sep 17 00:00:00 2001 From: gdkchan Date: Thu, 29 Oct 2020 18:57:34 -0300 Subject: [PATCH] Scale texture resolution before sending to backend (#1646) * Work * Propagate scale factor to copy temp. Not really needed, just here for consistency * PR feedback --- Ryujinx.Graphics.Gpu/Image/Texture.cs | 18 ++++----- Ryujinx.Graphics.Gpu/Image/TextureManager.cs | 15 ++++++-- Ryujinx.Graphics.OpenGL/Image/TextureBase.cs | 7 +--- Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs | 2 +- .../Image/TextureCopyUnscaled.cs | 11 +++--- .../Image/TextureStorage.cs | 37 +++++++++---------- Ryujinx.Graphics.OpenGL/Image/TextureView.cs | 9 ++--- 7 files changed, 47 insertions(+), 52 deletions(-) diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs index 2b1aaa0ad..016106294 100644 --- a/Ryujinx.Graphics.Gpu/Image/Texture.cs +++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs @@ -181,7 +181,7 @@ namespace Ryujinx.Graphics.Gpu.Image { Debug.Assert(!isView); - TextureCreateInfo createInfo = TextureManager.GetCreateInfo(Info, _context.Capabilities); + TextureCreateInfo createInfo = TextureManager.GetCreateInfo(Info, _context.Capabilities, ScaleFactor); HostTexture = _context.Renderer.CreateTexture(createInfo, ScaleFactor); SynchronizeMemory(); // Load the data. @@ -204,7 +204,7 @@ namespace Ryujinx.Graphics.Gpu.Image ScaleFactor = GraphicsConfig.ResScale; } - TextureCreateInfo createInfo = TextureManager.GetCreateInfo(Info, _context.Capabilities); + TextureCreateInfo createInfo = TextureManager.GetCreateInfo(Info, _context.Capabilities, ScaleFactor); HostTexture = _context.Renderer.CreateTexture(createInfo, ScaleFactor); } } @@ -232,8 +232,7 @@ namespace Ryujinx.Graphics.Gpu.Image ScaleFactor, ScaleMode); - TextureCreateInfo createInfo = TextureManager.GetCreateInfo(info, _context.Capabilities); - + TextureCreateInfo createInfo = TextureManager.GetCreateInfo(info, _context.Capabilities, ScaleFactor); texture.HostTexture = HostTexture.CreateView(createInfo, firstLayer, firstLevel); _viewStorage.AddView(texture); @@ -375,7 +374,7 @@ namespace Ryujinx.Graphics.Gpu.Image Info.SwizzleB, Info.SwizzleA)); - TextureCreateInfo createInfo = TextureManager.GetCreateInfo(Info, _context.Capabilities); + TextureCreateInfo createInfo = TextureManager.GetCreateInfo(Info, _context.Capabilities, ScaleFactor); if (_viewStorage != this) { @@ -451,7 +450,7 @@ namespace Ryujinx.Graphics.Gpu.Image Info.SwizzleB, Info.SwizzleA); - TextureCreateInfo createInfo = TextureManager.GetCreateInfo(viewInfo, _context.Capabilities); + TextureCreateInfo createInfo = TextureManager.GetCreateInfo(viewInfo, _context.Capabilities, ScaleFactor); for (int i = 0; i < Info.DepthOrLayers; i++) { @@ -475,8 +474,7 @@ namespace Ryujinx.Graphics.Gpu.Image { if (storage == null) { - TextureCreateInfo createInfo = TextureManager.GetCreateInfo(Info, _context.Capabilities); - + TextureCreateInfo createInfo = TextureManager.GetCreateInfo(Info, _context.Capabilities, scale); storage = _context.Renderer.CreateTexture(createInfo, scale); } @@ -530,12 +528,10 @@ namespace Ryujinx.Graphics.Gpu.Image Logger.Debug?.Print(LogClass.Gpu, $" Recreating view {Info.Width}x{Info.Height} {Info.FormatInfo.Format.ToString()}."); view.ScaleFactor = scale; - TextureCreateInfo viewCreateInfo = TextureManager.GetCreateInfo(view.Info, _context.Capabilities); - + TextureCreateInfo viewCreateInfo = TextureManager.GetCreateInfo(view.Info, _context.Capabilities, scale); ITexture newView = HostTexture.CreateView(viewCreateInfo, view._firstLayer - _firstLayer, view._firstLevel - _firstLevel); view.ReplaceStorage(newView); - view.ScaleMode = newScaleMode; } } diff --git a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs index 27292f56c..b0e715ea4 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs @@ -754,7 +754,7 @@ namespace Ryujinx.Graphics.Gpu.Image } break; - } + } else if (overlapCompatibility == TextureViewCompatibility.CopyOnly) { // TODO: Copy rules for targets created after the container texture. See below. @@ -833,7 +833,7 @@ namespace Ryujinx.Graphics.Gpu.Image TextureInfo overlapInfo = AdjustSizes(texture, overlap.Info, oInfo.FirstLevel); - TextureCreateInfo createInfo = GetCreateInfo(overlapInfo, _context.Capabilities); + TextureCreateInfo createInfo = GetCreateInfo(overlapInfo, _context.Capabilities, overlap.ScaleFactor); if (texture.ScaleFactor != overlap.ScaleFactor) { @@ -944,7 +944,7 @@ namespace Ryujinx.Graphics.Gpu.Image } else { - // Bpp may be a mismatch between the target texture and the param. + // Bpp may be a mismatch between the target texture and the param. // Due to the way linear strided and block layouts work, widths can be multiplied by Bpp for comparison. // Note: tex.Width is the aligned texture size. Prefer param.XCount, as the destination should be a texture with that exact size. @@ -1054,8 +1054,9 @@ namespace Ryujinx.Graphics.Gpu.Image /// /// Texture information /// GPU capabilities + /// Texture scale factor, to be applied to the texture size /// The texture creation information - public static TextureCreateInfo GetCreateInfo(TextureInfo info, Capabilities caps) + public static TextureCreateInfo GetCreateInfo(TextureInfo info, Capabilities caps, float scale) { FormatInfo formatInfo = info.FormatInfo; @@ -1092,6 +1093,12 @@ namespace Ryujinx.Graphics.Gpu.Image int depth = info.GetDepth() * info.GetLayers(); + if (scale != 1f) + { + width = (int)MathF.Ceiling(width * scale); + height = (int)MathF.Ceiling(height * scale); + } + return new TextureCreateInfo( width, height, diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs b/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs index 5f786decc..2e70fa82a 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs @@ -1,6 +1,5 @@ using OpenTK.Graphics.OpenGL; using Ryujinx.Graphics.GAL; -using System; namespace Ryujinx.Graphics.OpenGL.Image { @@ -10,8 +9,8 @@ namespace Ryujinx.Graphics.OpenGL.Image public TextureCreateInfo Info { get; } - public int Width { get; } - public int Height { get; } + public int Width => Info.Width; + public int Height => Info.Height; public float ScaleFactor { get; } public Target Target => Info.Target; @@ -20,8 +19,6 @@ namespace Ryujinx.Graphics.OpenGL.Image 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 edfbec5f8..191e9b634 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs @@ -129,7 +129,7 @@ namespace Ryujinx.Graphics.OpenGL.Image public TextureView BgraSwap(TextureView from) { - TextureView to = (TextureView)_renderer.CreateTexture(from.Info, 1f); + TextureView to = (TextureView)_renderer.CreateTexture(from.Info, from.ScaleFactor); EnsurePbo(from); diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureCopyUnscaled.cs b/Ryujinx.Graphics.OpenGL/Image/TextureCopyUnscaled.cs index 02ae3b581..284011385 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureCopyUnscaled.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureCopyUnscaled.cs @@ -15,16 +15,15 @@ namespace Ryujinx.Graphics.OpenGL.Image int srcLayer, int dstLayer, int srcLevel, - int dstLevel, - float scaleFactor = 1f) + int dstLevel) { - int srcWidth = (int)Math.Ceiling(srcInfo.Width * scaleFactor); - int srcHeight = (int)Math.Ceiling(srcInfo.Height * scaleFactor); + int srcWidth = srcInfo.Width; + int srcHeight = srcInfo.Height; int srcDepth = srcInfo.GetDepthOrLayers(); int srcLevels = srcInfo.Levels; - int dstWidth = (int)Math.Ceiling(dstInfo.Width * scaleFactor); - int dstHeight = (int)Math.Ceiling(dstInfo.Height * scaleFactor); + int dstWidth = dstInfo.Width; + int dstHeight = dstInfo.Height; 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 635b6c2ce..b34b02bf7 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs @@ -37,9 +37,6 @@ 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; @@ -60,7 +57,7 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTarget1d.Texture1D, Info.Levels, internalFormat, - width); + Info.Width); break; case Target.Texture1DArray: @@ -68,8 +65,8 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTarget2d.Texture1DArray, Info.Levels, internalFormat, - width, - height); + Info.Width, + Info.Height); break; case Target.Texture2D: @@ -77,8 +74,8 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTarget2d.Texture2D, Info.Levels, internalFormat, - width, - height); + Info.Width, + Info.Height); break; case Target.Texture2DArray: @@ -86,8 +83,8 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTarget3d.Texture2DArray, Info.Levels, internalFormat, - width, - height, + Info.Width, + Info.Height, Info.Depth); break; @@ -96,8 +93,8 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTargetMultisample2d.Texture2DMultisample, Info.Samples, internalFormat, - width, - height, + Info.Width, + Info.Height, true); break; @@ -106,8 +103,8 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTargetMultisample3d.Texture2DMultisampleArray, Info.Samples, internalFormat, - width, - height, + Info.Width, + Info.Height, Info.Depth, true); break; @@ -117,8 +114,8 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTarget3d.Texture3D, Info.Levels, internalFormat, - width, - height, + Info.Width, + Info.Height, Info.Depth); break; @@ -127,8 +124,8 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureTarget2d.TextureCubeMap, Info.Levels, internalFormat, - width, - height); + Info.Width, + Info.Height); break; case Target.CubemapArray: @@ -136,8 +133,8 @@ namespace Ryujinx.Graphics.OpenGL.Image (TextureTarget3d)All.TextureCubeMapArray, Info.Levels, internalFormat, - width, - height, + Info.Width, + Info.Height, Info.Depth); break; diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureView.cs b/Ryujinx.Graphics.OpenGL/Image/TextureView.cs index 04cadae73..449c18d4b 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureView.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureView.cs @@ -134,7 +134,7 @@ namespace Ryujinx.Graphics.OpenGL.Image _incompatibleFormatView = (TextureView)_renderer.CreateTexture(Info, ScaleFactor); } - TextureCopyUnscaled.Copy(_parent.Info, _incompatibleFormatView.Info, _parent.Handle, _incompatibleFormatView.Handle, FirstLayer, 0, FirstLevel, 0, ScaleFactor); + TextureCopyUnscaled.Copy(_parent.Info, _incompatibleFormatView.Info, _parent.Handle, _incompatibleFormatView.Handle, FirstLayer, 0, FirstLevel, 0); return _incompatibleFormatView.Handle; } @@ -146,7 +146,7 @@ namespace Ryujinx.Graphics.OpenGL.Image { if (_incompatibleFormatView != null) { - TextureCopyUnscaled.Copy(_incompatibleFormatView.Info, _parent.Info, _incompatibleFormatView.Handle, _parent.Handle, 0, FirstLayer, 0, FirstLevel, ScaleFactor); + TextureCopyUnscaled.Copy(_incompatibleFormatView.Info, _parent.Info, _incompatibleFormatView.Handle, _parent.Handle, 0, FirstLayer, 0, FirstLevel); } } @@ -154,7 +154,7 @@ namespace Ryujinx.Graphics.OpenGL.Image { TextureView destinationView = (TextureView)destination; - TextureCopyUnscaled.Copy(Info, destinationView.Info, Handle, destinationView.Handle, 0, firstLayer, 0, firstLevel, ScaleFactor); + TextureCopyUnscaled.Copy(Info, destinationView.Info, Handle, destinationView.Handle, 0, firstLayer, 0, firstLevel); if (destinationView._emulatedViewParent != null) { @@ -166,8 +166,7 @@ namespace Ryujinx.Graphics.OpenGL.Image 0, destinationView.FirstLayer, 0, - destinationView.FirstLevel, - ScaleFactor); + destinationView.FirstLevel); } }