BitMap.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. namespace Ryujinx.Graphics.Vulkan
  2. {
  3. readonly struct BitMap
  4. {
  5. public const int IntSize = 64;
  6. private const int IntShift = 6;
  7. private const int IntMask = IntSize - 1;
  8. private readonly long[] _masks;
  9. public BitMap(int count)
  10. {
  11. _masks = new long[(count + IntMask) / IntSize];
  12. }
  13. public bool AnySet()
  14. {
  15. for (int i = 0; i < _masks.Length; i++)
  16. {
  17. if (_masks[i] != 0)
  18. {
  19. return true;
  20. }
  21. }
  22. return false;
  23. }
  24. public bool IsSet(int bit)
  25. {
  26. int wordIndex = bit >> IntShift;
  27. int wordBit = bit & IntMask;
  28. long wordMask = 1L << wordBit;
  29. return (_masks[wordIndex] & wordMask) != 0;
  30. }
  31. public bool IsSet(int start, int end)
  32. {
  33. if (start == end)
  34. {
  35. return IsSet(start);
  36. }
  37. int startIndex = start >> IntShift;
  38. int startBit = start & IntMask;
  39. long startMask = -1L << startBit;
  40. int endIndex = end >> IntShift;
  41. int endBit = end & IntMask;
  42. long endMask = (long)(ulong.MaxValue >> (IntMask - endBit));
  43. if (startIndex == endIndex)
  44. {
  45. return (_masks[startIndex] & startMask & endMask) != 0;
  46. }
  47. if ((_masks[startIndex] & startMask) != 0)
  48. {
  49. return true;
  50. }
  51. for (int i = startIndex + 1; i < endIndex; i++)
  52. {
  53. if (_masks[i] != 0)
  54. {
  55. return true;
  56. }
  57. }
  58. if ((_masks[endIndex] & endMask) != 0)
  59. {
  60. return true;
  61. }
  62. return false;
  63. }
  64. public bool Set(int bit)
  65. {
  66. int wordIndex = bit >> IntShift;
  67. int wordBit = bit & IntMask;
  68. long wordMask = 1L << wordBit;
  69. if ((_masks[wordIndex] & wordMask) != 0)
  70. {
  71. return false;
  72. }
  73. _masks[wordIndex] |= wordMask;
  74. return true;
  75. }
  76. public void SetRange(int start, int end)
  77. {
  78. if (start == end)
  79. {
  80. Set(start);
  81. return;
  82. }
  83. int startIndex = start >> IntShift;
  84. int startBit = start & IntMask;
  85. long startMask = -1L << startBit;
  86. int endIndex = end >> IntShift;
  87. int endBit = end & IntMask;
  88. long endMask = (long)(ulong.MaxValue >> (IntMask - endBit));
  89. if (startIndex == endIndex)
  90. {
  91. _masks[startIndex] |= startMask & endMask;
  92. }
  93. else
  94. {
  95. _masks[startIndex] |= startMask;
  96. for (int i = startIndex + 1; i < endIndex; i++)
  97. {
  98. _masks[i] |= -1;
  99. }
  100. _masks[endIndex] |= endMask;
  101. }
  102. }
  103. public void Clear(int bit)
  104. {
  105. int wordIndex = bit >> IntShift;
  106. int wordBit = bit & IntMask;
  107. long wordMask = 1L << wordBit;
  108. _masks[wordIndex] &= ~wordMask;
  109. }
  110. public void Clear()
  111. {
  112. for (int i = 0; i < _masks.Length; i++)
  113. {
  114. _masks[i] = 0;
  115. }
  116. }
  117. public void ClearInt(int start, int end)
  118. {
  119. for (int i = start; i <= end; i++)
  120. {
  121. _masks[i] = 0;
  122. }
  123. }
  124. }
  125. }