TextureCopyUnscaled.cs 2.8 KB

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