TextureCopyUnscaled.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. float scaleFactor = 1f)
  19. {
  20. int srcWidth = (int)Math.Ceiling(srcInfo.Width * scaleFactor);
  21. int srcHeight = (int)Math.Ceiling(srcInfo.Height * scaleFactor);
  22. int srcDepth = srcInfo.GetDepthOrLayers();
  23. int srcLevels = srcInfo.Levels;
  24. int dstWidth = (int)Math.Ceiling(dstInfo.Width * scaleFactor);
  25. int dstHeight = (int)Math.Ceiling(dstInfo.Height * scaleFactor);
  26. int dstDepth = dstInfo.GetDepthOrLayers();
  27. int dstLevels = dstInfo.Levels;
  28. dstWidth = Math.Max(1, dstWidth >> dstLevel);
  29. dstHeight = Math.Max(1, dstHeight >> dstLevel);
  30. if (dstInfo.Target == Target.Texture3D)
  31. {
  32. dstDepth = Math.Max(1, dstDepth >> dstLevel);
  33. }
  34. // When copying from a compressed to a non-compressed format,
  35. // the non-compressed texture will have the size of the texture
  36. // in blocks (not in texels), so we must adjust that size to
  37. // match the size in texels of the compressed texture.
  38. if (!srcInfo.IsCompressed && dstInfo.IsCompressed)
  39. {
  40. dstWidth = BitUtils.DivRoundUp(dstWidth, dstInfo.BlockWidth);
  41. dstHeight = BitUtils.DivRoundUp(dstHeight, dstInfo.BlockHeight);
  42. }
  43. else if (srcInfo.IsCompressed && !dstInfo.IsCompressed)
  44. {
  45. dstWidth *= dstInfo.BlockWidth;
  46. dstHeight *= dstInfo.BlockHeight;
  47. }
  48. int width = Math.Min(srcWidth, dstWidth);
  49. int height = Math.Min(srcHeight, dstHeight);
  50. int depth = Math.Min(srcDepth, dstDepth);
  51. int levels = Math.Min(srcLevels, dstLevels);
  52. for (int level = 0; level < levels; level++)
  53. {
  54. // Stop copy if we are already out of the levels range.
  55. if (level >= srcInfo.Levels || dstLevel + level >= dstInfo.Levels)
  56. {
  57. break;
  58. }
  59. GL.CopyImageSubData(
  60. srcHandle,
  61. srcInfo.Target.ConvertToImageTarget(),
  62. srcLevel + level,
  63. 0,
  64. 0,
  65. srcLayer,
  66. dstHandle,
  67. dstInfo.Target.ConvertToImageTarget(),
  68. dstLevel + level,
  69. 0,
  70. 0,
  71. dstLayer,
  72. width,
  73. height,
  74. depth);
  75. width = Math.Max(1, width >> 1);
  76. height = Math.Max(1, height >> 1);
  77. if (srcInfo.Target == Target.Texture3D)
  78. {
  79. depth = Math.Max(1, depth >> 1);
  80. }
  81. }
  82. }
  83. }
  84. }