From bea1fc2e8d40ec792964852f57e7b884dfbd8306 Mon Sep 17 00:00:00 2001 From: riperiperi Date: Sat, 13 Jun 2020 23:31:06 +0100 Subject: Optimize texture format conversion, and MethodCopyBuffer (#1274) * Improve performance when converting texture formats. Still more work to do. * Speed up buffer -> texture copies. No longer copies byte by byte. Fast path when formats are identical. * Fix a few things, 64 byte block fast copy. * Spacing cleanup, unrelated change. * Fix base offset calculation for region copies. * Fix Linear -> BlockLinear * Fix some nits. (part 1 of review feedback) * Use a generic version of the Convert* functions rather than lambdas. This is some real monkey's paw shit. * Remove unnecessary span constructor. * Revert "Use a generic version of the Convert* functions rather than lambdas." This reverts commit aa43dcfbe8bba291eea4e10c68569af7a56a5851. * Fix bug with rectangle destination writing, better rectangle calculation for linear textures. --- Ryujinx.Graphics.Texture/OffsetCalculator.cs | 64 +++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) (limited to 'Ryujinx.Graphics.Texture/OffsetCalculator.cs') diff --git a/Ryujinx.Graphics.Texture/OffsetCalculator.cs b/Ryujinx.Graphics.Texture/OffsetCalculator.cs index bb5d606c..1f5d9614 100644 --- a/Ryujinx.Graphics.Texture/OffsetCalculator.cs +++ b/Ryujinx.Graphics.Texture/OffsetCalculator.cs @@ -1,17 +1,22 @@ using Ryujinx.Common; - +using System.Runtime.CompilerServices; using static Ryujinx.Graphics.Texture.BlockLinearConstants; namespace Ryujinx.Graphics.Texture { public class OffsetCalculator { + private int _width; + private int _height; private int _stride; private bool _isLinear; private int _bytesPerPixel; private BlockLinearLayout _layoutConverter; + // Variables for built in iteration. + private int _yPart; + public OffsetCalculator( int width, int height, @@ -20,6 +25,8 @@ namespace Ryujinx.Graphics.Texture int gobBlocksInY, int bytesPerPixel) { + _width = width; + _height = height; _stride = stride; _isLinear = isLinear; _bytesPerPixel = bytesPerPixel; @@ -40,6 +47,18 @@ namespace Ryujinx.Graphics.Texture } } + public void SetY(int y) + { + if (_isLinear) + { + _yPart = y * _stride; + } + else + { + _layoutConverter.SetY(y); + } + } + public int GetOffset(int x, int y) { if (_isLinear) @@ -51,5 +70,48 @@ namespace Ryujinx.Graphics.Texture return _layoutConverter.GetOffset(x, y, 0); } } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int GetOffset(int x) + { + if (_isLinear) + { + return x * _bytesPerPixel + _yPart; + } + else + { + return _layoutConverter.GetOffset(x); + } + } + + public (int offset, int size) GetRectangleRange(int x, int y, int width, int height) + { + if (_isLinear) + { + int start = y * _stride + x * _bytesPerPixel; + int end = (y + height - 1) * _stride + (x + width) * _bytesPerPixel; + return (start, end - start); + } + else + { + return _layoutConverter.GetRectangleRange(x, y, width, height); + } + } + + public bool LayoutMatches(OffsetCalculator other) + { + if (_isLinear) + { + return other._isLinear && + _width == other._width && + _height == other._height && + _stride == other._stride && + _bytesPerPixel == other._bytesPerPixel; + } + else + { + return !other._isLinear && _layoutConverter.LayoutMatches(other._layoutConverter); + } + } } } \ No newline at end of file -- cgit v1.2.3