BlockLinearLayout.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. using Ryujinx.Common;
  2. using System.Runtime.CompilerServices;
  3. using static Ryujinx.Graphics.Texture.BlockLinearConstants;
  4. namespace Ryujinx.Graphics.Texture
  5. {
  6. class BlockLinearLayout
  7. {
  8. private struct RobAndSliceSizes
  9. {
  10. public int RobSize;
  11. public int SliceSize;
  12. public RobAndSliceSizes(int robSize, int sliceSize)
  13. {
  14. RobSize = robSize;
  15. SliceSize = sliceSize;
  16. }
  17. }
  18. private int _texBpp;
  19. private int _bhMask;
  20. private int _bdMask;
  21. private int _bhShift;
  22. private int _bdShift;
  23. private int _bppShift;
  24. private int _xShift;
  25. private int _robSize;
  26. private int _sliceSize;
  27. public BlockLinearLayout(
  28. int width,
  29. int height,
  30. int depth,
  31. int gobBlocksInY,
  32. int gobBlocksInZ,
  33. int bpp)
  34. {
  35. _texBpp = bpp;
  36. _bppShift = BitUtils.CountTrailingZeros32(bpp);
  37. _bhMask = gobBlocksInY - 1;
  38. _bdMask = gobBlocksInZ - 1;
  39. _bhShift = BitUtils.CountTrailingZeros32(gobBlocksInY);
  40. _bdShift = BitUtils.CountTrailingZeros32(gobBlocksInZ);
  41. _xShift = BitUtils.CountTrailingZeros32(GobSize * gobBlocksInY * gobBlocksInZ);
  42. RobAndSliceSizes rsSizes = GetRobAndSliceSizes(width, height, gobBlocksInY, gobBlocksInZ);
  43. _robSize = rsSizes.RobSize;
  44. _sliceSize = rsSizes.SliceSize;
  45. }
  46. private RobAndSliceSizes GetRobAndSliceSizes(int width, int height, int gobBlocksInY, int gobBlocksInZ)
  47. {
  48. int widthInGobs = BitUtils.DivRoundUp(width * _texBpp, GobStride);
  49. int robSize = GobSize * gobBlocksInY * gobBlocksInZ * widthInGobs;
  50. int sliceSize = BitUtils.DivRoundUp(height, gobBlocksInY * GobHeight) * robSize;
  51. return new RobAndSliceSizes(robSize, sliceSize);
  52. }
  53. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  54. public int GetOffset(int x, int y, int z)
  55. {
  56. return GetOffsetWithLineOffset(x << _bppShift, y, z);
  57. }
  58. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  59. public int GetOffsetWithLineOffset(int x, int y, int z)
  60. {
  61. int yh = y / GobHeight;
  62. int offset = (z >> _bdShift) * _sliceSize + (yh >> _bhShift) * _robSize;
  63. offset += (x / GobStride) << _xShift;
  64. offset += (yh & _bhMask) * GobSize;
  65. offset += ((z & _bdMask) * GobSize) << _bhShift;
  66. offset += ((x & 0x3f) >> 5) << 8;
  67. offset += ((y & 0x07) >> 1) << 6;
  68. offset += ((x & 0x1f) >> 4) << 5;
  69. offset += ((y & 0x01) >> 0) << 4;
  70. offset += ((x & 0x0f) >> 0) << 0;
  71. return offset;
  72. }
  73. }
  74. }