diff options
-rw-r--r-- | src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs | 48 | ||||
-rw-r--r-- | src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs | 47 |
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> |