Seaside/SpyCustom/sdk/utlsoacontainer.h

300 lines
6.8 KiB
C
Raw Normal View History

2021-06-16 18:49:07 +03:00
#ifndef UTLSOACONTAINER_H
#define UTLSOACONTAINER_H
#ifdef _WIN32
#pragma once
#endif
#include "platform.h"
#include "dbg.h"
#include "threadtools.h"
#include "utlmemory.h"
#include "utlblockmemory.h"
#include "ssemath.h"
template<class T> class CStridedPtr
{
protected:
T* m_pData;
size_t m_nStride;
public:
FORCEINLINE CStridedPtr<T>(void* pData, size_t nByteStride)
{
m_pData = reinterpret_cast<T*>(pData);
m_nStride = nByteStride / sizeof(T);
}
FORCEINLINE CStridedPtr<T>(void) {}
T* operator->(void) const
{
return m_pData;
}
T& operator*(void) const
{
return *m_pData;
}
FORCEINLINE operator T* (void)
{
return m_pData;
}
FORCEINLINE CStridedPtr<T>& operator++(void)
{
m_pData += m_nStride;
return *this;
}
FORCEINLINE void operator+=(size_t nNumElements)
{
m_pData += nNumElements * m_nStride;
}
};
template<class T> class CStridedConstPtr
{
protected:
const T* m_pData;
size_t m_nStride;
public:
FORCEINLINE CStridedConstPtr<T>(void const* pData, size_t nByteStride)
{
m_pData = reinterpret_cast<T const*>(pData);
m_nStride = nByteStride / sizeof(T);
}
FORCEINLINE CStridedConstPtr<T>(void) {}
const T* operator->(void) const
{
return m_pData;
}
const T& operator*(void) const
{
return *m_pData;
}
FORCEINLINE operator const T* (void) const
{
return m_pData;
}
FORCEINLINE CStridedConstPtr<T>& operator++(void)
{
m_pData += m_nStride;
return *this;
}
FORCEINLINE void operator+=(size_t nNumElements)
{
m_pData += nNumElements * m_nStride;
}
};
enum EAttributeDataType
{
ATTRDATATYPE_FLOAT = 0,
ATTRDATATYPE_4V = 1,
ATTRDATATYPE_INT = 2,
ATTRDATATYPE_POINTER = 3,
ATTRDATATYPE_NONE = -1,
};
#define MAX_SOA_FIELDS 32
class CSOAContainer
{
protected:
int m_nColumns;
int m_nRows;
int m_nSlices;
int m_nPaddedColumns;
int m_nNumQuadsPerRow;
uint8* m_pDataMemory;
uint8* m_pAttributePtrs[MAX_SOA_FIELDS];
EAttributeDataType m_nDataType[MAX_SOA_FIELDS];
size_t m_nStrideInBytes[MAX_SOA_FIELDS];
size_t m_nRowStrideInBytes[MAX_SOA_FIELDS];
size_t m_nSliceStrideInBytes[MAX_SOA_FIELDS];
uint32 m_nFieldPresentMask;
FORCEINLINE void Init(void)
{
memset(m_nDataType, 0xff, sizeof(m_nDataType));
m_pDataMemory = 0;
m_nColumns = m_nPaddedColumns = m_nRows = m_nSlices = 0;
m_nFieldPresentMask = 0;
}
public:
CSOAContainer(void)
{
Init();
}
void Purge(void);
~CSOAContainer(void);
CSOAContainer(int nCols, int nRows, ...);
size_t ElementSize(void) const;
FORCEINLINE void SetAttributeType(int nAttrIdx, EAttributeDataType nDataType, bool bAllocateMemory = true)
{
Assert(!m_pDataMemory);
Assert(nAttrIdx < MAX_SOA_FIELDS);
m_nDataType[nAttrIdx] = nDataType;
if ((m_nDataType[nAttrIdx] != ATTRDATATYPE_NONE) && bAllocateMemory)
m_nFieldPresentMask |= (1 << nAttrIdx);
else
m_nFieldPresentMask &= ~(1 << nAttrIdx);
}
FORCEINLINE int NumRows(void) const
{
return m_nRows;
}
FORCEINLINE int NumCols(void) const
{
return m_nColumns;
}
FORCEINLINE int NumSlices(void) const
{
return m_nSlices;
}
FORCEINLINE void AssertDataType(int nAttrIdx, EAttributeDataType nDataType) const
{
Assert(nAttrIdx >= 0);
Assert(nAttrIdx < MAX_SOA_FIELDS);
Assert(m_nStrideInBytes[nAttrIdx]);
}
FORCEINLINE int NumQuadsPerRow(void) const
{
return m_nNumQuadsPerRow;
}
FORCEINLINE int Count(void) const
{
return NumCols();
}
FORCEINLINE int NumElements(void) const
{
return NumCols() * NumRows() * NumSlices();
}
FORCEINLINE size_t RowToRowStep(int nAttrIdx) const
{
return 0;
}
FORCEINLINE void* RowPtr(int nAttributeIdx, int nRowNumber, int nSliceNumber = 0) const
{
Assert(nRowNumber < m_nRows);
Assert(nAttributeIdx < MAX_SOA_FIELDS);
Assert(m_nDataType[nAttributeIdx] != ATTRDATATYPE_NONE);
Assert(m_nFieldPresentMask & (1 << nAttributeIdx));
return m_pAttributePtrs[nAttributeIdx] +
+nRowNumber * m_nRowStrideInBytes[nAttributeIdx]
+ nSliceNumber * m_nSliceStrideInBytes[nAttributeIdx];
}
FORCEINLINE void const* ConstRowPtr(int nAttributeIdx, int nRowNumber, int nSliceNumber = 0) const
{
Assert(nRowNumber < m_nRows);
Assert(nAttributeIdx < MAX_SOA_FIELDS);
Assert(m_nDataType[nAttributeIdx] != ATTRDATATYPE_NONE);
return m_pAttributePtrs[nAttributeIdx]
+ nRowNumber * m_nRowStrideInBytes[nAttributeIdx]
+ nSliceNumber * m_nSliceStrideInBytes[nAttributeIdx];
}
template<class T> FORCEINLINE T* ElementPointer(int nAttributeIdx,
int nX = 0, int nY = 0, int nZ = 0) const
{
Assert(nAttributeIdx < MAX_SOA_FIELDS);
Assert(nX < m_nColumns);
Assert(nY < m_nRows);
Assert(nZ < m_nSlices);
Assert(m_nDataType[nAttributeIdx] != ATTRDATATYPE_NONE);
Assert(m_nDataType[nAttributeIdx] != ATTRDATATYPE_4V);
return reinterpret_cast<T*>(m_pAttributePtrs[nAttributeIdx]
+ nX * sizeof(float)
+ nY * m_nRowStrideInBytes[nAttributeIdx]
+ nZ * m_nSliceStrideInBytes[nAttributeIdx]
);
}
FORCEINLINE size_t ItemByteStride(int nAttributeIdx) const
{
Assert(nAttributeIdx < MAX_SOA_FIELDS);
Assert(m_nDataType[nAttributeIdx] != ATTRDATATYPE_NONE);
return m_nStrideInBytes[nAttributeIdx];
}
void CopyAttrFrom(CSOAContainer const& other, int nAttributeIdx);
void CopyAttrToAttr(int nSrcAttributeIndex, int nDestAttributeIndex);
FORCEINLINE void MoveDataFrom(CSOAContainer other)
{
(*this) = other;
other.Init();
}
void AllocateData(int nNCols, int nNRows, int nSlices = 1);
void RandomizeAttribute(int nAttr, float flMin, float flMax) const;
void FillAttrWithInterpolatedValues(int nAttr, float flValue00, float flValue10, float flValue01, float flValue11) const;
void FillAttrWithInterpolatedValues(int nAttr, Vector flValue00, Vector flValue10,
Vector const& flValue01, Vector const& flValue11) const;
};
class CFltX4AttributeIterator : public CStridedConstPtr<fltx4>
{
FORCEINLINE CFltX4AttributeIterator(CSOAContainer const* pContainer, int nAttribute, int nRowNumber = 0)
: CStridedConstPtr<fltx4>(pContainer->ConstRowPtr(nAttribute, nRowNumber),
pContainer->ItemByteStride(nAttribute))
{
}
};
class CFltX4AttributeWriteIterator : public CStridedPtr<fltx4>
{
FORCEINLINE CFltX4AttributeWriteIterator(CSOAContainer const* pContainer, int nAttribute, int nRowNumber = 0)
: CStridedPtr<fltx4>(pContainer->RowPtr(nAttribute, nRowNumber),
pContainer->ItemByteStride(nAttribute))
{
}
};
#endif