aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Gpu')
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs3
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs27
-rw-r--r--Ryujinx.Graphics.Gpu/Image/Texture.cs18
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureCache.cs10
4 files changed, 53 insertions, 5 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs b/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs
index 5814eeb7..da25a89d 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs
@@ -224,7 +224,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
xCount,
yCount,
dstLinear,
- dst.MemoryLayout);
+ dst.MemoryLayout.UnpackGobBlocksInY(),
+ dst.MemoryLayout.UnpackGobBlocksInZ());
if (target != null)
{
diff --git a/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs b/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs
index c0939057..6120d295 100644
--- a/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs
@@ -29,6 +29,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
private int _dstHeight;
private int _dstStride;
private int _dstGobBlocksInY;
+ private int _dstGobBlocksInZ;
private int _lineLengthIn;
private int _lineCount;
@@ -117,6 +118,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
_dstHeight = (int)state.SetDstHeight;
_dstStride = (int)state.PitchOut;
_dstGobBlocksInY = 1 << (int)state.SetDstBlockSizeHeight;
+ _dstGobBlocksInZ = 1 << (int)state.SetDstBlockSizeDepth;
_lineLengthIn = (int)state.LineLengthIn;
_lineCount = (int)state.LineCount;
@@ -176,6 +178,31 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
}
else
{
+ // TODO: Verify if the destination X/Y and width/height are taken into account
+ // for linear texture transfers. If not, we can use the fast path for that aswell.
+ // Right now the copy code at the bottom assumes that it is used on both which might be incorrect.
+ if (!_isLinear)
+ {
+ var target = memoryManager.Physical.TextureCache.FindTexture(
+ memoryManager,
+ _dstGpuVa,
+ 1,
+ _dstStride,
+ _dstHeight,
+ _lineLengthIn,
+ _lineCount,
+ _isLinear,
+ _dstGobBlocksInY,
+ _dstGobBlocksInZ);
+
+ if (target != null)
+ {
+ target.SetData(data, 0, 0, new GAL.Rectangle<int>(_dstX, _dstY, _lineLengthIn / target.Info.FormatInfo.BytesPerPixel, _lineCount));
+
+ return;
+ }
+ }
+
var dstCalculator = new OffsetCalculator(
_dstWidth,
_dstHeight,
diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs
index a598f212..320bc014 100644
--- a/Ryujinx.Graphics.Gpu/Image/Texture.cs
+++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs
@@ -762,6 +762,24 @@ namespace Ryujinx.Graphics.Gpu.Image
}
/// <summary>
+ /// Uploads new texture data to the host GPU for a specific layer/level and 2D sub-region.
+ /// </summary>
+ /// <param name="data">New data</param>
+ /// <param name="layer">Target layer</param>
+ /// <param name="level">Target level</param>
+ /// <param name="region">Target sub-region of the texture to update</param>
+ public void SetData(ReadOnlySpan<byte> data, int layer, int level, Rectangle<int> region)
+ {
+ BlacklistScale();
+
+ HostTexture.SetData(data, layer, level, region);
+
+ _currentData = null;
+
+ _hasData = true;
+ }
+
+ /// <summary>
/// Converts texture data to a format and layout that is supported by the host GPU.
/// </summary>
/// <param name="data">Data to be converted</param>
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureCache.cs b/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
index dcac9f64..d76879eb 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
@@ -905,7 +905,8 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="xCount">Number of pixels to be copied per line</param>
/// <param name="yCount">Number of lines to be copied</param>
/// <param name="linear">True if the texture has a linear layout, false otherwise</param>
- /// <param name="memoryLayout">If <paramref name="linear"/> is false, should have the memory layout, otherwise ignored</param>
+ /// <param name="gobBlocksInY">If <paramref name="linear"/> is false, the amount of GOB blocks in the Y axis</param>
+ /// <param name="gobBlocksInZ">If <paramref name="linear"/> is false, the amount of GOB blocks in the Z axis</param>
/// <returns>A matching texture, or null if there is no match</returns>
public Texture FindTexture(
MemoryManager memoryManager,
@@ -916,7 +917,8 @@ namespace Ryujinx.Graphics.Gpu.Image
int xCount,
int yCount,
bool linear,
- MemoryLayout memoryLayout)
+ int gobBlocksInY,
+ int gobBlocksInZ)
{
ulong address = memoryManager.Translate(gpuVa);
@@ -955,8 +957,8 @@ namespace Ryujinx.Graphics.Gpu.Image
bool sizeMatch = xCount * bpp == texture.Info.Width * format.BytesPerPixel && height == texture.Info.Height;
bool formatMatch = !texture.Info.IsLinear &&
- texture.Info.GobBlocksInY == memoryLayout.UnpackGobBlocksInY() &&
- texture.Info.GobBlocksInZ == memoryLayout.UnpackGobBlocksInZ();
+ texture.Info.GobBlocksInY == gobBlocksInY &&
+ texture.Info.GobBlocksInZ == gobBlocksInZ;
match = sizeMatch && formatMatch;
}