BlockLinearLayout.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using Ryujinx.Common;
  2. using System;
  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 _texWidth;
  19. private int _texHeight;
  20. private int _texDepth;
  21. private int _texGobBlocksInY;
  22. private int _texGobBlocksInZ;
  23. private int _texBpp;
  24. private int _bhMask;
  25. private int _bdMask;
  26. private int _bhShift;
  27. private int _bdShift;
  28. private int _bppShift;
  29. private int _xShift;
  30. private int _robSize;
  31. private int _sliceSize;
  32. public BlockLinearLayout(
  33. int width,
  34. int height,
  35. int depth,
  36. int gobBlocksInY,
  37. int gobBlocksInZ,
  38. int bpp)
  39. {
  40. _texWidth = width;
  41. _texHeight = height;
  42. _texDepth = depth;
  43. _texGobBlocksInY = gobBlocksInY;
  44. _texGobBlocksInZ = gobBlocksInZ;
  45. _texBpp = bpp;
  46. _bppShift = BitUtils.CountTrailingZeros32(bpp);
  47. _bhMask = gobBlocksInY - 1;
  48. _bdMask = gobBlocksInZ - 1;
  49. _bhShift = BitUtils.CountTrailingZeros32(gobBlocksInY);
  50. _bdShift = BitUtils.CountTrailingZeros32(gobBlocksInZ);
  51. _xShift = BitUtils.CountTrailingZeros32(GobSize * gobBlocksInY * gobBlocksInZ);
  52. RobAndSliceSizes rsSizes = GetRobAndSliceSizes(width, height, gobBlocksInY, gobBlocksInZ);
  53. _robSize = rsSizes.RobSize;
  54. _sliceSize = rsSizes.SliceSize;
  55. }
  56. private RobAndSliceSizes GetRobAndSliceSizes(int width, int height, int gobBlocksInY, int gobBlocksInZ)
  57. {
  58. int widthInGobs = BitUtils.DivRoundUp(width * _texBpp, GobStride);
  59. int robSize = GobSize * gobBlocksInY * gobBlocksInZ * widthInGobs;
  60. int sliceSize = BitUtils.DivRoundUp(height, gobBlocksInY * GobHeight) * robSize;
  61. return new RobAndSliceSizes(robSize, sliceSize);
  62. }
  63. public int GetOffset(int x, int y, int z)
  64. {
  65. x <<= _bppShift;
  66. int yh = y / GobHeight;
  67. int position = (z >> _bdShift) * _sliceSize + (yh >> _bhShift) * _robSize;
  68. position += (x / GobStride) << _xShift;
  69. position += (yh & _bhMask) * GobSize;
  70. position += ((z & _bdMask) * GobSize) << _bhShift;
  71. position += ((x & 0x3f) >> 5) << 8;
  72. position += ((y & 0x07) >> 1) << 6;
  73. position += ((x & 0x1f) >> 4) << 5;
  74. position += ((y & 0x01) >> 0) << 4;
  75. position += ((x & 0x0f) >> 0) << 0;
  76. return position;
  77. }
  78. }
  79. }