OffsetCalculator.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. using Ryujinx.Common;
  2. using System.Runtime.CompilerServices;
  3. using static Ryujinx.Graphics.Texture.BlockLinearConstants;
  4. namespace Ryujinx.Graphics.Texture
  5. {
  6. public class OffsetCalculator
  7. {
  8. private int _width;
  9. private int _height;
  10. private int _stride;
  11. private bool _isLinear;
  12. private int _bytesPerPixel;
  13. private BlockLinearLayout _layoutConverter;
  14. // Variables for built in iteration.
  15. private int _yPart;
  16. public OffsetCalculator(
  17. int width,
  18. int height,
  19. int stride,
  20. bool isLinear,
  21. int gobBlocksInY,
  22. int gobBlocksInZ,
  23. int bytesPerPixel)
  24. {
  25. _width = width;
  26. _height = height;
  27. _stride = stride;
  28. _isLinear = isLinear;
  29. _bytesPerPixel = bytesPerPixel;
  30. int wAlignment = GobStride / bytesPerPixel;
  31. int wAligned = BitUtils.AlignUp(width, wAlignment);
  32. if (!isLinear)
  33. {
  34. _layoutConverter = new BlockLinearLayout(
  35. wAligned,
  36. height,
  37. gobBlocksInY,
  38. gobBlocksInZ,
  39. bytesPerPixel);
  40. }
  41. }
  42. public OffsetCalculator(
  43. int width,
  44. int height,
  45. int stride,
  46. bool isLinear,
  47. int gobBlocksInY,
  48. int bytesPerPixel) : this(width, height, stride, isLinear, gobBlocksInY, 1, bytesPerPixel)
  49. {
  50. }
  51. public void SetY(int y)
  52. {
  53. if (_isLinear)
  54. {
  55. _yPart = y * _stride;
  56. }
  57. else
  58. {
  59. _layoutConverter.SetY(y);
  60. }
  61. }
  62. public int GetOffset(int x, int y)
  63. {
  64. if (_isLinear)
  65. {
  66. return x * _bytesPerPixel + y * _stride;
  67. }
  68. else
  69. {
  70. return _layoutConverter.GetOffset(x, y, 0);
  71. }
  72. }
  73. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  74. public int GetOffset(int x)
  75. {
  76. if (_isLinear)
  77. {
  78. return x * _bytesPerPixel + _yPart;
  79. }
  80. else
  81. {
  82. return _layoutConverter.GetOffset(x);
  83. }
  84. }
  85. public (int offset, int size) GetRectangleRange(int x, int y, int width, int height)
  86. {
  87. if (_isLinear)
  88. {
  89. int start = y * _stride + x * _bytesPerPixel;
  90. int end = (y + height - 1) * _stride + (x + width) * _bytesPerPixel;
  91. return (start, end - start);
  92. }
  93. else
  94. {
  95. return _layoutConverter.GetRectangleRange(x, y, width, height);
  96. }
  97. }
  98. public bool LayoutMatches(OffsetCalculator other)
  99. {
  100. if (_isLinear)
  101. {
  102. return other._isLinear &&
  103. _width == other._width &&
  104. _height == other._height &&
  105. _stride == other._stride &&
  106. _bytesPerPixel == other._bytesPerPixel;
  107. }
  108. else
  109. {
  110. return !other._isLinear && _layoutConverter.LayoutMatches(other._layoutConverter);
  111. }
  112. }
  113. }
  114. }