MethodCopyBuffer.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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(int argument)
  9. {
  10. var cbp = _context.State.Get<CopyBufferParams>(MethodOffset.CopyBufferParams);
  11. var swizzle = _context.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 = _context.State.Get<CopyBufferTexture>(MethodOffset.CopyBufferDstTexture);
  26. var src = _context.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. Span<byte> data = _context.MemoryAccessor.Read(cbp.SrcAddress.Pack(), (uint)size);
  59. _context.MemoryAccessor.Write(cbp.DstAddress.Pack(), data);
  60. }
  61. }
  62. }
  63. }