aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs48
-rw-r--r--src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs47
2 files changed, 93 insertions, 2 deletions
diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs b/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs
index 218db15cf..f2bfd8eaa 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs
@@ -276,8 +276,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
276 dstBaseOffset += dstStride * (yCount - 1); 276 dstBaseOffset += dstStride * (yCount - 1);
277 } 277 }
278 278
279 ReadOnlySpan<byte> srcSpan = memoryManager.GetSpan(srcGpuVa + (ulong)srcBaseOffset, srcSize, true);
280
281 // If remapping is disabled, we always copy the components directly, in order. 279 // If remapping is disabled, we always copy the components directly, in order.
282 // If it's enabled, but the mapping is just XYZW, we also copy them in order. 280 // If it's enabled, but the mapping is just XYZW, we also copy them in order.
283 bool isIdentityRemap = !remap || 281 bool isIdentityRemap = !remap ||
@@ -289,6 +287,52 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
289 bool completeSource = IsTextureCopyComplete(src, srcLinear, srcBpp, srcStride, xCount, yCount); 287 bool completeSource = IsTextureCopyComplete(src, srcLinear, srcBpp, srcStride, xCount, yCount);
290 bool completeDest = IsTextureCopyComplete(dst, dstLinear, dstBpp, dstStride, xCount, yCount); 288 bool completeDest = IsTextureCopyComplete(dst, dstLinear, dstBpp, dstStride, xCount, yCount);
291 289
290 // Check if the source texture exists on the GPU, if it does, do a GPU side copy.
291 // Otherwise, we would need to flush the source texture which is costly.
292 // We don't expect the source to be linear in such cases, as linear source usually indicates buffer or CPU written data.
293
294 if (completeSource && completeDest && !srcLinear && isIdentityRemap)
295 {
296 var source = memoryManager.Physical.TextureCache.FindTexture(
297 memoryManager,
298 srcGpuVa,
299 srcBpp,
300 srcStride,
301 src.Height,
302 xCount,
303 yCount,
304 srcLinear,
305 src.MemoryLayout.UnpackGobBlocksInY(),
306 src.MemoryLayout.UnpackGobBlocksInZ());
307
308 if (source != null && source.Height == yCount)
309 {
310 source.SynchronizeMemory();
311
312 var target = memoryManager.Physical.TextureCache.FindOrCreateTexture(
313 memoryManager,
314 source.Info.FormatInfo,
315 dstGpuVa,
316 xCount,
317 yCount,
318 dstStride,
319 dstLinear,
320 dst.MemoryLayout.UnpackGobBlocksInY(),
321 dst.MemoryLayout.UnpackGobBlocksInZ());
322
323 if (source.ScaleFactor != target.ScaleFactor)
324 {
325 target.PropagateScale(source);
326 }
327
328 source.HostTexture.CopyTo(target.HostTexture, 0, 0);
329 target.SignalModified();
330 return;
331 }
332 }
333
334 ReadOnlySpan<byte> srcSpan = memoryManager.GetSpan(srcGpuVa + (ulong)srcBaseOffset, srcSize, true);
335
292 // Try to set the texture data directly, 336 // Try to set the texture data directly,
293 // but only if we are doing a complete copy, 337 // but only if we are doing a complete copy,
294 // and not for block linear to linear copies, since those are typically accessed from the CPU. 338 // and not for block linear to linear copies, since those are typically accessed from the CPU.
diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
index b6fa842e3..5a3319b06 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
+++ b/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
@@ -351,6 +351,53 @@ namespace Ryujinx.Graphics.Gpu.Image
351 /// Tries to find an existing texture, or create a new one if not found. 351 /// Tries to find an existing texture, or create a new one if not found.
352 /// </summary> 352 /// </summary>
353 /// <param name="memoryManager">GPU memory manager where the texture is mapped</param> 353 /// <param name="memoryManager">GPU memory manager where the texture is mapped</param>
354 /// <param name="formatInfo">Format of the texture</param>
355 /// <param name="gpuAddress">GPU virtual address of the texture</param>
356 /// <param name="xCount">Texture width in bytes</param>
357 /// <param name="yCount">Texture height</param>
358 /// <param name="stride">Texture stride if linear, otherwise ignored</param>
359 /// <param name="isLinear">Indicates if the texture is linear or block linear</param>
360 /// <param name="gobBlocksInY">GOB blocks in Y for block linear textures</param>
361 /// <param name="gobBlocksInZ">GOB blocks in Z for 3D block linear textures</param>
362 /// <returns>The texture</returns>
363 public Texture FindOrCreateTexture(
364 MemoryManager memoryManager,
365 FormatInfo formatInfo,
366 ulong gpuAddress,
367 int xCount,
368 int yCount,
369 int stride,
370 bool isLinear,
371 int gobBlocksInY,
372 int gobBlocksInZ)
373 {
374 TextureInfo info = new(
375 gpuAddress,
376 xCount / formatInfo.BytesPerPixel,
377 yCount,
378 1,
379 1,
380 1,
381 1,
382 stride,
383 isLinear,
384 gobBlocksInY,
385 gobBlocksInZ,
386 1,
387 Target.Texture2D,
388 formatInfo);
389
390 Texture texture = FindOrCreateTexture(memoryManager, TextureSearchFlags.ForCopy, info, 0, sizeHint: new Size(xCount, yCount, 1));
391
392 texture?.SynchronizeMemory();
393
394 return texture;
395 }
396
397 /// <summary>
398 /// Tries to find an existing texture, or create a new one if not found.
399 /// </summary>
400 /// <param name="memoryManager">GPU memory manager where the texture is mapped</param>
354 /// <param name="colorState">Color buffer texture to find or create</param> 401 /// <param name="colorState">Color buffer texture to find or create</param>
355 /// <param name="layered">Indicates if the texture might be accessed with a non-zero layer index</param> 402 /// <param name="layered">Indicates if the texture might be accessed with a non-zero layer index</param>
356 /// <param name="discard">Indicates that the sizeHint region's data will be overwritten</param> 403 /// <param name="discard">Indicates that the sizeHint region's data will be overwritten</param>