SizeInfo.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using System;
  2. using System.Collections.Generic;
  3. namespace Ryujinx.Graphics.Texture
  4. {
  5. public readonly struct SizeInfo
  6. {
  7. private readonly int[] _mipOffsets;
  8. private readonly int _levels;
  9. private readonly int _depth;
  10. private readonly bool _is3D;
  11. public readonly int[] AllOffsets;
  12. public readonly int[] SliceSizes;
  13. public readonly int[] LevelSizes;
  14. public int LayerSize { get; }
  15. public int TotalSize { get; }
  16. public SizeInfo(int size)
  17. {
  18. _mipOffsets = new int[] { 0 };
  19. AllOffsets = new int[] { 0 };
  20. SliceSizes = new int[] { size };
  21. LevelSizes = new int[] { size };
  22. _depth = 1;
  23. _levels = 1;
  24. LayerSize = size;
  25. TotalSize = size;
  26. _is3D = false;
  27. }
  28. internal SizeInfo(
  29. int[] mipOffsets,
  30. int[] allOffsets,
  31. int[] sliceSizes,
  32. int[] levelSizes,
  33. int depth,
  34. int levels,
  35. int layerSize,
  36. int totalSize,
  37. bool is3D)
  38. {
  39. _mipOffsets = mipOffsets;
  40. AllOffsets = allOffsets;
  41. SliceSizes = sliceSizes;
  42. LevelSizes = levelSizes;
  43. _depth = depth;
  44. _levels = levels;
  45. LayerSize = layerSize;
  46. TotalSize = totalSize;
  47. _is3D = is3D;
  48. }
  49. public int GetMipOffset(int level)
  50. {
  51. if ((uint)level >= _mipOffsets.Length)
  52. {
  53. throw new ArgumentOutOfRangeException(nameof(level));
  54. }
  55. return _mipOffsets[level];
  56. }
  57. public bool FindView(int offset, out int firstLayer, out int firstLevel)
  58. {
  59. int index = Array.BinarySearch(AllOffsets, offset);
  60. if (index < 0)
  61. {
  62. firstLayer = 0;
  63. firstLevel = 0;
  64. return false;
  65. }
  66. if (_is3D)
  67. {
  68. firstLayer = index;
  69. firstLevel = 0;
  70. int levelDepth = _depth;
  71. while (firstLayer >= levelDepth)
  72. {
  73. firstLayer -= levelDepth;
  74. firstLevel++;
  75. levelDepth = Math.Max(levelDepth >> 1, 1);
  76. }
  77. }
  78. else
  79. {
  80. firstLayer = index / _levels;
  81. firstLevel = index - (firstLayer * _levels);
  82. }
  83. return true;
  84. }
  85. public IEnumerable<Region> AllRegions()
  86. {
  87. if (_is3D)
  88. {
  89. for (int i = 0; i < _mipOffsets.Length; i++)
  90. {
  91. int maxSize = TotalSize - _mipOffsets[i];
  92. yield return new Region(_mipOffsets[i], Math.Min(maxSize, LevelSizes[i]));
  93. }
  94. }
  95. else
  96. {
  97. for (int i = 0; i < AllOffsets.Length; i++)
  98. {
  99. yield return new Region(AllOffsets[i], SliceSizes[i % _levels]);
  100. }
  101. }
  102. }
  103. }
  104. }