aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Texture/OffsetCalculator.cs
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2020-06-13 23:31:06 +0100
committerGitHub <noreply@github.com>2020-06-13 19:31:06 -0300
commitbea1fc2e8d40ec792964852f57e7b884dfbd8306 (patch)
tree8cbbb5bb49d8c1ff635ddd1bb81e58f39a1b7eaf /Ryujinx.Graphics.Texture/OffsetCalculator.cs
parentce983f360b3353bbcd73f3e58c24a23a22e1c94d (diff)
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.
Diffstat (limited to 'Ryujinx.Graphics.Texture/OffsetCalculator.cs')
-rw-r--r--Ryujinx.Graphics.Texture/OffsetCalculator.cs64
1 files changed, 63 insertions, 1 deletions
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