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