OffsetCalculator.cs 3.8 KB

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