mirror of
https://github.com/GreemDev/Ryujinx.git
synced 2024-12-22 22:45:46 +00:00
Account for negative strides on DMA copy (#2623)
* Account for negative strides on DMA copy * Should account for non-zero Y
This commit is contained in:
parent
016fc64b3d
commit
ac4ec1a015
4 changed files with 27 additions and 11 deletions
|
@ -76,6 +76,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||
{
|
||||
if (linear)
|
||||
{
|
||||
// If the stride is negative, the texture has to be flipped, so
|
||||
// the fast copy is not trivial, use the slow path.
|
||||
if (stride <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int alignWidth = Constants.StrideAlignment / bpp;
|
||||
return tex.RegionX == 0 &&
|
||||
tex.RegionY == 0 &&
|
||||
|
@ -155,8 +162,18 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||
(int srcBaseOffset, int srcSize) = srcCalculator.GetRectangleRange(src.RegionX, src.RegionY, xCount, yCount);
|
||||
(int dstBaseOffset, int dstSize) = dstCalculator.GetRectangleRange(dst.RegionX, dst.RegionY, xCount, yCount);
|
||||
|
||||
ReadOnlySpan<byte> srcSpan = memoryManager.GetSpan(srcGpuVa + (uint)srcBaseOffset, srcSize, true);
|
||||
Span<byte> dstSpan = memoryManager.GetSpan(dstGpuVa + (uint)dstBaseOffset, dstSize).ToArray();
|
||||
if (srcLinear && srcStride < 0)
|
||||
{
|
||||
srcBaseOffset += srcStride * (yCount - 1);
|
||||
}
|
||||
|
||||
if (dstLinear && dstStride < 0)
|
||||
{
|
||||
dstBaseOffset += dstStride * (yCount - 1);
|
||||
}
|
||||
|
||||
ReadOnlySpan<byte> srcSpan = memoryManager.GetSpan(srcGpuVa + (ulong)srcBaseOffset, srcSize, true);
|
||||
Span<byte> dstSpan = memoryManager.GetSpan(dstGpuVa + (ulong)dstBaseOffset, dstSize).ToArray();
|
||||
|
||||
bool completeSource = IsTextureCopyComplete(src, srcLinear, srcBpp, srcStride, xCount, yCount);
|
||||
bool completeDest = IsTextureCopyComplete(dst, dstLinear, dstBpp, dstStride, xCount, yCount);
|
||||
|
@ -214,7 +231,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||
{
|
||||
srcSpan.CopyTo(dstSpan); // No layout conversion has to be performed, just copy the data entirely.
|
||||
|
||||
memoryManager.Write(dstGpuVa + (uint)dstBaseOffset, dstSpan);
|
||||
memoryManager.Write(dstGpuVa + (ulong)dstBaseOffset, dstSpan);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -255,7 +272,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
|||
_ => throw new NotSupportedException($"Unable to copy ${srcBpp} bpp pixel format.")
|
||||
};
|
||||
|
||||
memoryManager.Write(dstGpuVa + (uint)dstBaseOffset, dstSpan);
|
||||
memoryManager.Write(dstGpuVa + (ulong)dstBaseOffset, dstSpan);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -110,10 +110,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
|||
|
||||
ulong dstGpuVa = ((ulong)state.OffsetOutUpperValue << 32) | state.OffsetOut;
|
||||
|
||||
ulong dstBaseAddress = _channel.MemoryManager.Translate(dstGpuVa);
|
||||
|
||||
// Trigger read tracking, to flush any managed resources in the destination region.
|
||||
_channel.MemoryManager.Physical.GetSpan(dstBaseAddress, _size, true);
|
||||
_channel.MemoryManager.GetSpan(dstGpuVa, _size, true);
|
||||
|
||||
_dstGpuVa = dstGpuVa;
|
||||
_dstX = state.SetDstOriginBytesXV;
|
||||
|
|
|
@ -892,7 +892,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
{
|
||||
_physicalMemory.Write(Range, GetTextureDataFromGpu(Span<byte>.Empty, true, texture));
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
_physicalMemory.WriteUntracked(Range, GetTextureDataFromGpu(Span<byte>.Empty, false, texture));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Ryujinx.Common;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using static Ryujinx.Graphics.Texture.BlockLinearConstants;
|
||||
|
||||
|
@ -111,9 +112,9 @@ namespace Ryujinx.Graphics.Texture
|
|||
{
|
||||
if (_isLinear)
|
||||
{
|
||||
int start = y * _stride + x * _bytesPerPixel;
|
||||
int end = (y + height - 1) * _stride + (x + width) * _bytesPerPixel;
|
||||
return (start, end - start);
|
||||
int start = y * Math.Abs(_stride) + x * _bytesPerPixel;
|
||||
int end = (y + height - 1) * Math.Abs(_stride) + (x + width) * _bytesPerPixel;
|
||||
return (y * _stride + x * _bytesPerPixel, end - start);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue