NvGpuEngine2d.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. using Ryujinx.Graphics.Gal;
  2. using Ryujinx.Graphics.Memory;
  3. using Ryujinx.Graphics.Texture;
  4. namespace Ryujinx.Graphics
  5. {
  6. class NvGpuEngine2d : INvGpuEngine
  7. {
  8. private enum CopyOperation
  9. {
  10. SrcCopyAnd,
  11. RopAnd,
  12. Blend,
  13. SrcCopy,
  14. Rop,
  15. SrcCopyPremult,
  16. BlendPremult
  17. }
  18. public int[] Registers { get; private set; }
  19. private NvGpu Gpu;
  20. public NvGpuEngine2d(NvGpu Gpu)
  21. {
  22. this.Gpu = Gpu;
  23. Registers = new int[0x238];
  24. }
  25. public void CallMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
  26. {
  27. WriteRegister(MethCall);
  28. if ((NvGpuEngine2dReg)MethCall.Method == NvGpuEngine2dReg.BlitSrcYInt)
  29. {
  30. TextureCopy(Vmm);
  31. }
  32. }
  33. private void TextureCopy(NvGpuVmm Vmm)
  34. {
  35. CopyOperation Operation = (CopyOperation)ReadRegister(NvGpuEngine2dReg.CopyOperation);
  36. int DstFormat = ReadRegister(NvGpuEngine2dReg.DstFormat);
  37. bool DstLinear = ReadRegister(NvGpuEngine2dReg.DstLinear) != 0;
  38. int DstWidth = ReadRegister(NvGpuEngine2dReg.DstWidth);
  39. int DstHeight = ReadRegister(NvGpuEngine2dReg.DstHeight);
  40. int DstPitch = ReadRegister(NvGpuEngine2dReg.DstPitch);
  41. int DstBlkDim = ReadRegister(NvGpuEngine2dReg.DstBlockDimensions);
  42. int SrcFormat = ReadRegister(NvGpuEngine2dReg.SrcFormat);
  43. bool SrcLinear = ReadRegister(NvGpuEngine2dReg.SrcLinear) != 0;
  44. int SrcWidth = ReadRegister(NvGpuEngine2dReg.SrcWidth);
  45. int SrcHeight = ReadRegister(NvGpuEngine2dReg.SrcHeight);
  46. int SrcPitch = ReadRegister(NvGpuEngine2dReg.SrcPitch);
  47. int SrcBlkDim = ReadRegister(NvGpuEngine2dReg.SrcBlockDimensions);
  48. int DstBlitX = ReadRegister(NvGpuEngine2dReg.BlitDstX);
  49. int DstBlitY = ReadRegister(NvGpuEngine2dReg.BlitDstY);
  50. int DstBlitW = ReadRegister(NvGpuEngine2dReg.BlitDstW);
  51. int DstBlitH = ReadRegister(NvGpuEngine2dReg.BlitDstH);
  52. int SrcBlitX = ReadRegister(NvGpuEngine2dReg.BlitSrcXInt);
  53. int SrcBlitY = ReadRegister(NvGpuEngine2dReg.BlitSrcYInt);
  54. GalImageFormat SrcImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)SrcFormat);
  55. GalImageFormat DstImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)DstFormat);
  56. GalMemoryLayout SrcLayout = GetLayout(SrcLinear);
  57. GalMemoryLayout DstLayout = GetLayout(DstLinear);
  58. int SrcBlockHeight = 1 << ((SrcBlkDim >> 4) & 0xf);
  59. int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf);
  60. long SrcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress);
  61. long DstAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.DstAddress);
  62. long SrcKey = Vmm.GetPhysicalAddress(SrcAddress);
  63. long DstKey = Vmm.GetPhysicalAddress(DstAddress);
  64. GalImage SrcTexture = new GalImage(
  65. SrcWidth,
  66. SrcHeight, 1,
  67. SrcBlockHeight,
  68. SrcLayout,
  69. SrcImgFormat);
  70. GalImage DstTexture = new GalImage(
  71. DstWidth,
  72. DstHeight, 1,
  73. DstBlockHeight,
  74. DstLayout,
  75. DstImgFormat);
  76. SrcTexture.Pitch = SrcPitch;
  77. DstTexture.Pitch = DstPitch;
  78. Gpu.ResourceManager.SendTexture(Vmm, SrcKey, SrcTexture);
  79. Gpu.ResourceManager.SendTexture(Vmm, DstKey, DstTexture);
  80. Gpu.Renderer.RenderTarget.Copy(
  81. SrcKey,
  82. DstKey,
  83. SrcBlitX,
  84. SrcBlitY,
  85. SrcBlitX + DstBlitW,
  86. SrcBlitY + DstBlitH,
  87. DstBlitX,
  88. DstBlitY,
  89. DstBlitX + DstBlitW,
  90. DstBlitY + DstBlitH);
  91. //Do a guest side copy aswell. This is necessary when
  92. //the texture is modified by the guest, however it doesn't
  93. //work when resources that the gpu can write to are copied,
  94. //like framebuffers.
  95. ImageUtils.CopyTexture(
  96. Vmm,
  97. SrcTexture,
  98. DstTexture,
  99. SrcAddress,
  100. DstAddress,
  101. SrcBlitX,
  102. SrcBlitY,
  103. DstBlitX,
  104. DstBlitY,
  105. DstBlitW,
  106. DstBlitH);
  107. Vmm.IsRegionModified(DstKey, ImageUtils.GetSize(DstTexture), NvGpuBufferType.Texture);
  108. }
  109. private static GalMemoryLayout GetLayout(bool Linear)
  110. {
  111. return Linear
  112. ? GalMemoryLayout.Pitch
  113. : GalMemoryLayout.BlockLinear;
  114. }
  115. private long MakeInt64From2xInt32(NvGpuEngine2dReg Reg)
  116. {
  117. return
  118. (long)Registers[(int)Reg + 0] << 32 |
  119. (uint)Registers[(int)Reg + 1];
  120. }
  121. private void WriteRegister(GpuMethodCall MethCall)
  122. {
  123. Registers[MethCall.Method] = MethCall.Argument;
  124. }
  125. private int ReadRegister(NvGpuEngine2dReg Reg)
  126. {
  127. return Registers[(int)Reg];
  128. }
  129. }
  130. }