/ src / Ryujinx.Graphics.Vulkan / BufferUsageBitmap.cs
BufferUsageBitmap.cs
 1  namespace Ryujinx.Graphics.Vulkan
 2  {
 3      internal class BufferUsageBitmap
 4      {
 5          private readonly BitMap _bitmap;
 6          private readonly int _size;
 7          private readonly int _granularity;
 8          private readonly int _bits;
 9          private readonly int _writeBitOffset;
10  
11          private readonly int _intsPerCb;
12          private readonly int _bitsPerCb;
13  
14          public BufferUsageBitmap(int size, int granularity)
15          {
16              _size = size;
17              _granularity = granularity;
18  
19              // There are two sets of bits - one for read tracking, and the other for write.
20              int bits = (size + (granularity - 1)) / granularity;
21              _writeBitOffset = bits;
22              _bits = bits << 1;
23  
24              _intsPerCb = (_bits + (BitMap.IntSize - 1)) / BitMap.IntSize;
25              _bitsPerCb = _intsPerCb * BitMap.IntSize;
26  
27              _bitmap = new BitMap(_bitsPerCb * CommandBufferPool.MaxCommandBuffers);
28          }
29  
30          public void Add(int cbIndex, int offset, int size, bool write)
31          {
32              if (size == 0)
33              {
34                  return;
35              }
36  
37              // Some usages can be out of bounds (vertex buffer on amd), so bound if necessary.
38              if (offset + size > _size)
39              {
40                  size = _size - offset;
41              }
42  
43              int cbBase = cbIndex * _bitsPerCb + (write ? _writeBitOffset : 0);
44              int start = cbBase + offset / _granularity;
45              int end = cbBase + (offset + size - 1) / _granularity;
46  
47              _bitmap.SetRange(start, end);
48          }
49  
50          public bool OverlapsWith(int cbIndex, int offset, int size, bool write = false)
51          {
52              if (size == 0)
53              {
54                  return false;
55              }
56  
57              int cbBase = cbIndex * _bitsPerCb + (write ? _writeBitOffset : 0);
58              int start = cbBase + offset / _granularity;
59              int end = cbBase + (offset + size - 1) / _granularity;
60  
61              return _bitmap.IsSet(start, end);
62          }
63  
64          public bool OverlapsWith(int offset, int size, bool write)
65          {
66              for (int i = 0; i < CommandBufferPool.MaxCommandBuffers; i++)
67              {
68                  if (OverlapsWith(i, offset, size, write))
69                  {
70                      return true;
71                  }
72              }
73  
74              return false;
75          }
76  
77          public void Clear(int cbIndex)
78          {
79              _bitmap.ClearInt(cbIndex * _intsPerCb, (cbIndex + 1) * _intsPerCb - 1);
80          }
81      }
82  }