SizeInfo.cs 2.9 KB

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