85 this->
Setup(descriptors.begin(), (
SizeT)descriptors.size());
94 this->
Setup(descriptors, num);
109 n_assert(last != AttributeId::Invalid());
110 uint const largestBit = last.id;
111 this->
size = (largestBit / 128) + 1;
114 for (
int i = 0; i < this->
size; i++)
115 this->
mask[i] = _mm_setzero_si128();
117 alignas(16) uint64_t partialMask[2] = { 0, 0 };
119 uint64_t offset = descriptors[0].id / 128;
120 uint64_t prevOffset = offset;
123 n_assert(i != AttributeId::Invalid());
125 if (offset != prevOffset)
128 *(this->
mask + prevOffset) = _mm_set_epi64x(partialMask[0], partialMask[1]);
130 memset(&partialMask, 0,
sizeof(partialMask));
132 uint32_t mod = (i.id % 128);
133 partialMask[mod / 64] |= 1ull << mod;
136 *(this->
mask + offset) = _mm_set_epi64x(partialMask[0], partialMask[1]);
140 this->
mask =
nullptr;
156 for (
int i = 0; i < this->
size; i++)
157 this->
mask[i] = _mm_load_si128(rhs.
mask + i);
161 this->
mask =
nullptr;
171 if (this->
mask !=
nullptr)
181 if (this->
size != rhs.
size || this->size == 0 || rhs.
size == 0)
186 for (
int i = 0; i < this->
size; i++)
188 __m128i temp = _mm_cmpeq_epi32(this->
mask[i], rhs.
mask[i]);
189 if ((_mm_movemask_epi8(temp) != 0xFFFF))
202 int offset = component.id / 128;
203 if (offset < this->
size)
205 alignas(16) uint64_t partialMask[2] = { 0, 0 };
206 uint64_t
const bit = component.id % 128;
207 partialMask[bit / 64] |= 1ull << bit;
208 __m128i temp = _mm_set_epi64x(partialMask[0], partialMask[1]);
209 int const isSet = !_mm_testz_si128(temp, this->
mask[offset]);
222 int offset = component.id / 128;
224 alignas(16) uint64_t partialMask[2] = { 0, 0 };
225 uint64_t bit = component.id % 128;
226 partialMask[bit / 64] |= 1ull << bit;
227 __m128i temp = _mm_set_epi64x(partialMask[0], partialMask[1]);
228 this->
mask[offset] = _mm_xor_si128(this->
mask[offset], temp);
237 int offset = component.id / 128;
238 if (offset >= this->
size)
240 uint8_t newSize = offset + 1;
241 __m128i* newMask = (__m128i*)
Memory::Alloc(Memory::HeapType::ObjectHeap, newSize * 16);
242 if (this->
mask !=
nullptr)
244 for (
int i = 0; i < this->
size; i++)
245 newMask[i] = _mm_load_si128(this->
mask + i);
249 this->
mask = newMask;
250 this->
size = newSize;
252 alignas(16) uint64_t partialMask[2] = {0, 0};
253 uint64_t bit = component.id % 128;
254 partialMask[bit / 64] |= 1ull << bit;
255 __m128i temp = _mm_set_epi64x(partialMask[0], partialMask[1]);
256 this->
mask[offset] = _mm_or_si128(this->
mask[offset], temp);
265 int offset = component.id / 128;
267 alignas(16) uint64_t partialMask[2] = {0, 0};
268 uint64_t bit = component.id % 128;
269 partialMask[bit / 64] |= 1ull << bit;
270 __m128i temp = _mm_set_epi64x(partialMask[0], partialMask[1]);
271 this->
mask[offset] = _mm_andnot_si128(temp, this->
mask[offset]);
284 for (
int i = 0; i < this->
size; i++)
285 this->
mask[i] = _mm_load_si128(rhs.
mask + i);
289 this->
mask =
nullptr;
302 if (src.
size == 0 ||
mask.size == 0)
308 __m128i cmp = _mm_cmpeq_epi32(
mask.mask[
mask.size - 1], _mm_setzero_si128());
309 n_assert(_mm_movemask_epi8(cmp) != 0xFFFF);
318 for (
int i = 0; i <
mask.size; i++)
320 __m128i temp = _mm_and_si128(src.
mask[i],
mask.mask[i]);
321 __m128i cmp = _mm_cmpeq_epi32(temp,
mask.mask[i]);
322 if ((_mm_movemask_epi8(cmp) != 0xFFFF))
337 if (src.
size == 0 ||
mask.size == 0)
343 __m128i cmp = _mm_cmpeq_epi32(
mask.mask[
mask.size - 1], _mm_setzero_si128());
344 n_assert(_mm_movemask_epi8(cmp) != 0xFFFF);
350 for (
int i = 0; i <
size; i++)
352 __m128i temp = _mm_and_si128(src.
mask[i],
mask.mask[i]);
353 __m128i cmp = _mm_cmpeq_epi32(temp, _mm_setzero_si128());
354 if ((_mm_movemask_epi8(cmp) == 0xFFFF))
Basically a bitfield with packed ComponentIds.
Definition tablesignature.h:26
static bool const CheckBits(TableSignature const &src, TableSignature const &mask)
(src & mask) == mask
Definition tablesignature.h:300
bool const operator==(TableSignature const &rhs) const
equality operator
Definition tablesignature.h:179
void FlipBit(AttributeId component)
flip a bit.
Definition tablesignature.h:220
TableSignature & operator=(TableSignature const &rhs)
assignment operator
Definition tablesignature.h:278
uint8_t size
number of SSE regs allocated
Definition tablesignature.h:67
TableSignature()
default constructor.
Definition tablesignature.h:29
~TableSignature()
destructor
Definition tablesignature.h:169
bool const IsValid() const
check if signature is valid
Definition tablesignature.h:45
void SetBit(AttributeId component)
set a bit.
Definition tablesignature.h:235
__m128i * mask
large bit field, using SSE registers
Definition tablesignature.h:65
bool const IsSet(AttributeId component) const
check if a single bit is set
Definition tablesignature.h:200
void Setup(AttributeId const *descriptors, SizeT num)
create bitfield from fixed array.
Definition tablesignature.h:102
void ClearBit(AttributeId component)
clear a bit.
Definition tablesignature.h:263
static bool const HasAny(TableSignature const &src, TableSignature const &mask)
check if src has any of the bits in mask set ((src & mask) == 0)
Definition tablesignature.h:335
Nebula's dynamic array class.
Definition array.h:60
Iterator End() const
return iterator to end of array
Definition array.h:1265
void Sort()
sort the array
Definition array.h:1434
Implements a fixed size one-dimensional array.
Definition fixedarray.h:20
Iterator Begin() const
get iterator to first element
Definition fixedarray.h:598
const SizeT Size() const
get number of elements
Definition fixedarray.h:532
#define n_assert(exp)
Definition debug.h:50
__forceinline TYPE min(TYPE a, TYPE b)
Definition scalar.h:390
Attribute.
Definition attribute.h:26
void * Alloc(HeapType heapType, size_t size, size_t alignment)
Allocate a block of memory from one of the global heaps.
Definition osxmemory.cc:56
void Free(HeapType heapType, void *ptr)
Free a block of memory.
Definition osxmemory.cc:136
Definition attributeid.h:19
int SizeT
Definition types.h:49
unsigned int uint
Definition types.h:31