MethodCopyBuffer.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. using Ryujinx.Graphics.Gpu.State;
  2. using Ryujinx.Graphics.Texture;
  3. using System;
  4. namespace Ryujinx.Graphics.Gpu.Engine
  5. {
  6. partial class Methods
  7. {
  8. private void CopyBuffer(GpuState state, int argument)
  9. {
  10. var cbp = state.Get<CopyBufferParams>(MethodOffset.CopyBufferParams);
  11. var swizzle = state.Get<CopyBufferSwizzle>(MethodOffset.CopyBufferSwizzle);
  12. bool srcLinear = (argument & (1 << 7)) != 0;
  13. bool dstLinear = (argument & (1 << 8)) != 0;
  14. bool copy2D = (argument & (1 << 9)) != 0;
  15. int size = cbp.XCount;
  16. if (size == 0)
  17. {
  18. return;
  19. }
  20. if (copy2D)
  21. {
  22. // Buffer to texture copy.
  23. int srcBpp = swizzle.UnpackSrcComponentsCount() * swizzle.UnpackComponentSize();
  24. int dstBpp = swizzle.UnpackDstComponentsCount() * swizzle.UnpackComponentSize();
  25. var dst = state.Get<CopyBufferTexture>(MethodOffset.CopyBufferDstTexture);
  26. var src = state.Get<CopyBufferTexture>(MethodOffset.CopyBufferSrcTexture);
  27. var srcCalculator = new OffsetCalculator(
  28. src.Width,
  29. src.Height,
  30. cbp.SrcStride,
  31. srcLinear,
  32. src.MemoryLayout.UnpackGobBlocksInY(),
  33. srcBpp);
  34. var dstCalculator = new OffsetCalculator(
  35. dst.Width,
  36. dst.Height,
  37. cbp.DstStride,
  38. dstLinear,
  39. dst.MemoryLayout.UnpackGobBlocksInY(),
  40. dstBpp);
  41. ulong srcBaseAddress = _context.MemoryManager.Translate(cbp.SrcAddress.Pack());
  42. ulong dstBaseAddress = _context.MemoryManager.Translate(cbp.DstAddress.Pack());
  43. for (int y = 0; y < cbp.YCount; y++)
  44. for (int x = 0; x < cbp.XCount; x++)
  45. {
  46. int srcOffset = srcCalculator.GetOffset(src.RegionX + x, src.RegionY + y);
  47. int dstOffset = dstCalculator.GetOffset(dst.RegionX + x, dst.RegionY + y);
  48. ulong srcAddress = srcBaseAddress + (ulong)srcOffset;
  49. ulong dstAddress = dstBaseAddress + (ulong)dstOffset;
  50. Span<byte> pixel = _context.PhysicalMemory.Read(srcAddress, (ulong)srcBpp);
  51. _context.PhysicalMemory.Write(dstAddress, pixel);
  52. }
  53. }
  54. else
  55. {
  56. // Buffer to buffer copy.
  57. _bufferManager.CopyBuffer(cbp.SrcAddress, cbp.DstAddress, (uint)size);
  58. }
  59. }
  60. }
  61. }