TextureCopyUnscaled.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using OpenTK.Graphics.OpenGL;
  2. using Ryujinx.Common;
  3. using Ryujinx.Graphics.GAL;
  4. using System;
  5. namespace Ryujinx.Graphics.OpenGL.Image
  6. {
  7. static class TextureCopyUnscaled
  8. {
  9. public static void Copy(
  10. TextureCreateInfo srcInfo,
  11. TextureCreateInfo dstInfo,
  12. int srcHandle,
  13. int dstHandle,
  14. int srcLayer,
  15. int dstLayer,
  16. int srcLevel,
  17. int dstLevel)
  18. {
  19. int srcWidth = srcInfo.Width;
  20. int srcHeight = srcInfo.Height;
  21. int srcDepth = srcInfo.GetDepthOrLayers();
  22. int srcLevels = srcInfo.Levels;
  23. int dstWidth = dstInfo.Width;
  24. int dstHeight = dstInfo.Height;
  25. int dstDepth = dstInfo.GetDepthOrLayers();
  26. int dstLevels = dstInfo.Levels;
  27. dstWidth = Math.Max(1, dstWidth >> dstLevel);
  28. dstHeight = Math.Max(1, dstHeight >> dstLevel);
  29. if (dstInfo.Target == Target.Texture3D)
  30. {
  31. dstDepth = Math.Max(1, dstDepth >> dstLevel);
  32. }
  33. // When copying from a compressed to a non-compressed format,
  34. // the non-compressed texture will have the size of the texture
  35. // in blocks (not in texels), so we must adjust that size to
  36. // match the size in texels of the compressed texture.
  37. if (!srcInfo.IsCompressed && dstInfo.IsCompressed)
  38. {
  39. dstWidth = BitUtils.DivRoundUp(dstWidth, dstInfo.BlockWidth);
  40. dstHeight = BitUtils.DivRoundUp(dstHeight, dstInfo.BlockHeight);
  41. }
  42. else if (srcInfo.IsCompressed && !dstInfo.IsCompressed)
  43. {
  44. dstWidth *= dstInfo.BlockWidth;
  45. dstHeight *= dstInfo.BlockHeight;
  46. }
  47. int width = Math.Min(srcWidth, dstWidth);
  48. int height = Math.Min(srcHeight, dstHeight);
  49. int depth = Math.Min(srcDepth, dstDepth);
  50. int levels = Math.Min(srcLevels, dstLevels);
  51. for (int level = 0; level < levels; level++)
  52. {
  53. // Stop copy if we are already out of the levels range.
  54. if (level >= srcInfo.Levels || dstLevel + level >= dstInfo.Levels)
  55. {
  56. break;
  57. }
  58. GL.CopyImageSubData(
  59. srcHandle,
  60. srcInfo.Target.ConvertToImageTarget(),
  61. srcLevel + level,
  62. 0,
  63. 0,
  64. srcLayer,
  65. dstHandle,
  66. dstInfo.Target.ConvertToImageTarget(),
  67. dstLevel + level,
  68. 0,
  69. 0,
  70. dstLayer,
  71. width,
  72. height,
  73. depth);
  74. width = Math.Max(1, width >> 1);
  75. height = Math.Max(1, height >> 1);
  76. if (srcInfo.Target == Target.Texture3D)
  77. {
  78. depth = Math.Max(1, depth >> 1);
  79. }
  80. }
  81. }
  82. }
  83. }