124 lines
3.3 KiB
C++
124 lines
3.3 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose: Provide a class (SSE/SIMD only) holding a 2d matrix of class
|
|
// FourVectors, for high speed processing in tools.
|
|
//
|
|
// $NoKeywords: $
|
|
//
|
|
//=============================================================================//
|
|
|
|
#ifndef SIMDVECTORMATRIX_H
|
|
#define SIMDVECTORMATRIX_H
|
|
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
#include <string.h>
|
|
#include "mathlib/ssemath.h"
|
|
#include "tier0/dbg.h"
|
|
#include "tier0/platform.h"
|
|
#include "tier1/utlsoacontainer.h"
|
|
|
|
class CSIMDVectorMatrix {
|
|
public:
|
|
int m_nWidth; // in actual vectors
|
|
int m_nHeight;
|
|
|
|
int m_nPaddedWidth; // # of 4x wide elements
|
|
|
|
FourVectors *m_pData;
|
|
|
|
protected:
|
|
void Init(void) {
|
|
m_pData = NULL;
|
|
m_nWidth = 0;
|
|
m_nHeight = 0;
|
|
m_nPaddedWidth = 0;
|
|
}
|
|
|
|
int NVectors(void) const { return m_nHeight * m_nPaddedWidth; }
|
|
|
|
public:
|
|
// constructors and destructors
|
|
CSIMDVectorMatrix(void) { Init(); }
|
|
|
|
~CSIMDVectorMatrix(void) {
|
|
if (m_pData) delete[] m_pData;
|
|
}
|
|
|
|
// set up storage and fields for m x n matrix. destroys old data
|
|
void SetSize(int width, int height) {
|
|
if ((!m_pData) || (width != m_nWidth) || (height != m_nHeight)) {
|
|
if (m_pData) delete[] m_pData;
|
|
|
|
m_nWidth = width;
|
|
m_nHeight = height;
|
|
|
|
m_nPaddedWidth = (m_nWidth + 3) >> 2;
|
|
m_pData = NULL;
|
|
if (width && height)
|
|
m_pData = new FourVectors[m_nPaddedWidth * m_nHeight];
|
|
}
|
|
}
|
|
|
|
CSIMDVectorMatrix(int width, int height) {
|
|
Init();
|
|
SetSize(width, height);
|
|
}
|
|
|
|
CSIMDVectorMatrix &operator=(CSIMDVectorMatrix const &src) {
|
|
SetSize(src.m_nWidth, src.m_nHeight);
|
|
if (m_pData)
|
|
memcpy(m_pData, src.m_pData,
|
|
m_nHeight * m_nPaddedWidth * sizeof(m_pData[0]));
|
|
return *this;
|
|
}
|
|
|
|
CSIMDVectorMatrix &operator+=(CSIMDVectorMatrix const &src);
|
|
|
|
CSIMDVectorMatrix &operator*=(Vector const &src);
|
|
|
|
// create from an RGBA float bitmap. alpha ignored.
|
|
void CreateFromRGBA_FloatImageData(int srcwidth, int srcheight,
|
|
float const *srcdata);
|
|
|
|
// create from 3 fields in a csoa
|
|
void CreateFromCSOAAttributes(CSOAContainer const *pSrc, int nAttrIdx0,
|
|
int nAttrIdx1, int nAttrIdx2);
|
|
|
|
// Element access. If you are calling this a lot, you don't want to use this
|
|
// class, because you're not getting the sse advantage
|
|
Vector Element(int x, int y) const {
|
|
Assert(m_pData);
|
|
Assert(x < m_nWidth);
|
|
Assert(y < m_nHeight);
|
|
Vector ret;
|
|
FourVectors const *pData = m_pData + y * m_nPaddedWidth + (x >> 2);
|
|
|
|
int xo = (x & 3);
|
|
ret.x = pData->X(xo);
|
|
ret.y = pData->Y(xo);
|
|
ret.z = pData->Z(xo);
|
|
return ret;
|
|
}
|
|
|
|
// addressing the individual fourvectors elements
|
|
FourVectors &CompoundElement(int x, int y) {
|
|
Assert(m_pData);
|
|
Assert(y < m_nHeight);
|
|
Assert(x < m_nPaddedWidth);
|
|
return m_pData[x + m_nPaddedWidth * y];
|
|
}
|
|
|
|
// math operations on the whole image
|
|
void Clear(void) {
|
|
Assert(m_pData);
|
|
memset(m_pData, 0, m_nHeight * m_nPaddedWidth * sizeof(m_pData[0]));
|
|
}
|
|
|
|
void RaiseToPower(float power);
|
|
};
|
|
|
|
#endif
|