mirror of
https://github.com/0TheSpy/Seaside.git
synced 2025-01-11 03:32:10 +08:00
300 lines
6.8 KiB
C++
300 lines
6.8 KiB
C++
#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 |