Speed up buffer -> texture copies.

No longer copies byte by byte. Fast path when formats are identical.
This commit is contained in:
riperiperi
2020-05-22 00:17:25 +01:00
parent fc2d5086e7
commit 8a7e25de71
5 changed files with 147 additions and 21 deletions

View File

@@ -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,55 @@ 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);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetOffsetWithLineOffset(int x)
{
if (_isLinear)
{
return x + _yPart;
}
else
{
return _layoutConverter.GetOffsetWithLineOffset(x);
}
}
public (int offset, int size) GetRectangleRange(int x, int y, int width, int height)
{
if (_isLinear)
{
return (y * _stride + x, height * _stride);
}
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);
}
}
}
}