From: <axl...@us...> - 2010-05-18 14:48:40
|
Revision: 734 http://hgengine.svn.sourceforge.net/hgengine/?rev=734&view=rev Author: axlecrusher Date: 2010-05-18 14:48:33 +0000 (Tue, 18 May 2010) Log Message: ----------- Faster matrix multiplication (7.3 time samples down to 1.8 in the profiler). Much faster LoadIdentity function (6.58 to 0.34 time samples in the profiler). Modified Paths: -------------- Mercury2/src/MercuryMath.cpp Mercury2/src/MercuryMath.h Mercury2/src/MercuryMatrix.cpp Modified: Mercury2/src/MercuryMath.cpp =================================================================== --- Mercury2/src/MercuryMath.cpp 2010-05-17 23:58:27 UTC (rev 733) +++ Mercury2/src/MercuryMath.cpp 2010-05-18 14:48:33 UTC (rev 734) @@ -242,42 +242,114 @@ void MatrixMultiply4f( const FloatRow* in1, const FloatRow* in2, FloatRow* out) { - unsigned int y; - __m128 xmm[4], a[4], b[4]; + unsigned int y = 0; + __m128 xmm[4], b[4]; -// PREFETCH(in1, _MM_HINT_T0); -// PREFETCH(in2, _MM_HINT_T1); -// PREFETCH(out, _MM_HINT_T1); + b[3] = _mm_load_ps(in1[0]); //use b3 as temporary storage for matrix1 row1 + + //start loading matrix2 b[0] = _mm_load_ps(in2[0]); b[1] = _mm_load_ps(in2[1]); b[2] = _mm_load_ps(in2[2]); - b[3] = _mm_load_ps(in2[3]); + + //load row1 of matrix1 into columns + xmm[0] = _mm_shuffle_ps (b[3], b[3], 0x00); + xmm[1] = _mm_shuffle_ps (b[3], b[3], 0x55); + xmm[2] = _mm_shuffle_ps (b[3], b[3], 0xaa); + xmm[3] = _mm_shuffle_ps (b[3], b[3], 0xff); - for (y = 0; y < 4; ++y) + b[3] = _mm_load_ps(in2[3]); //finish loading matrix2, do not change b after this! +/* + do { - a[y] = _mm_load_ps(in1[y]); - - //load rows as columns - xmm[3] = _mm_shuffle_ps (a[y], a[y], 0xff); - xmm[2] = _mm_shuffle_ps (a[y], a[y], 0xaa); - xmm[1] = _mm_shuffle_ps (a[y], a[y], 0x55); - xmm[0] = _mm_shuffle_ps (a[y], a[y], 0x00); - xmm[0] = _mm_mul_ps( xmm[0], b[0] ); xmm[1] = _mm_mul_ps( xmm[1], b[1] ); + xmm[0] = _mm_add_ps( xmm[0], xmm[1] ); //done with xmm1 + + xmm[1] = _mm_load_ps(in1[y+1]); //load next row, shuffle this last + xmm[2] = _mm_mul_ps( xmm[2], b[2] ); xmm[3] = _mm_mul_ps( xmm[3], b[3] ); + xmm[2] = _mm_add_ps( xmm[2], xmm[3] ); //done with xmm3 - xmm[0] = _mm_add_ps( xmm[0], xmm[1] ); - xmm[2] = _mm_add_ps( xmm[2], xmm[3] ); - a[y] = _mm_add_ps( xmm[0], xmm[2] ); - } + xmm[2] = _mm_add_ps( xmm[0], xmm[2] ); //final result + _mm_store_ps(out[y++], xmm[2]); - //try to use the CPU's write-combining - _mm_store_ps(out[0], a[0]); - _mm_store_ps(out[1], a[1]); - _mm_store_ps(out[2], a[2]); - _mm_store_ps(out[3], a[3]); + xmm[3] = _mm_shuffle_ps (xmm[1], xmm[1], 0xff); + xmm[0] = _mm_shuffle_ps (xmm[1], xmm[1], 0x00); + xmm[2] = _mm_shuffle_ps (xmm[1], xmm[1], 0xaa); + xmm[1] = _mm_shuffle_ps (xmm[1], xmm[1], 0x55); + } while (y < 4); +*/ + //manually unroll loop, much faster!! + //loop 1 + xmm[0] = _mm_mul_ps( xmm[0], b[0] ); + xmm[1] = _mm_mul_ps( xmm[1], b[1] ); + xmm[0] = _mm_add_ps( xmm[0], xmm[1] ); //done with xmm1 + + xmm[1] = _mm_load_ps(in1[1]); //load next row, shuffle this last + + xmm[2] = _mm_mul_ps( xmm[2], b[2] ); + xmm[3] = _mm_mul_ps( xmm[3], b[3] ); + xmm[2] = _mm_add_ps( xmm[2], xmm[3] ); //done with xmm3 + + xmm[2] = _mm_add_ps( xmm[0], xmm[2] ); //final result + _mm_store_ps(out[0], xmm[2]); + + xmm[3] = _mm_shuffle_ps (xmm[1], xmm[1], 0xff); + xmm[0] = _mm_shuffle_ps (xmm[1], xmm[1], 0x00); + xmm[2] = _mm_shuffle_ps (xmm[1], xmm[1], 0xaa); + xmm[1] = _mm_shuffle_ps (xmm[1], xmm[1], 0x55); + + //loop2 + xmm[0] = _mm_mul_ps( xmm[0], b[0] ); + xmm[1] = _mm_mul_ps( xmm[1], b[1] ); + xmm[0] = _mm_add_ps( xmm[0], xmm[1] ); //done with xmm1 + + xmm[1] = _mm_load_ps(in1[2]); //load next row, shuffle this last + + xmm[2] = _mm_mul_ps( xmm[2], b[2] ); + xmm[3] = _mm_mul_ps( xmm[3], b[3] ); + xmm[2] = _mm_add_ps( xmm[2], xmm[3] ); //done with xmm3 + + xmm[2] = _mm_add_ps( xmm[0], xmm[2] ); //final result + _mm_store_ps(out[1], xmm[2]); + + xmm[3] = _mm_shuffle_ps (xmm[1], xmm[1], 0xff); + xmm[0] = _mm_shuffle_ps (xmm[1], xmm[1], 0x00); + xmm[2] = _mm_shuffle_ps (xmm[1], xmm[1], 0xaa); + xmm[1] = _mm_shuffle_ps (xmm[1], xmm[1], 0x55); + + //loop3 + xmm[0] = _mm_mul_ps( xmm[0], b[0] ); + xmm[1] = _mm_mul_ps( xmm[1], b[1] ); + xmm[0] = _mm_add_ps( xmm[0], xmm[1] ); //done with xmm1 + + xmm[1] = _mm_load_ps(in1[3]); //load next row, shuffle this last + + xmm[2] = _mm_mul_ps( xmm[2], b[2] ); + xmm[3] = _mm_mul_ps( xmm[3], b[3] ); + xmm[2] = _mm_add_ps( xmm[2], xmm[3] ); //done with xmm3 + + xmm[2] = _mm_add_ps( xmm[0], xmm[2] ); //final result + _mm_store_ps(out[2], xmm[2]); + + xmm[3] = _mm_shuffle_ps (xmm[1], xmm[1], 0xff); + xmm[0] = _mm_shuffle_ps (xmm[1], xmm[1], 0x00); + xmm[2] = _mm_shuffle_ps (xmm[1], xmm[1], 0xaa); + xmm[1] = _mm_shuffle_ps (xmm[1], xmm[1], 0x55); + + //loop4 + xmm[0] = _mm_mul_ps( xmm[0], b[0] ); + xmm[1] = _mm_mul_ps( xmm[1], b[1] ); + xmm[0] = _mm_add_ps( xmm[0], xmm[1] ); //done with xmm1 + + xmm[2] = _mm_mul_ps( xmm[2], b[2] ); + xmm[3] = _mm_mul_ps( xmm[3], b[3] ); + xmm[2] = _mm_add_ps( xmm[2], xmm[3] ); //done with xmm3 + + xmm[2] = _mm_add_ps( xmm[0], xmm[2] ); //final result + _mm_store_ps(out[3], xmm[2]); } //This is an SSE matrix vector multiply, see the standard C++ code @@ -321,6 +393,22 @@ } */ +void LoadIdentity(FloatRow* matrix) +{ + float *m = (float*)matrix; + + __m128 r[2]; + + r[0] = _mm_set_ps(0.0f,0.0f,0.0f,1.0f); + _mm_storer_ps(m+12,r[0]); //reverse r[0] + + r[1] = _mm_shuffle_ps(r[0], r[0], _MM_SHUFFLE(1,1,0,1)); + _mm_storer_ps(m+8,r[1]); //reverse r[1] + + _mm_store_ps(m, r[0]); + _mm_store_ps(m+4, r[1]); +} + void MMCrossProduct( const FloatRow& r1, const FloatRow& r2, FloatRow& result) { __m128 a,b,c,d,r;//using more registers is faster Modified: Mercury2/src/MercuryMath.h =================================================================== --- Mercury2/src/MercuryMath.h 2010-05-17 23:58:27 UTC (rev 733) +++ Mercury2/src/MercuryMath.h 2010-05-18 14:48:33 UTC (rev 734) @@ -109,6 +109,7 @@ void VectorMultiply4f(const FloatRow* matrix, const FloatRow& p, FloatRow& out ); void TransposeMatrix( FloatRow* m ); void MMCrossProduct( const FloatRow& r1, const FloatRow& r2, FloatRow& result); +void LoadIdentity(FloatRow* matrix); //http://graphics.stanford.edu/~seander/bithacks.html #define SetBit(x,mask,t) ((x & ~mask) | (-t & mask)) /*superscalar CPU version*/ Modified: Mercury2/src/MercuryMatrix.cpp =================================================================== --- Mercury2/src/MercuryMatrix.cpp 2010-05-17 23:58:27 UTC (rev 733) +++ Mercury2/src/MercuryMatrix.cpp 2010-05-18 14:48:33 UTC (rev 734) @@ -126,9 +126,7 @@ void MercuryMatrix::LoadIdentity() { - for (uint8_t x=0;x<4;++x) - for (uint8_t y=0;y<4;++y) - m_matrix[x][y] = (x==y)?1.0f:0.0f; + ::LoadIdentity(m_matrix); } void MercuryMatrix::Translate(float x, float y, float z) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-05-18 19:58:27
|
Revision: 735 http://hgengine.svn.sourceforge.net/hgengine/?rev=735&view=rev Author: axlecrusher Date: 2010-05-18 19:58:20 +0000 (Tue, 18 May 2010) Log Message: ----------- Faster matrix transpose and memcpy apparently is faster, when optimize build Modified Paths: -------------- Mercury2/src/MercuryMath.cpp Mercury2/src/MercuryMath.h Mercury2/src/MercuryMatrix.cpp Mercury2/src/MercuryMatrix.h Modified: Mercury2/src/MercuryMath.cpp =================================================================== --- Mercury2/src/MercuryMath.cpp 2010-05-18 14:48:33 UTC (rev 734) +++ Mercury2/src/MercuryMath.cpp 2010-05-18 19:58:20 UTC (rev 735) @@ -2,10 +2,15 @@ #include "MercuryMath.h" //the SSE version of this was really slow, this is quicker -void TransposeMatrix( FloatRow* m ) + +#ifndef USE_SSE + +//Generic Math functions. Compile these if you can not use optimized functions. + +void TransposeMatrix( const FloatRow* matrix, FloatRow* out ) { float tmp; - float *_m = (float*)m; + float *_m = (float*)out; tmp = _m[1]; _m[1] = _m[4]; @@ -30,10 +35,6 @@ _m[14] = tmp; } -#ifndef USE_SSE - -//Generic Math functions. Compile these if you can not use optimized functions. - void ZeroFloatRow(FloatRow& r) { Copy4f(&r, &gfrZero ); @@ -71,21 +72,6 @@ Copy4f(out,r); } -void Copy4f( void * dest, const void * source ) -{ - COPY<float,4>((float*)source, (float*)dest); -} - -void Copy8f( void * dest, const void * source ) -{ - COPY<float,8>((float*)source, (float*)dest); -} - -void Copy16f( void * dest, const void * source ) -{ - COPY<float,16>((float*)source, (float*)dest); -} - void MatrixMultiply4f ( const FloatRow* in1a, const FloatRow* in2a, FloatRow* outa) { const float *in1 = *in1a; @@ -216,30 +202,6 @@ _mm_store_ps(out,o); } -void Copy4f( void * dest, const void * source ) -{ - _mm_stream_ps(((float*)dest),((__m128*)source)[0]); -} - -void Copy8f( void * dest, const void * source ) -{ - _mm_stream_ps(((float*)dest),((__m128*)source)[0]); - _mm_stream_ps(((float*)dest)+4,((__m128*)source)[1]); -} - -void Copy16f( void * dest, const void * source ) -{ -/* _mm_stream_si128((__m128i*)dest,((__m128i*)source)[0]); - _mm_stream_si128(&((__m128i*)dest)[1],((__m128i*)source)[1]); - _mm_stream_si128(&((__m128i*)dest)[2],((__m128i*)source)[2]); - _mm_stream_si128(&((__m128i*)dest)[3],((__m128i*)source)[3]); -*/ - _mm_stream_ps(((float*)dest),((__m128*)source)[0]); - _mm_stream_ps(((float*)dest)+4,((__m128*)source)[1]); - _mm_stream_ps(((float*)dest)+8,((__m128*)source)[2]); - _mm_stream_ps(((float*)dest)+12,((__m128*)source)[3]); -} - void MatrixMultiply4f( const FloatRow* in1, const FloatRow* in2, FloatRow* out) { unsigned int y = 0; @@ -399,7 +361,7 @@ __m128 r[2]; - r[0] = _mm_set_ps(0.0f,0.0f,0.0f,1.0f); + r[0] = _mm_set_ss(1.0f); _mm_storer_ps(m+12,r[0]); //reverse r[0] r[1] = _mm_shuffle_ps(r[0], r[0], _MM_SHUFFLE(1,1,0,1)); @@ -409,9 +371,42 @@ _mm_store_ps(m+4, r[1]); } +void TransposeMatrix( const FloatRow* matrix, FloatRow* out ) +{ + //compiler acts better when we send in 2 parameter rather than 1 + __m128 m[4],r[4]; + + m[0] = _mm_load_ps(matrix[0]); + m[1] = _mm_load_ps(matrix[1]); + m[2] = _mm_load_ps(matrix[2]); + m[3] = _mm_load_ps(matrix[3]); + + r[0] = _mm_movelh_ps(m[0],m[1]); + r[1] = _mm_movelh_ps(m[2],m[3]); + r[2] = _mm_movehl_ps(m[1],m[0]); + r[3] = _mm_movehl_ps(m[3],m[2]); + //done with m matrix, we can reuse it now + + m[0] = _mm_shuffle_ps(r[0], r[0], _MM_SHUFFLE(3,1,2,0)); //produce beginning of new row 0 and 1 + m[1] = _mm_shuffle_ps(r[1], r[1], _MM_SHUFFLE(3,1,2,0)); //produce ending of new row 0 and 1 + m[2] = _mm_shuffle_ps(r[2], r[2], _MM_SHUFFLE(3,1,2,0)); //produce beginning of new row 2 and 3 + m[3] = _mm_shuffle_ps(r[3], r[3], _MM_SHUFFLE(3,1,2,0)); //produce ending of new row 2 and 3 + + r[0] = _mm_movelh_ps(m[0],m[1]); //row 0 is done + r[2] = _mm_movelh_ps(m[2],m[3]); //row 2 is done + r[1] = _mm_movehl_ps(m[1],m[0]); //row 1 is done + r[3] = _mm_movehl_ps(m[3],m[2]); //row 3 is done + + _mm_store_ps(out[0], r[0]); + _mm_store_ps(out[1], r[1]); + _mm_store_ps(out[2], r[2]); + _mm_store_ps(out[3], r[3]); +} + void MMCrossProduct( const FloatRow& r1, const FloatRow& r2, FloatRow& result) { - __m128 a,b,c,d,r;//using more registers is faster + //using more registers is faster(8 maximum) + __m128 a,b,c,d,r; __m128 t1,t2; //unaligned load, vectors are not aligned Modified: Mercury2/src/MercuryMath.h =================================================================== --- Mercury2/src/MercuryMath.h 2010-05-18 14:48:33 UTC (rev 734) +++ Mercury2/src/MercuryMath.h 2010-05-18 19:58:20 UTC (rev 735) @@ -102,18 +102,22 @@ void Div4f(const FloatRow& first, const FloatRow& second, FloatRow& out); void Add4f(const FloatRow& first, const FloatRow& second, FloatRow& out); void Sub4f(const FloatRow& first, const FloatRow& second, FloatRow& out); -void Copy4f( void * dest, const void * source ); -void Copy8f( void * dest, const void * source ); -void Copy16f( void * dest, const void * source ); +inline void Copy4f( void * dest, const void * source ) { memcpy(dest,source,16); } +inline void Copy8f( void * dest, const void * source ) { memcpy(dest,source,32); } +inline void Copy16f( void * dest, const void * source ) { memcpy(dest,source,64); } void MatrixMultiply4f ( const FloatRow* in1, const FloatRow* in2, FloatRow* out ); void VectorMultiply4f(const FloatRow* matrix, const FloatRow& p, FloatRow& out ); -void TransposeMatrix( FloatRow* m ); +void TransposeMatrix(const FloatRow* matrix, FloatRow* out); void MMCrossProduct( const FloatRow& r1, const FloatRow& r2, FloatRow& result); void LoadIdentity(FloatRow* matrix); //http://graphics.stanford.edu/~seander/bithacks.html -#define SetBit(x,mask,t) ((x & ~mask) | (-t & mask)) /*superscalar CPU version*/ -#define GetBit(x,mask) ((x & mask)>0) +inline unsigned int SetBit(unsigned int x, unsigned int mask, bool t) +{ + #pragma warning( disable : 4804 ) + return ((x & ~mask) | (-t & mask)); /*superscalar CPU version*/ +} +inline bool GetBit(unsigned int x, unsigned int mask) { return ((x & mask)>0); } //void Float2FloatRow(const float* f, FloatRow& r); //void FloatRow2Float(const FloatRow& fr, float* f); Modified: Mercury2/src/MercuryMatrix.cpp =================================================================== --- Mercury2/src/MercuryMatrix.cpp 2010-05-18 14:48:33 UTC (rev 734) +++ Mercury2/src/MercuryMatrix.cpp 2010-05-18 19:58:20 UTC (rev 735) @@ -25,6 +25,18 @@ for (unsigned int i = 0; i < rows;i++) m_free.push_back( m_data.Buffer()+i ); +/* + //test matrix transpose + MercuryMatrix test; + for (int i = 0; i < 16; ++i) + test.Ptr()[i] = i+1; + + LOG.Write("before transpose\n"); + test.Print(); + test.Transpose(); + LOG.Write("after Transpose\n"); + test.Print(); + */ } FloatRow* MercuryMatrixMemory::GetNewMatrix() @@ -45,26 +57,10 @@ MSemaphoreLock lock(&m_lock); m_free.push_back((MatrixArray*)m); } -/* -VC_ALIGN(16) float base_matrix_identity[16] CC_ALIGN(16) = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f }; -*/ + MercuryMatrix::MercuryMatrix() :m_matrix(0) -{/* -#ifdef USE_SSE - m_matrix[0] = _mm_load1_ps( &base_matrix_identity[0] ); - m_matrix[1] = _mm_load1_ps( &base_matrix_identity[4] ); - m_matrix[2] = _mm_load1_ps( &base_matrix_identity[8] ); - m_matrix[3] = _mm_load1_ps( &base_matrix_identity[12] ); -#else - Copy16f(m_matrix[0], base_matrix_identity ); -#endif -*/ -// *this = Identity(); +{ m_matrix = MercuryMatrixMemory::GetInstance().GetNewMatrix(); LoadIdentity(); } @@ -292,6 +288,14 @@ return r; } +void MercuryMatrix::Transpose() +{ + //we know we will be operating on this data so try to go get it, 3-4x increase in speed. + PREFETCH((const char*)m_matrix,_MM_HINT_NTA); + TransposeMatrix( m_matrix, m_matrix ); +} + + MercuryMatrix MercuryMatrix::IdentityMatrix; /* Modified: Mercury2/src/MercuryMatrix.h =================================================================== --- Mercury2/src/MercuryMatrix.h 2010-05-18 14:48:33 UTC (rev 734) +++ Mercury2/src/MercuryMatrix.h 2010-05-18 19:58:20 UTC (rev 735) @@ -77,7 +77,7 @@ inline void Scale(const MercuryVertex& v) { Scale(v[0], v[1], v[2]); } void Transotale( float tX, float tY, float tZ, float rX, float rY, float rZ, float sX, float sY, float sZ ); - inline void Transpose() { TransposeMatrix( m_matrix ); } + void Transpose(); void Zero(); static const MercuryMatrix& Identity(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-05-19 16:42:39
|
Revision: 741 http://hgengine.svn.sourceforge.net/hgengine/?rev=741&view=rev Author: axlecrusher Date: 2010-05-19 16:42:33 +0000 (Wed, 19 May 2010) Log Message: ----------- should be constant and public Modified Paths: -------------- Mercury2/src/MercuryMatrix.cpp Mercury2/src/MercuryMatrix.h Modified: Mercury2/src/MercuryMatrix.cpp =================================================================== --- Mercury2/src/MercuryMatrix.cpp 2010-05-18 20:22:07 UTC (rev 740) +++ Mercury2/src/MercuryMatrix.cpp 2010-05-19 16:42:33 UTC (rev 741) @@ -296,7 +296,7 @@ } -MercuryMatrix MercuryMatrix::IdentityMatrix; +const MercuryMatrix MercuryMatrix::IdentityMatrix; /* * Copyright (c) 2006-2009 Joshua Allen Modified: Mercury2/src/MercuryMatrix.h =================================================================== --- Mercury2/src/MercuryMatrix.h 2010-05-18 20:22:07 UTC (rev 740) +++ Mercury2/src/MercuryMatrix.h 2010-05-19 16:42:33 UTC (rev 741) @@ -41,7 +41,6 @@ // FloatRow m_matrix[4]; FloatRow* m_matrix; - static MercuryMatrix IdentityMatrix; public: MercuryMatrix(); MercuryMatrix(const MercuryMatrix& m); @@ -84,6 +83,8 @@ void LoadIdentity(); void Print() const; + + const static MercuryMatrix IdentityMatrix; }; static InstanceCounter<MercuryMatrixMemory> MMMcounter("MercuryMatrixMemory"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-05-19 22:05:58
|
Revision: 742 http://hgengine.svn.sourceforge.net/hgengine/?rev=742&view=rev Author: axlecrusher Date: 2010-05-19 22:05:52 +0000 (Wed, 19 May 2010) Log Message: ----------- Clean setting and using matrix pointers. This causes a large speedup of all matrix math operations. I suspect this is much friendlier to the CPU cache. Modified Paths: -------------- Mercury2/src/Camera.cpp Mercury2/src/Light.cpp Mercury2/src/Mercury2.cpp Mercury2/src/MercuryNode.cpp Mercury2/src/MercuryNode.h Mercury2/src/RenderGraph.cpp Mercury2/src/TransformNode.cpp Mercury2/src/TransformNode.h Modified: Mercury2/src/Camera.cpp =================================================================== --- Mercury2/src/Camera.cpp 2010-05-19 16:42:33 UTC (rev 741) +++ Mercury2/src/Camera.cpp 2010-05-19 22:05:52 UTC (rev 742) @@ -45,7 +45,7 @@ { m_tainted = false; - MercuryMatrix local, parent(GetParentMatrix()); + MercuryMatrix local, parent(*m_pGlobalMatrix); MQuaternion r( GetRotation() ); Modified: Mercury2/src/Light.cpp =================================================================== --- Mercury2/src/Light.cpp 2010-05-19 16:42:33 UTC (rev 741) +++ Mercury2/src/Light.cpp 2010-05-19 22:05:52 UTC (rev 742) @@ -30,8 +30,8 @@ void Light::Render(const MercuryMatrix& matrix) { - m_worldPosition = FindModelViewMatrix(); - m_worldPosition2 = FindGlobalMatrix(); + m_worldPosition = GetModelViewMatrix(); + m_worldPosition2 = GetGlobalMatrix(); CURRENTRENDERGRAPH->AddDifferedLight( this ); // m_boundingVolume->Render(); // m_parent = node; Modified: Mercury2/src/Mercury2.cpp =================================================================== --- Mercury2/src/Mercury2.cpp 2010-05-19 16:42:33 UTC (rev 741) +++ Mercury2/src/Mercury2.cpp 2010-05-19 22:05:52 UTC (rev 742) @@ -35,7 +35,7 @@ bool SHOWBOUNDINGVOLUME = false; bool SHOWAXISES = false; bool DOOCCLUSIONCULL = false; - +/* MSemaphore UpdateLoopGo; void* UpdateThread(void* node) { @@ -46,7 +46,7 @@ } return NULL; } - +*/ int SignalHandler( int signal ) { char buffer[2048]; @@ -144,9 +144,12 @@ do { timer.Touch(); + + root->RecursiveUpdate( timer.Age(), MercuryMatrix::IdentityMatrix ); //comment to use threads + + //seems to work better after update. is this the correct place? MESSAGEMAN.PumpMessages( timer.MicrosecondsSinceInit() ); - root->RecursiveUpdate( timer.Age() ); //comment to use threads CURRENTRENDERGRAPH = &renderGraph; if ( MercuryNode::NeedsRebuild() ) Modified: Mercury2/src/MercuryNode.cpp =================================================================== --- Mercury2/src/MercuryNode.cpp 2010-05-19 16:42:33 UTC (rev 741) +++ Mercury2/src/MercuryNode.cpp 2010-05-19 22:05:52 UTC (rev 742) @@ -20,8 +20,8 @@ m_nextSibling(NULL), m_flags(SAVECHILDREN & ENABLESAVE), m_iPasses( DEFAULT_PASSES ), m_iForcePasses( 0 ) { - m_pGlobalMatrix = &MercuryMatrix::Identity(); - m_pModelViewMatrix = &MercuryMatrix::Identity(); + m_pGlobalMatrix = &MercuryMatrix::IdentityMatrix; + m_pModelViewMatrix = &MercuryMatrix::IdentityMatrix; } MercuryNode::~MercuryNode() @@ -192,12 +192,15 @@ return 0; } -void MercuryNode::RecursiveUpdate(float dTime) +void MercuryNode::RecursiveUpdate(float dTime, const MercuryMatrix& globalMatrix) { + m_pGlobalMatrix = &globalMatrix; + if (m_parent) m_pModelViewMatrix = m_parent->m_pModelViewMatrix; + Update(dTime); - + for (MercuryNode* child = FirstChild(); child != NULL; child = NextChild(child)) - child->RecursiveUpdate(dTime); + child->RecursiveUpdate(dTime, *m_pGlobalMatrix); } void MercuryNode::RecursivePreRender() @@ -421,40 +424,11 @@ (*i)->Asset().PostRender(this); } -const MercuryMatrix& MercuryNode::FindGlobalMatrix() const -{ - const MercuryNode* n = NULL; - const TransformNode* tn; - for (n = this; n; n = n->Parent()) - { - tn = TransformNode::Cast(n); - if ( tn ) - return tn->GetGlobalMatrix(); - } - - return MercuryMatrix::Identity(); -} - -const MercuryMatrix& MercuryNode::FindModelViewMatrix() const -{ - const MercuryNode* n = NULL; - const TransformNode* tn; - for (n = this; n; n = n->Parent()) - { - tn = TransformNode::Cast(n); - if ( tn ) - return tn->GetModelViewMatrix(); - } - - return MercuryMatrix::Identity(); -} - MercuryMatrix MercuryNode::ManipulateMatrix(const MercuryMatrix& matrix) { return VIEWMATRIX * matrix; } - NodeFactory& NodeFactory::GetInstance() { static NodeFactory* instance = NULL; Modified: Mercury2/src/MercuryNode.h =================================================================== --- Mercury2/src/MercuryNode.h 2010-05-19 16:42:33 UTC (rev 741) +++ Mercury2/src/MercuryNode.h 2010-05-19 22:05:52 UTC (rev 742) @@ -71,7 +71,7 @@ MercuryNode * TraversalNextNode( MercuryNode * stopnode, int & iDepthDelta ); virtual void Update(float dTime) {}; - virtual void RecursiveUpdate(float dTime); + virtual void RecursiveUpdate(float dTime, const MercuryMatrix& globalMatrix); void ThreadedUpdate(float dTime); @@ -170,10 +170,6 @@ // std::list< MercuryAsset* > m_render; // std::list< MercuryAsset* > m_postrender; - ///This will get the world space matrix - const MercuryMatrix& FindGlobalMatrix() const; - const MercuryMatrix& FindModelViewMatrix() const; - const MercuryMatrix * m_pGlobalMatrix; const MercuryMatrix * m_pModelViewMatrix; Modified: Mercury2/src/RenderGraph.cpp =================================================================== --- Mercury2/src/RenderGraph.cpp 2010-05-19 16:42:33 UTC (rev 741) +++ Mercury2/src/RenderGraph.cpp 2010-05-19 22:05:52 UTC (rev 742) @@ -58,14 +58,10 @@ RenderGraphEntry* lastEntry = &entry; // MercuryNode* rn = MercuryNode::Cast(node); - //Update the Matrices - node->m_pGlobalMatrix = &node->FindGlobalMatrix(); - node->m_pModelViewMatrix = &node->FindModelViewMatrix(); - if ( node ) { //found a new renderable - entry.m_children.push_back( RenderGraphEntry(&(node->FindGlobalMatrix()), node) ); + entry.m_children.push_back( RenderGraphEntry(&(node->GetGlobalMatrix()), node) ); lastEntry = &(entry.m_children.back()); } Modified: Mercury2/src/TransformNode.cpp =================================================================== --- Mercury2/src/TransformNode.cpp 2010-05-19 16:42:33 UTC (rev 741) +++ Mercury2/src/TransformNode.cpp 2010-05-19 22:05:52 UTC (rev 742) @@ -14,6 +14,8 @@ void TransformNode::Update(float dTime) { if (m_tainted) ComputeMatrix(); + m_pGlobalMatrix = &m_globalMatrix; + m_pModelViewMatrix = &m_modelView; } void TransformNode::RecursivePreRender() @@ -89,23 +91,9 @@ // m_scale[0], m_scale[1], m_scale[2] ); // local = t * local; - m_globalMatrix = GetParentMatrix() * local; + m_globalMatrix = *m_pGlobalMatrix * local; } -const MercuryMatrix& TransformNode::GetParentMatrix() const -{ - const MercuryNode* n = m_parent; - const TransformNode* tn; - while (n) - { - tn = TransformNode::Cast( n ); - if ( tn ) return tn->GetGlobalMatrix(); - n = n->Parent(); - } - - return MercuryMatrix::Identity(); -} - void TransformNode::RippleTaintDown(MercuryNode* node) { TransformNode* tn; @@ -200,11 +188,6 @@ } } -const MercuryMatrix& TransformNode::GetGlobalMatrix() const -{ - return m_globalMatrix; -} - void RotatorNode::Update(float dTime) { MQuaternion r = GetRotation(); Modified: Mercury2/src/TransformNode.h =================================================================== --- Mercury2/src/TransformNode.h 2010-05-19 16:42:33 UTC (rev 741) +++ Mercury2/src/TransformNode.h 2010-05-19 22:05:52 UTC (rev 742) @@ -23,11 +23,6 @@ inline const MercuryVertex& GetPosition() const { return m_position; } inline const MQuaternion& GetRotation() const { return m_rotation; } -// inline const MercuryMatrix& GetGlobalMatrix() const { return m_globalMatrix; } - virtual const MercuryMatrix& GetGlobalMatrix() const; - inline const MercuryMatrix& GetModelViewMatrix() const { return m_modelView; } - const MercuryMatrix& GetParentMatrix() const; - void SetTaint(bool taint); virtual void ComputeMatrix(); @@ -55,6 +50,7 @@ // MercuryMatrix m_localMatrix; protected: + //these are the matrices that should be pointed to MercuryMatrix m_modelView; MercuryMatrix m_globalMatrix; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-05-23 15:56:11
|
Revision: 748 http://hgengine.svn.sourceforge.net/hgengine/?rev=748&view=rev Author: axlecrusher Date: 2010-05-23 15:56:04 +0000 (Sun, 23 May 2010) Log Message: ----------- Change asset creation to generate keys BEFORE asking for the asset Modified Paths: -------------- Mercury2/src/MercuryAsset.cpp Mercury2/src/MercuryAsset.h Mercury2/src/MercuryNode.cpp Mercury2/src/Texture.cpp Mercury2/src/Texture.h Modified: Mercury2/src/MercuryAsset.cpp =================================================================== --- Mercury2/src/MercuryAsset.cpp 2010-05-23 12:38:12 UTC (rev 747) +++ Mercury2/src/MercuryAsset.cpp 2010-05-23 15:56:04 UTC (rev 748) @@ -154,14 +154,14 @@ return *instance; } -bool AssetFactory::RegisterFactoryCallback(const MString & type, MAutoPtr< MercuryAsset > (*functor)( const MString &, bool ) ) +bool AssetFactory::RegisterFactoryCallback(const MString & type, MAutoPtr< MercuryAsset > (*functor)( const MString &, bool, const XMLNode* n ) ) { MString t = ToUpper( type ); m_factoryCallbacks[t] = functor; return true; } -MAutoPtr<MercuryAsset> AssetFactory::Generate(const MString& type, const MString& key, bool bInstanced ) +MAutoPtr<MercuryAsset> AssetFactory::Generate(const MString& type, const MString& key, bool bInstanced, const XMLNode* n ) { MString t = ToUpper( type ); @@ -172,11 +172,11 @@ } printf( "Asset (%s) not found, generating\n", (t+key).c_str() ); - MAutoPtr< MercuryAsset > (**generator)( const MString &, bool ) = m_factoryCallbacks.get( t ); + MAutoPtr< MercuryAsset > (**generator)( const MString &, bool, const XMLNode* n ) = m_factoryCallbacks.get( t ); if( generator ) { - MAutoPtr< MercuryAsset > g = (**generator)(key, bInstanced); + MAutoPtr< MercuryAsset > g = (**generator)(key, bInstanced, n); AddAssetInstance( t+key, g.Ptr() ); g->slType = g->GetType(); return g; Modified: Mercury2/src/MercuryAsset.h =================================================================== --- Mercury2/src/MercuryAsset.h 2010-05-23 12:38:12 UTC (rev 747) +++ Mercury2/src/MercuryAsset.h 2010-05-23 15:56:04 UTC (rev 748) @@ -78,6 +78,7 @@ virtual MercuryAssetInstance * MakeAssetInstance( MercuryNode * ParentNode ); + static MString GenKey(const MString& k, const XMLNode* n) { return k; } GENRTTI( MercuryAsset ); const char * slType; //Tricky - we need to know our type in the destructor. Don't touch this. @@ -145,9 +146,9 @@ { public: static AssetFactory& GetInstance(); - bool RegisterFactoryCallback(const MString& type, MAutoPtr< MercuryAsset > (*)( const MString &, bool ) ); + bool RegisterFactoryCallback(const MString& type, MAutoPtr< MercuryAsset > (*)( const MString &, bool, const XMLNode* ) ); - MAutoPtr<MercuryAsset> Generate(const MString& type, const MString& key, bool bInstanced = true ); + MAutoPtr<MercuryAsset> Generate(const MString& type, const MString& key, bool bInstanced = true, const XMLNode* n = NULL ); void AddAssetInstance(const MString& key, MercuryAsset* asset); void RemoveAssetInstance(const MString& key); @@ -155,7 +156,7 @@ private: MAutoPtr< MercuryAsset > LocateAsset( const MString& key ) { MAutoPtr< MercuryAsset > * a = m_assetInstances.get( key ); return a?(*a):0; } - MHash< MAutoPtr< MercuryAsset > (*)( const MString &, bool ) > m_factoryCallbacks; + MHash< MAutoPtr< MercuryAsset > (*)( const MString &, bool, const XMLNode* ) > m_factoryCallbacks; //the actual storage point is in MercuryAssetInstance MHash< MAutoPtr< MercuryAsset > > m_assetInstances; @@ -167,7 +168,7 @@ static InstanceCounter<AssetFactory> AFcounter("AssetFactory"); #define REGISTER_ASSET_TYPE(class)\ - MAutoPtr<MercuryAsset> FactoryFunct##class( const MString & key, bool bInstanced ) { return new class( key, bInstanced ); } \ + MAutoPtr<MercuryAsset> FactoryFunct##class( const MString & key, bool bInstanced, const XMLNode* n) { return new class( class::GenKey(key,n), bInstanced ); } \ bool GlobalRegisterSuccess##class = AssetFactory::GetInstance().RegisterFactoryCallback(#class, FactoryFunct##class); #define CLASS_HELPERS(baseClass)\ Modified: Mercury2/src/MercuryNode.cpp =================================================================== --- Mercury2/src/MercuryNode.cpp 2010-05-23 12:38:12 UTC (rev 747) +++ Mercury2/src/MercuryNode.cpp 2010-05-23 15:56:04 UTC (rev 748) @@ -306,7 +306,8 @@ else if ( child.Name() == "asset" ) { MString key = child.Attribute("file"); - MAutoPtr< MercuryAsset > asset( AssetFactory::GetInstance().Generate( child.Attribute("type"), key ) ); + + MAutoPtr< MercuryAsset > asset( AssetFactory::GetInstance().Generate( child.Attribute("type"), key, true, &child ) ); if ( asset.IsValid() ) { asset->LoadFromXML( child ); Modified: Mercury2/src/Texture.cpp =================================================================== --- Mercury2/src/Texture.cpp 2010-05-23 12:38:12 UTC (rev 747) +++ Mercury2/src/Texture.cpp 2010-05-23 15:56:04 UTC (rev 748) @@ -152,10 +152,10 @@ if( sNewKey == m_path && GetLoadState() != NONE ) return true; - if ( m_dynamic ) - MakeDynamic( 0, 0, RGBA, sNewKey ); + if ( !m_dynamic ) + LoadImagePath( sNewKey ); else - LoadImagePath( sNewKey ); +// MakeDynamic( 0, 0, RGBA, sNewKey ); if( sNewKey != m_path ) return MercuryAsset::ChangeKey( sNewKey ); @@ -320,6 +320,18 @@ LoadImagePath(m_path); } +MString Texture::GenKey(const MString& k, const XMLNode* n) +{ + bool dynamic = false; + if (n) + { + const XMLNode& node = *n; + LOAD_FROM_XML( "dynamic", dynamic, StrToBool ); + } + if (dynamic) return "DYNATEXT"+k; + return k; +} + MAutoPtr< Texture > Texture::LoadFromFile(const MString& path) { MAutoPtr< MercuryAsset > t( AssetFactory::GetInstance().Generate("Texture", path) ); Modified: Mercury2/src/Texture.h =================================================================== --- Mercury2/src/Texture.h 2010-05-23 12:38:12 UTC (rev 747) +++ Mercury2/src/Texture.h 2010-05-23 15:56:04 UTC (rev 748) @@ -46,6 +46,8 @@ static void ApplyActiveTextures(uint16_t stride, uint8_t uvByteOffset); static void DisableUnusedTextures(); + static MString GenKey(const MString& k, const XMLNode* n); + void SetFilter( TextureFilterMode t ) { m_tFilterMode = t; } GENRTTI( Texture ); protected: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-05-23 15:56:43
|
Revision: 749 http://hgengine.svn.sourceforge.net/hgengine/?rev=749&view=rev Author: axlecrusher Date: 2010-05-23 15:56:37 +0000 (Sun, 23 May 2010) Log Message: ----------- fix windows compile VS2008 Modified Paths: -------------- Mercury2/src/MercuryMath.cpp Mercury2/src/MercuryNode.h Mercury2/src/OGLExtensions.cpp Mercury2/src/OGLExtensions.h Modified: Mercury2/src/MercuryMath.cpp =================================================================== --- Mercury2/src/MercuryMath.cpp 2010-05-23 15:56:04 UTC (rev 748) +++ Mercury2/src/MercuryMath.cpp 2010-05-23 15:56:37 UTC (rev 749) @@ -143,6 +143,13 @@ f[i] = r[i]; } */ +void LoadIdentity(FloatRow* matrix) +{ + float *m = (float*)matrix; + for (uint8_t i = 0; i < 16; ++i) + m[i] = i%5?0.0f:1.0f; +} + void MMCrossProduct( const FloatRow& r1, const FloatRow& r2, FloatRow& result) { FloatRow r; Modified: Mercury2/src/MercuryNode.h =================================================================== --- Mercury2/src/MercuryNode.h 2010-05-23 15:56:04 UTC (rev 748) +++ Mercury2/src/MercuryNode.h 2010-05-23 15:56:37 UTC (rev 749) @@ -123,19 +123,19 @@ virtual void Render(const MercuryMatrix& matrix); virtual void PostRender(const MercuryMatrix& matrix); - virtual void SetHidden( bool bHide ) { m_flags = SetBit(m_flags,HIDDEN,bHide); } //is there anyway to make this not virtual?? + virtual void SetHidden( bool bHide ) { m_flags = (uint8_t)SetBit(m_flags,HIDDEN,bHide); } //is there anyway to make this not virtual?? inline bool IsHidden() { return GetBit(m_flags,HIDDEN); } - inline void SetCulled(bool t) { m_flags = SetBit(m_flags,CULLED,t); } + inline void SetCulled(bool t) { m_flags = (uint8_t)SetBit(m_flags,CULLED,t); } inline bool IsCulled() const { return GetBit(m_flags,CULLED); } - inline void SetSaveChildren(bool t) { m_flags = SetBit(m_flags,SAVECHILDREN,t); } + inline void SetSaveChildren(bool t) { m_flags = (uint8_t)SetBit(m_flags,SAVECHILDREN,t); } inline bool GetSaveChildren() const { return GetBit(m_flags,SAVECHILDREN); } - inline void SetEnableSave(bool t) { m_flags = SetBit(m_flags,ENABLESAVE,t); } + inline void SetEnableSave(bool t) { m_flags = (uint8_t)SetBit(m_flags,ENABLESAVE,t); } inline bool GetEnableSave() const { return GetBit(m_flags,ENABLESAVE); } - inline void SetUseAlphaPass(bool t) { m_flags = SetBit(m_flags,ALPHAPATH,t); } + inline void SetUseAlphaPass(bool t) { m_flags = (uint8_t)SetBit(m_flags,ALPHAPATH,t); } inline bool GetUseAlphaPass() const { return GetBit(m_flags,ALPHAPATH); } virtual MercuryMatrix ManipulateMatrix(const MercuryMatrix& matrix); Modified: Mercury2/src/OGLExtensions.cpp =================================================================== --- Mercury2/src/OGLExtensions.cpp 2010-05-23 15:56:04 UTC (rev 748) +++ Mercury2/src/OGLExtensions.cpp 2010-05-23 15:56:37 UTC (rev 749) @@ -12,6 +12,7 @@ PFNGLGENBUFFERSARBPROC glGenBuffersARB; PFNGLBUFFERDATAARBPROC glBufferDataARB; +PFNGLBUFFERSUBDATAARBPROC glBufferSubDataARB; PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements; @@ -70,6 +71,7 @@ EXTENSION( PFNGLCLIENTACTIVETEXTUREARBPROC,glClientActiveTextureARB ); EXTENSION( PFNGLGENBUFFERSARBPROC,glGenBuffersARB ); EXTENSION( PFNGLBUFFERDATAARBPROC,glBufferDataARB ); +EXTENSION( PFNGLBUFFERSUBDATAARBPROC,glBufferSubDataARB ); EXTENSION( PFNGLDRAWRANGEELEMENTSPROC,glDrawRangeElements ); Modified: Mercury2/src/OGLExtensions.h =================================================================== --- Mercury2/src/OGLExtensions.h 2010-05-23 15:56:04 UTC (rev 748) +++ Mercury2/src/OGLExtensions.h 2010-05-23 15:56:37 UTC (rev 749) @@ -8,6 +8,7 @@ extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB; extern PFNGLGENBUFFERSARBPROC glGenBuffersARB; extern PFNGLBUFFERDATAARBPROC glBufferDataARB; +extern PFNGLBUFFERSUBDATAARBPROC glBufferSubDataARB; extern PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements; //glsl This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-06-30 01:43:32
|
Revision: 753 http://hgengine.svn.sourceforge.net/hgengine/?rev=753&view=rev Author: axlecrusher Date: 2010-06-30 01:43:25 +0000 (Wed, 30 Jun 2010) Log Message: ----------- Reorganize headers and math data structures to allow for much easier inclusion into tools. Tools no longer need to pull in a huge mess of HG2 source files when compiling. Modified Paths: -------------- Mercury2/src/AlignedBuffer.h Mercury2/src/Camera.cpp Mercury2/src/MQuaternion.cpp Mercury2/src/MQuaternion.h Mercury2/src/MercuryAsset.h Mercury2/src/MercuryCrash.c Mercury2/src/MercuryCrash.h Mercury2/src/MercuryFile.cpp Mercury2/src/MercuryFile.h Mercury2/src/MercuryHash.h Mercury2/src/MercuryLog.h Mercury2/src/MercuryMatrix.cpp Mercury2/src/MercuryMatrix.h Mercury2/src/MercuryMessageManager.h Mercury2/src/MercuryNamedResource.cpp Mercury2/src/MercuryPrefs.cpp Mercury2/src/MercuryPrefs.h Mercury2/src/MercurySound.h Mercury2/src/MercuryTheme.cpp Mercury2/src/MercuryTheme.h Mercury2/src/MercuryUtil.cpp Mercury2/src/MercuryUtil.h Mercury2/src/MercuryValue.cpp Mercury2/src/MercuryVector.h Mercury2/src/MercuryVertex.cpp Mercury2/src/MercuryVertex.h Mercury2/src/MercuryWindow.h Mercury2/src/ModuleManager.h Mercury2/src/RawImageData.h Mercury2/src/XMLParser.cpp Added Paths: ----------- Mercury2/src/InstanceCounter.h Mercury2/src/MercuryStringUtil.cpp Mercury2/src/MercuryStringUtil.h Modified: Mercury2/src/AlignedBuffer.h =================================================================== --- Mercury2/src/AlignedBuffer.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/AlignedBuffer.h 2010-06-30 01:43:25 UTC (rev 753) @@ -1,6 +1,7 @@ #ifndef ALIGNEDBUFFER_H #define ALIGNEDBUFFER_H +#include <MercuryUtil.h> #include <Mint.h> template <typename T> Modified: Mercury2/src/Camera.cpp =================================================================== --- Mercury2/src/Camera.cpp 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/Camera.cpp 2010-06-30 01:43:25 UTC (rev 753) @@ -51,7 +51,7 @@ //compute the world space look vector (broken if camera is in transform node) m_lookAt = MercuryVector(0,0,-1); //by default camera looks down world Z - m_lookAt = m_lookAt.Rotate( r ); + m_lookAt = RotateVector(m_lookAt,r); m_lookAt.NormalizeSelf(); LOOKAT = m_lookAt; @@ -102,7 +102,8 @@ MQuaternion qLeftRight = MQuaternion::CreateFromAxisAngle(MercuryVector(0,1,0), m_x); MercuryVector LocalX = MercuryVector( 1, 0, 0 ); - LocalX = LocalX.Rotate( qLeftRight ); + LocalX = RotateVector( LocalX,qLeftRight ); + MQuaternion qUpDown = MQuaternion::CreateFromAxisAngle(LocalX, m_y); Added: Mercury2/src/InstanceCounter.h =================================================================== --- Mercury2/src/InstanceCounter.h (rev 0) +++ Mercury2/src/InstanceCounter.h 2010-06-30 01:43:25 UTC (rev 753) @@ -0,0 +1,39 @@ +#ifndef INSTANCECOUNTER_H +#define INSTANCECOUNTER_H + +//This counter is used with singletons to +//ensure proper destruction order of the +//singleton +template<typename T> +class InstanceCounter +{ + public: + InstanceCounter(const MString & name) + :m_name(name) + { + if (m_count == 0) + { + printf("Creating instance %s\n", m_name.c_str()); + m_instance = &T::GetInstance(); + } + ++m_count; + } + ~InstanceCounter() + { + --m_count; + if (m_count == 0) + { + printf("Destroying instance %s\n", m_name.c_str()); + SAFE_DELETE(m_instance); + } + } + private: + static unsigned long m_count; + MString m_name; + T* m_instance; +}; + +template<typename T> + unsigned long InstanceCounter<T>::m_count = 0; + +#endif Modified: Mercury2/src/MQuaternion.cpp =================================================================== --- Mercury2/src/MQuaternion.cpp 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MQuaternion.cpp 2010-06-30 01:43:25 UTC (rev 753) @@ -359,6 +359,10 @@ matrix[3][3] = 1; } +MercuryVertex RotateVector(const MercuryVertex& v, const MQuaternion& q) +{ + return (q * MQuaternion(0, v) * q.reciprocal()).ToVector(); +} /**************************************************************************** * Copyright (C) 2009 by Joshua Allen, Charles Lohr, Adam Lowman * Modified: Mercury2/src/MQuaternion.h =================================================================== --- Mercury2/src/MQuaternion.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MQuaternion.h 2010-06-30 01:43:25 UTC (rev 753) @@ -91,6 +91,8 @@ ///Spherically interpolate between two quaternions t = 0..1 MQuaternion SLERP( const MQuaternion &a, const MQuaternion &b,float t); +MercuryVertex RotateVector(const MercuryVertex& v, const MQuaternion& q); + #endif /**************************************************************************** Modified: Mercury2/src/MercuryAsset.h =================================================================== --- Mercury2/src/MercuryAsset.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryAsset.h 2010-06-30 01:43:25 UTC (rev 753) @@ -9,7 +9,7 @@ #include <XMLParser.h> #include <Callback.h> #include <MercuryLog.h> - +#include <MercuryStringUtil.h> #include <MercuryHash.h> #include <list> Modified: Mercury2/src/MercuryCrash.c =================================================================== --- Mercury2/src/MercuryCrash.c 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryCrash.c 2010-06-30 01:43:25 UTC (rev 753) @@ -187,6 +187,15 @@ return exceptions[i].name; } +void fail_m( const char * message, const char * file, int line ) +{ + char backtracebuffer[2048]; + //Probably should message box here somewhere in the event we're running on Windows. + fprintf( stderr, "Fatal Error: \"%s\" in %s:%d\n", message, file, line ); + cnget_backtrace( 1, backtracebuffer, 2047 ); + puts( backtracebuffer ); + exit(-1); +} /* * (c) 2003-2008 Glenn Maynard, Steve Checkoway, Avery Lee, Charles Lohr Modified: Mercury2/src/MercuryCrash.h =================================================================== --- Mercury2/src/MercuryCrash.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryCrash.h 2010-06-30 01:43:25 UTC (rev 753) @@ -11,10 +11,14 @@ int cnset_execute_on_crash( FNType fn ); const char * cn_get_crash_description( int code ); +void fail_m( const char * message, const char * file, int line ); + #ifdef __cplusplus }; #endif +#define FAIL( message ) fail_m( message, __FILE__, __LINE__ ); + #endif Modified: Mercury2/src/MercuryFile.cpp =================================================================== --- Mercury2/src/MercuryFile.cpp 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryFile.cpp 2010-06-30 01:43:25 UTC (rev 753) @@ -6,8 +6,8 @@ #include "MercuryFileDriverZipped.h" #include "MercuryFileDriverPacked.h" #include "MercuryTheme.h" +#include <MercuryStringUtil.h> - /********************FILE MANAGER**************************/ MercuryFileManager::MercuryFileManager() @@ -134,7 +134,47 @@ return true; } +long FileToString( const MString & sFileName, char * & data ) +{ + data = 0; + MercuryFile * f = FILEMAN.Open( sFileName ); + if( !f ) return -1; + + int length = f->Length(); + + data = (char*)malloc( length + 1 ); + + if( !data ) + { + data = 0; + delete f; + return -1; + } + + int r = f->Read( data, length ); + + delete f; + + if( r != length ) + { + free( data ); + data = 0; + return -1; + } + + return length; +} + +bool StringToFile( const MString & sFileName, const MString & data ) +{ + MercuryFile * f = FILEMAN.Open( sFileName, MFP_WRITE_ONLY ); + if( !f ) return false; + f->Write( data.c_str(), data.length() ); + delete f; + return true; +} + MercuryFileManager& MercuryFileManager::GetInstance() { static MercuryFileManager* instance = NULL; Modified: Mercury2/src/MercuryFile.h =================================================================== --- Mercury2/src/MercuryFile.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryFile.h 2010-06-30 01:43:25 UTC (rev 753) @@ -3,6 +3,7 @@ #include <MAutoPtr.h> #include <MercuryUtil.h> +#include <InstanceCounter.h> //Forward decleration, as there's no real need to have this included unless we _need_ it. template< typename t > @@ -93,7 +94,13 @@ MVector< MAutoPtr< MercuryFileDriver> > * m_Drivers; }; +///Open up filename: sFileName and dump it into a new buffer; you must delete the return value when done. +///The return value is -1 if there was an issue, otherwise it is valid. +long FileToString( const MString & sFileName, char * & data ); +///Take a string and write it to the hard drive as a file. True indicates everything is okay. +bool StringToFile( const MString & sFileName, const MString & data ); + static InstanceCounter<MercuryFileManager> MFMcounter("MercuryFileManager"); #define FILEMAN MercuryFileManager::GetInstance() Modified: Mercury2/src/MercuryHash.h =================================================================== --- Mercury2/src/MercuryHash.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryHash.h 2010-06-30 01:43:25 UTC (rev 753) @@ -4,6 +4,7 @@ #include "global.h" #include <MercuryVector.h> #include <assert.h> +#include <MercuryString.h> ///Mercury Hash Table for Strings template<typename T> Modified: Mercury2/src/MercuryLog.h =================================================================== --- Mercury2/src/MercuryLog.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryLog.h 2010-06-30 01:43:25 UTC (rev 753) @@ -4,8 +4,8 @@ #include <list> #include <MercuryString.h> #include <MercuryThreads.h> - #include <MercuryUtil.h> +#include <InstanceCounter.h> class MercuryLog { Modified: Mercury2/src/MercuryMatrix.cpp =================================================================== --- Mercury2/src/MercuryMatrix.cpp 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryMatrix.cpp 2010-06-30 01:43:25 UTC (rev 753) @@ -1,5 +1,5 @@ #include "MercuryMatrix.h" -#include <MercuryLog.h> +//#include <MercuryLog.h> MercuryMatrixMemory::MercuryMatrixMemory() { @@ -271,7 +271,7 @@ MatrixMultiply4f ( m_matrix, m.m_matrix, r.m_matrix); return r; } - +/* void MercuryMatrix::Print() const { for (int i = 0; i < 4; ++i) @@ -280,7 +280,7 @@ } LOG.Write("\n"); } - +*/ MercuryVector MercuryMatrix::operator*(const MercuryVector& v) const { MercuryVector r; Modified: Mercury2/src/MercuryMatrix.h =================================================================== --- Mercury2/src/MercuryMatrix.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryMatrix.h 2010-06-30 01:43:25 UTC (rev 753) @@ -6,7 +6,7 @@ #include "MercuryUtil.h" #include <MercuryVertex.h> #include <MQuaternion.h> - +#include <InstanceCounter.h> #include <list> #include <MSemaphore.h> Modified: Mercury2/src/MercuryMessageManager.h =================================================================== --- Mercury2/src/MercuryMessageManager.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryMessageManager.h 2010-06-30 01:43:25 UTC (rev 753) @@ -13,6 +13,7 @@ #include <MAutoPtr.h> #include <MSemaphore.h> #include <MercuryValue.h> +#include <InstanceCounter.h> class MessageHolder : public RefBase { Modified: Mercury2/src/MercuryNamedResource.cpp =================================================================== --- Mercury2/src/MercuryNamedResource.cpp 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryNamedResource.cpp 2010-06-30 01:43:25 UTC (rev 753) @@ -1,5 +1,5 @@ #include <MercuryNamedResource.h> -#include <MercuryUtil.h> +#include <MercuryStringUtil.h> #include <stdio.h> MString MercuryNamedResource::GetValueS( const MString & sDataPointer ) Modified: Mercury2/src/MercuryPrefs.cpp =================================================================== --- Mercury2/src/MercuryPrefs.cpp 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryPrefs.cpp 2010-06-30 01:43:25 UTC (rev 753) @@ -1,5 +1,6 @@ #include <MercuryPrefs.h> #include <XMLParser.h> +#include <MercuryCrash.h> MercuryPreferences & MercuryPreferences::GetInstance() { Modified: Mercury2/src/MercuryPrefs.h =================================================================== --- Mercury2/src/MercuryPrefs.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryPrefs.h 2010-06-30 01:43:25 UTC (rev 753) @@ -3,6 +3,7 @@ #include <MercuryNamedResource.h> #include <MercuryUtil.h> +#include <InstanceCounter.h> class XMLNode; class XMLDocument; Modified: Mercury2/src/MercurySound.h =================================================================== --- Mercury2/src/MercurySound.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercurySound.h 2010-06-30 01:43:25 UTC (rev 753) @@ -6,6 +6,7 @@ #include <MAutoPtr.h> #include <MercuryHash.h> #include <MercuryVector.h> +#include <InstanceCounter.h> class MercurySoundSource : public RefBase { Added: Mercury2/src/MercuryStringUtil.cpp =================================================================== --- Mercury2/src/MercuryStringUtil.cpp (rev 0) +++ Mercury2/src/MercuryStringUtil.cpp 2010-06-30 01:43:25 UTC (rev 753) @@ -0,0 +1,207 @@ +#include <MercuryStringUtil.h> + +MString ConvertToCFormat( const MString & ncf ) +{ + MString ret; + const char* nccf = ncf.c_str(); + + for ( int i = 0; (unsigned)i < ncf.length(); i++ ) + { + switch ( nccf[i] ) + { + case '\t': ret += "\\t"; break; + case '\n': ret += "\\n"; break; + case '\r': ret += "\\r"; break; + case '\f': ret += "\\f"; break; + case '\b': ret += "\\b"; break; + case '\\': ret += "\\\\"; break; + case '\'': ret += "\\\'"; break; + case '\"': ret += "\\\""; break; + default: + if( nccf[i] < 32 ) + { + ret += "\\"; + ret += ((unsigned char)nccf[i]/64)%8 + '0'; + ret += ((unsigned char)nccf[i]/8)%8 + '0'; + ret += (unsigned char)nccf[i]%8 + '0'; + } else + ret += nccf[i]; + } + } + return ret; +} + +MString ConvertToUnformatted( const MString & cf ) +{ + MString ret; + const char* ccf = cf.c_str(); + + for ( int i = 0; (unsigned)i < cf.length(); i++ ) + { + switch ( ccf[i] ) + { + case '\\': + i++; + if ( (unsigned)i >= cf.length() ) + return ret; + switch ( ccf[i] ) + { + case 't': ret += '\t'; break; + case 'n': ret += '\n'; break; + case 'r': ret += '\r'; break; + case 'f': ret += '\f'; break; + case 'b': ret += '\b'; break; + case '\\': ret += '\\'; break; + case '\'': ret += '\''; break; + case '\"': ret += '\"'; break; + default: + if( ccf[i] >= '0' && ccf[i] <= '7' ) + { + char c = ccf[i] - '0'; + if( ccf[i+1] >= '0' && ccf[i+1] <= '8' ) + { + i++; + c = c * 8 + ccf[i] - '0'; + } + if( ccf[i+1] >= '0' && ccf[i+1] <= '8' ) + { + i++; + c = c * 8 + ccf[i] - '0'; + } + ret += c; + } + } + break; + default: + ret += ccf[i]; + } + } + return ret; +} + +MString ToUpper(const MString& s) +{ + MString t = s; + char * ti = (char*)t.c_str(); + for (unsigned long i = 0; i < s.length(); ++i) + { + if( ti[i] >= 'a' && ti[i] <= 'z' ) + ti[i] -= ( 'a' - 'A' ); + } + return t; +} + +MString ToLower(const MString & s) +{ + MString t = s; + char * ti = (char*)t.c_str(); + for (unsigned long i = 0; i < s.length(); ++i) + { + if( ti[i] >= 'A' && ti[i] <= 'Z' ) + ti[i] += ( 'a' - 'A' ); + } + return t; +} + +MString ToProper(const MString & s) +{ + if( s.length() == 0 ) + return ""; + + MString t = s; + char * ti = (char*)t.c_str(); + + if( ti[0] >= 'a' && ti[0] <= 'z' ) + ti[0] -= ( 'a' - 'A' ); + + for (unsigned long i = 1; i < s.length(); ++i) + { + if( ti[i] >= 'A' && ti[i] <= 'Z' ) + ti[i] += ( 'a' - 'A' ); + } + return t; + +} + + + +float StrToFloat(const MString & s, float d) +{ + float x = d; +#if defined( WIN32 ) && !defined( LEAN_HG ) + if ( s.length() > 0) sscanf_s(s.c_str(), "%f", &x); +#else + if ( s.length() > 0) sscanf(s.c_str(), "%f", &x); +#endif + return x; +} + +int32_t StrToInt(const MString & s, int32_t d) +{ + int32_t x = d; +#if defined( WIN32 ) && !defined( LEAN_HG ) + if ( s.length() > 0) sscanf_s(s.c_str(), "%d", &x); +#else + if ( s.length() > 0) sscanf(s.c_str(), "%d", &x); +#endif + return x; +} + +bool StrToBool( const MString & s, bool d ) +{ + MString tmpret = s; + + tmpret = ToUpper( tmpret ); + if( tmpret.compare( "TRUE" ) == 0 ) return 1; + if( tmpret.compare( "FALSE" ) == 0 ) return 0; + if( tmpret.compare( "ON" ) == 0 ) return 1; + if( tmpret.compare( "OFF" ) == 0 ) return 0; + if( tmpret.compare( "YES" ) == 0 ) return 1; + if( tmpret.compare( "NO" ) == 0 ) return 0; + + return StrToInt( tmpret, d ) != 0; +} + +void SplitStrings( const MString & in, MVector < MString > & out, + const char * termin, const char * whitespace, + long termlen, long wslen ) +{ + const char * inStr = in.c_str(); + long curPos = 0; + long inLen = in.length(); + while ( curPos < inLen ) + { + curPos += BytesNUntil( inStr, whitespace, curPos, inLen, wslen ); + long NextPos = BytesUntil( inStr, termin, curPos, inLen, termlen ); + out.push_back( in.substr( curPos, NextPos ) ); + curPos += NextPos + 1; + } +} + + +/* Copyright (c) 2010, Joshua Allen and Charles Lohr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the Mercury Engine nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ Added: Mercury2/src/MercuryStringUtil.h =================================================================== --- Mercury2/src/MercuryStringUtil.h (rev 0) +++ Mercury2/src/MercuryStringUtil.h 2010-06-30 01:43:25 UTC (rev 753) @@ -0,0 +1,58 @@ +#ifndef MERCURYSTRINGUTIL_H +#define MERCURYSTRINGUTIL_H + +#include <MercuryString.h> +#include <Mint.h> +#include <MercuryVector.h> + +///Make a string all upper case +MString ToUpper(const MString & s); + +///Make a string all lower case +MString ToLower(const MString & s); + +///Make a string proper case (HELLO -> Hello, hello -> Hello) +MString ToProper(const MString & s); + +float StrToFloat(const MString & s, float d = 0); +int32_t StrToInt(const MString & s, int32_t d = 0); +bool StrToBool( const MString & s, bool d = false ); + +///Split given string into other strings using delimiters from termin +void SplitStrings( const MString & in, MVector < MString > & out, const char * termin, const char * whitespace, long termlen, long wslen ); + +///Convert string containing binary characters to C-style formatted string. +MString ConvertToCFormat( const MString & ncf ); + +///Convert a C-style formatted string into it's binary string equivalent. +MString ConvertToUnformatted( const MString & cf ); + +#endif + + +/* Copyright (c) 2010, Joshua Allen and Charles Lohr + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of the Mercury Engine nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ Modified: Mercury2/src/MercuryTheme.cpp =================================================================== --- Mercury2/src/MercuryTheme.cpp 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryTheme.cpp 2010-06-30 01:43:25 UTC (rev 753) @@ -1,6 +1,8 @@ #include <MercuryTheme.h> #include <MercuryPrefs.h> #include <XMLParser.h> +#include <MercuryCrash.h> +#include <MercuryStringUtil.h> #define MAX_THEMES 100 Modified: Mercury2/src/MercuryTheme.h =================================================================== --- Mercury2/src/MercuryTheme.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryTheme.h 2010-06-30 01:43:25 UTC (rev 753) @@ -2,9 +2,9 @@ #define _MERCURY_THEME_H #include <MercuryNamedResource.h> -#include <MercuryUtil.h> //huh? #include <MercuryHash.h> #include <MercuryVector.h> +#include <InstanceCounter.h> class XMLNode; class XMLDocument; Modified: Mercury2/src/MercuryUtil.cpp =================================================================== --- Mercury2/src/MercuryUtil.cpp 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryUtil.cpp 2010-06-30 01:43:25 UTC (rev 753) @@ -1,8 +1,5 @@ #include <MercuryUtil.h> -#include <MercuryFile.h> #include <Mint.h> -#include <MercuryVector.h> -#include <MercuryBacktrace.h> #include <math.h> #ifdef WIN32 @@ -11,179 +8,6 @@ #include <unistd.h> #endif -MString ConvertToCFormat( const MString & ncf ) -{ - MString ret; - const char* nccf = ncf.c_str(); - - for ( int i = 0; (unsigned)i < ncf.length(); i++ ) - { - switch ( nccf[i] ) - { - case '\t': ret += "\\t"; break; - case '\n': ret += "\\n"; break; - case '\r': ret += "\\r"; break; - case '\f': ret += "\\f"; break; - case '\b': ret += "\\b"; break; - case '\\': ret += "\\\\"; break; - case '\'': ret += "\\\'"; break; - case '\"': ret += "\\\""; break; - default: - if( nccf[i] < 32 ) - { - ret += "\\"; - ret += ((unsigned char)nccf[i]/64)%8 + '0'; - ret += ((unsigned char)nccf[i]/8)%8 + '0'; - ret += (unsigned char)nccf[i]%8 + '0'; - } else - ret += nccf[i]; - } - } - return ret; -} - -MString ConvertToUnformatted( const MString & cf ) -{ - MString ret; - const char* ccf = cf.c_str(); - - for ( int i = 0; (unsigned)i < cf.length(); i++ ) - { - switch ( ccf[i] ) - { - case '\\': - i++; - if ( (unsigned)i >= cf.length() ) - return ret; - switch ( ccf[i] ) - { - case 't': ret += '\t'; break; - case 'n': ret += '\n'; break; - case 'r': ret += '\r'; break; - case 'f': ret += '\f'; break; - case 'b': ret += '\b'; break; - case '\\': ret += '\\'; break; - case '\'': ret += '\''; break; - case '\"': ret += '\"'; break; - default: - if( ccf[i] >= '0' && ccf[i] <= '7' ) - { - char c = ccf[i] - '0'; - if( ccf[i+1] >= '0' && ccf[i+1] <= '8' ) - { - i++; - c = c * 8 + ccf[i] - '0'; - } - if( ccf[i+1] >= '0' && ccf[i+1] <= '8' ) - { - i++; - c = c * 8 + ccf[i] - '0'; - } - ret += c; - } - } - break; - default: - ret += ccf[i]; - } - } - return ret; -} - -MString ToUpper(const MString& s) -{ - MString t = s; - char * ti = (char*)t.c_str(); - for (unsigned long i = 0; i < s.length(); ++i) - { - if( ti[i] >= 'a' && ti[i] <= 'z' ) - ti[i] -= ( 'a' - 'A' ); - } - return t; -} - -MString ToLower(const MString & s) -{ - MString t = s; - char * ti = (char*)t.c_str(); - for (unsigned long i = 0; i < s.length(); ++i) - { - if( ti[i] >= 'A' && ti[i] <= 'Z' ) - ti[i] += ( 'a' - 'A' ); - } - return t; -} - -MString ToProper(const MString & s) -{ - if( s.length() == 0 ) - return ""; - - MString t = s; - char * ti = (char*)t.c_str(); - - if( ti[0] >= 'a' && ti[0] <= 'z' ) - ti[0] -= ( 'a' - 'A' ); - - for (unsigned long i = 1; i < s.length(); ++i) - { - if( ti[i] >= 'A' && ti[i] <= 'Z' ) - ti[i] += ( 'a' - 'A' ); - } - return t; - -} - - - -float StrToFloat(const MString & s, float d) -{ - float x = d; -#if defined( WIN32 ) && !defined( LEAN_HG ) - if ( s.length() > 0) sscanf_s(s.c_str(), "%f", &x); -#else - if ( s.length() > 0) sscanf(s.c_str(), "%f", &x); -#endif - return x; -} - -int32_t StrToInt(const MString & s, int32_t d) -{ - int32_t x = d; -#if defined( WIN32 ) && !defined( LEAN_HG ) - if ( s.length() > 0) sscanf_s(s.c_str(), "%d", &x); -#else - if ( s.length() > 0) sscanf(s.c_str(), "%d", &x); -#endif - return x; -} - -bool StrToBool( const MString & s, bool d ) -{ - MString tmpret = s; - - tmpret = ToUpper( tmpret ); - if( tmpret.compare( "TRUE" ) == 0 ) return 1; - if( tmpret.compare( "FALSE" ) == 0 ) return 0; - if( tmpret.compare( "ON" ) == 0 ) return 1; - if( tmpret.compare( "OFF" ) == 0 ) return 0; - if( tmpret.compare( "YES" ) == 0 ) return 1; - if( tmpret.compare( "NO" ) == 0 ) return 0; - - return StrToInt( tmpret, d ) != 0; -} - - -void fail_m( const char * message, const char * file, int line ) -{ - char backtracebuffer[2048]; - //Probably should message box here somewhere in the event we're running on Windows. - fprintf( stderr, "Fatal Error: \"%s\" in %s:%d\n", message, file, line ); - cnget_backtrace( 1, backtracebuffer, 2047 ); - puts( backtracebuffer ); - exit(-1); -} - void* mmemalign(size_t align, size_t size, void*& mem) { uintptr_t mask = ~(uintptr_t)(align - 1); @@ -197,48 +21,6 @@ return (uintptr_t(mem) % align) == 0; } -long FileToString( const MString & sFileName, char * & data ) -{ - data = 0; - - MercuryFile * f = FILEMAN.Open( sFileName ); - if( !f ) return -1; - - int length = f->Length(); - - data = (char*)malloc( length + 1 ); - - if( !data ) - { - data = 0; - delete f; - return -1; - } - - int r = f->Read( data, length ); - - delete f; - - if( r != length ) - { - free( data ); - data = 0; - return -1; - } - - return length; -} - -bool StringToFile( const MString & sFileName, const MString & data ) -{ - MercuryFile * f = FILEMAN.Open( sFileName, MFP_WRITE_ONLY ); - if( !f ) return false; - f->Write( data.c_str(), data.length() ); - delete f; - return true; -} - - int GeneralUsePrimes[] = { 3, 13, 37, 73, 131, 229, 337, 821, 2477, 4594, 8941, 14797, 24953, 39041, 60811, 104729 }; int GetAPrime( int ith ) @@ -274,22 +56,6 @@ return i - start; } -void SplitStrings( const MString & in, MVector < MString > & out, - const char * termin, const char * whitespace, - long termlen, long wslen ) -{ - const char * inStr = in.c_str(); - long curPos = 0; - long inLen = in.length(); - while ( curPos < inLen ) - { - curPos += BytesNUntil( inStr, whitespace, curPos, inLen, wslen ); - long NextPos = BytesUntil( inStr, termin, curPos, inLen, termlen ); - out.push_back( in.substr( curPos, NextPos ) ); - curPos += NextPos + 1; - } -} - void msleep(uint32_t msec) { #ifdef WIN32 Modified: Mercury2/src/MercuryUtil.h =================================================================== --- Mercury2/src/MercuryUtil.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryUtil.h 2010-06-30 01:43:25 UTC (rev 753) @@ -2,7 +2,6 @@ #define MERCURYUTIL_H #include <stdlib.h> -#include <MercuryString.h> #include <global.h> #include <stdio.h> @@ -12,26 +11,10 @@ #define TO_ENDIAN( x ) -void fail_m( const char * message, const char * file, int line ); -#define FAIL( message ) fail_m( message, __FILE__, __LINE__ ); - //returns an aligned pointer, mem is the actual (unaligned) pointer for freeing void* mmemalign(size_t align, size_t size, void*& mem); bool isAligned(size_t align, const void* mem); -///Make a string all upper case -MString ToUpper(const MString & s); - -///Make a string all lower case -MString ToLower(const MString & s); - -///Make a string proper case (HELLO -> Hello, hello -> Hello) -MString ToProper(const MString & s); - -float StrToFloat(const MString & s, float d = 0); -int32_t StrToInt(const MString & s, int32_t d = 0); -bool StrToBool( const MString & s, bool d = false ); - template<typename T> const T& MAX(const T& t1, const T& t2) { @@ -52,48 +35,6 @@ return value; } -//This counter is used with singletons to -//ensure proper destruction order of the -//singleton -template<typename T> -class InstanceCounter -{ - public: - InstanceCounter(const MString & name) - :m_name(name) - { - if (m_count == 0) - { - printf("Creating instance %s\n", m_name.c_str()); - m_instance = &T::GetInstance(); - } - ++m_count; - } - ~InstanceCounter() - { - --m_count; - if (m_count == 0) - { - printf("Destroying instance %s\n", m_name.c_str()); - SAFE_DELETE(m_instance); - } - } - private: - static unsigned long m_count; - MString m_name; - T* m_instance; -}; - -template<typename T> - unsigned long InstanceCounter<T>::m_count = 0; - -///Open up filename: sFileName and dump it into a new buffer; you must delete the return value when done. -///The return value is -1 if there was an issue, otherwise it is valid. -long FileToString( const MString & sFileName, char * & data ); - -///Take a string and write it to the hard drive as a file. True indicates everything is okay. -bool StringToFile( const MString & sFileName, const MString & data ); - /* These two functions are very different */ /// nextPow2 will go to the NEXT power of 2 even if x is already a power of 2. inline int nextPow2(int x) { int num = 1; while(num <= x) num <<= 1; return num; } @@ -119,15 +60,6 @@ ///Bytes until something other than a terminal long BytesNUntil( const char* strin, const char * termin, long start, long slen, long termlen ); -///Split given string into other strings using delimiters from termin -void SplitStrings( const MString & in, MVector < MString > & out, const char * termin, const char * whitespace, long termlen, long wslen ); - -///Convert string containing binary characters to C-style formatted string. -MString ConvertToCFormat( const MString & ncf ); - -///Convert a C-style formatted string into it's binary string equivalent. -MString ConvertToUnformatted( const MString & cf ); - ///millisecond sleep void msleep(uint32_t msec); Modified: Mercury2/src/MercuryValue.cpp =================================================================== --- Mercury2/src/MercuryValue.cpp 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryValue.cpp 2010-06-30 01:43:25 UTC (rev 753) @@ -1,8 +1,8 @@ #include <MercuryMessageManager.h> #include <MercuryValue.h> #include <MessageHandler.h> +#include <MercuryStringUtil.h> - DelegateNotifierList::DelegateNotifierList( DeletionNotifier nf, MessageHandler * no ) : NotifyFunction( nf ), NotifyObject( no ), Next( NULL ) { Modified: Mercury2/src/MercuryVector.h =================================================================== --- Mercury2/src/MercuryVector.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryVector.h 2010-06-30 01:43:25 UTC (rev 753) @@ -2,6 +2,7 @@ #define _MERCURY_VECTOR_H #include <string.h> +#include <stdlib.h> ///Stripped down and fast vector class template<typename T> Modified: Mercury2/src/MercuryVertex.cpp =================================================================== --- Mercury2/src/MercuryVertex.cpp 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryVertex.cpp 2010-06-30 01:43:25 UTC (rev 753) @@ -1,10 +1,7 @@ #include <MercuryVertex.h> #include <MercuryUtil.h> #include <MercuryMath.h> -#include <MQuaternion.h> -#include <MercuryMatrix.h> - MercuryVertex::MercuryVertex() { m_xyzw[0] = m_xyzw[1] = m_xyzw[2] = m_xyzw[3] = 0; @@ -127,22 +124,6 @@ return dp; } -MercuryVertex MercuryVertex::operator*(const MercuryMatrix& m) const -{ - MercuryVertex r; - MercuryVertex v1(m[0][0], m[1][0], m[2][0], m[3][0]); - MercuryVertex v2(m[0][1], m[1][1], m[2][1], m[3][1]); - MercuryVertex v3(m[0][2], m[1][2], m[2][2], m[3][2]); - MercuryVertex v4(m[0][3], m[1][3], m[2][3], m[3][3]); - - r[0] = ((*this)*v1).AddComponents(); - r[1] = ((*this)*v2).AddComponents(); - r[2] = ((*this)*v3).AddComponents(); - r[3] = ((*this)*v4).AddComponents(); - - return r; -} - float MercuryVertex::AddComponents() const { return GetX() + GetY() + GetZ() + GetW(); @@ -153,11 +134,6 @@ return ssprintf("%s: %f %f %f %f", s.c_str(), m_xyzw[0], m_xyzw[1], m_xyzw[2], m_xyzw[3]); } -MercuryVertex MercuryVertex::Rotate(const MQuaternion& q) const -{ - return (q * MQuaternion(0, *this) * q.reciprocal()).ToVector(); -} - MercuryVertex MercuryVertex::CreateFromString(const MString& s) { float x,y,z; Modified: Mercury2/src/MercuryVertex.h =================================================================== --- Mercury2/src/MercuryVertex.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryVertex.h 2010-06-30 01:43:25 UTC (rev 753) @@ -10,8 +10,6 @@ #define __inline__ inline #endif -class MQuaternion; -class MercuryMatrix; class MercuryVertex { @@ -62,9 +60,6 @@ const MercuryVertex& operator /= (const MercuryVertex& p); inline MercuryVertex operator * (const MercuryVertex& p) const { MercuryVertex r(*this); r*=p; return r; } inline MercuryVertex operator / (const MercuryVertex& p) const { MercuryVertex r(*this); r/=p; return r; } - - MercuryVertex operator*(const MercuryMatrix& m) const; - inline MercuryVertex& operator += ( const MercuryVertex& other ) { m_xyzw[0]+=other[0]; m_xyzw[1]+=other[1]; m_xyzw[2]+=other[2]; return *this; } inline MercuryVertex& operator -= ( const MercuryVertex& other ) { m_xyzw[0]-=other[0]; m_xyzw[1]-=other[1]; m_xyzw[2]-=other[2]; return *this; } @@ -89,9 +84,7 @@ MercuryVertex DotProduct3(const MercuryVertex& rhs1, const MercuryVertex& rhs2, const MercuryVertex& rhs3) const; MString Stringify(const MString& s = "Vertex") const; - - MercuryVertex Rotate(const MQuaternion& q) const; - + float AddComponents() const; static MercuryVertex CreateFromString(const MString& s); Modified: Mercury2/src/MercuryWindow.h =================================================================== --- Mercury2/src/MercuryWindow.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/MercuryWindow.h 2010-06-30 01:43:25 UTC (rev 753) @@ -3,6 +3,7 @@ #include <global.h> #include <MercuryUtil.h> +#include <MercuryStringUtil.h> #include <list> #include <Callback.h> Modified: Mercury2/src/ModuleManager.h =================================================================== --- Mercury2/src/ModuleManager.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/ModuleManager.h 2010-06-30 01:43:25 UTC (rev 753) @@ -4,6 +4,7 @@ #include <MercuryUtil.h> #include <MercuryHash.h> #include <MercuryThreads.h> +#include <InstanceCounter.h> #ifdef INSTANCE_WATCH #include <set> Modified: Mercury2/src/RawImageData.h =================================================================== --- Mercury2/src/RawImageData.h 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/RawImageData.h 2010-06-30 01:43:25 UTC (rev 753) @@ -2,6 +2,7 @@ #define RAWIMAGEDATA_H #include <MercuryUtil.h> +#include <MercuryStringUtil.h> enum ColorByteType { Modified: Mercury2/src/XMLParser.cpp =================================================================== --- Mercury2/src/XMLParser.cpp 2010-06-29 03:47:54 UTC (rev 752) +++ Mercury2/src/XMLParser.cpp 2010-06-30 01:43:25 UTC (rev 753) @@ -1,6 +1,7 @@ #include <XMLParser.h> #include <MercuryFile.h> #include <MercuryVector.h> +#include <MercuryStringUtil.h> #include <libxml/parser.h> #include <libxml/tree.h> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-11-12 16:59:11
|
Revision: 758 http://hgengine.svn.sourceforge.net/hgengine/?rev=758&view=rev Author: axlecrusher Date: 2010-11-12 16:59:05 +0000 (Fri, 12 Nov 2010) Log Message: ----------- Move memory allocator into its own template class Modified Paths: -------------- Mercury2/src/MercuryMatrix.cpp Mercury2/src/MercuryMatrix.h Added Paths: ----------- Mercury2/src/MercuryMemory.h Modified: Mercury2/src/MercuryMatrix.cpp =================================================================== --- Mercury2/src/MercuryMatrix.cpp 2010-07-12 02:57:25 UTC (rev 757) +++ Mercury2/src/MercuryMatrix.cpp 2010-11-12 16:59:05 UTC (rev 758) @@ -1,81 +1,33 @@ #include "MercuryMatrix.h" //#include <MercuryLog.h> -MercuryMatrixMemory::MercuryMatrixMemory() +FloatRow* MercuryMatrix::GetNewMatrix() { - m_data.Allocate(rows,16); -} - -MercuryMatrixMemory& MercuryMatrixMemory::GetInstance() -{ - static MercuryMatrixMemory* mmm = NULL; - - if (mmm==NULL) + if (m_matrixMemory == NULL) { - mmm = new MercuryMatrixMemory(); - mmm->Init(); + m_matrixMemory = new MercuryMemory< MatrixArray >(1024);//1024 matrices * 64bytes each = 64kb } - - return *mmm; + return (FloatRow*)(m_matrixMemory->Allocate()); } -void MercuryMatrixMemory::Init() -{ - MSemaphoreLock lock(&m_lock); - - for (unsigned int i = 0; i < rows;i++) - m_free.push_back( m_data.Buffer()+i ); -/* - //test matrix transpose - MercuryMatrix test; - for (int i = 0; i < 16; ++i) - test.Ptr()[i] = i+1; - - LOG.Write("before transpose\n"); - test.Print(); - test.Transpose(); - LOG.Write("after Transpose\n"); - test.Print(); - */ -} - -FloatRow* MercuryMatrixMemory::GetNewMatrix() -{ - MatrixArray* m = (MatrixArray*)0x0; - MSemaphoreLock lock(&m_lock); - if ( m_free.begin() != m_free.end() ) - { - m = m_free.front(); - m_free.pop_front(); - } - if (m==0x0) ***m=0; - return (FloatRow*)m; -} - -void MercuryMatrixMemory::FreeMatrix(FloatRow* m) -{ - MSemaphoreLock lock(&m_lock); - m_free.push_back((MatrixArray*)m); -} - MercuryMatrix::MercuryMatrix() :m_matrix(0) { - m_matrix = MercuryMatrixMemory::GetInstance().GetNewMatrix(); + m_matrix = GetNewMatrix(); LoadIdentity(); } MercuryMatrix::MercuryMatrix(const MercuryMatrix& m) :m_matrix(0) { - m_matrix = MercuryMatrixMemory::GetInstance().GetNewMatrix(); + m_matrix = GetNewMatrix(); Copy16f(m_matrix, m.m_matrix); } MercuryMatrix::~MercuryMatrix() { if (m_matrix) - MercuryMatrixMemory::GetInstance().FreeMatrix( m_matrix ); + m_matrixMemory->Free((MatrixArray*)m_matrix); m_matrix = NULL; } @@ -297,6 +249,7 @@ const MercuryMatrix MercuryMatrix::IdentityMatrix; +MercuryMemory<MercuryMatrix::MatrixArray>* MercuryMatrix::m_matrixMemory = NULL; /* * Copyright (c) 2006-2009 Joshua Allen Modified: Mercury2/src/MercuryMatrix.h =================================================================== --- Mercury2/src/MercuryMatrix.h 2010-07-12 02:57:25 UTC (rev 757) +++ Mercury2/src/MercuryMatrix.h 2010-11-12 16:59:05 UTC (rev 758) @@ -10,28 +10,8 @@ #include <list> #include <MSemaphore.h> -#include <AlignedBuffer.h> +#include <MercuryMemory.h> -///Memory holder for matrices -class MercuryMatrixMemory -{ - /* Allocates all matrix space as one contigous block - to try to take advantage of data prefetching. Some matrix data should get a - free ride into the CPU cache. */ - public: - MercuryMatrixMemory(); - void Init(); - static MercuryMatrixMemory& GetInstance(); - FloatRow* GetNewMatrix(); - void FreeMatrix(FloatRow* m); - private: - static const unsigned int rows = 1024; //1024 matrices * 64bytes each = 64kb - typedef FloatRow MatrixArray[4]; //64kb - AlignedBuffer<MatrixArray> m_data; - std::list< MatrixArray* > m_free; - MSemaphore m_lock; -}; - ///General Purpose 4x4 row-major matrix class MercuryMatrix { @@ -85,10 +65,12 @@ void Print() const; const static MercuryMatrix IdentityMatrix; + + typedef FloatRow MatrixArray[4]; //64bytes + static FloatRow* GetNewMatrix(); + static MercuryMemory<MatrixArray>* m_matrixMemory; }; -static InstanceCounter<MercuryMatrixMemory> MMMcounter("MercuryMatrixMemory"); - #endif /* Added: Mercury2/src/MercuryMemory.h =================================================================== --- Mercury2/src/MercuryMemory.h (rev 0) +++ Mercury2/src/MercuryMemory.h 2010-11-12 16:59:05 UTC (rev 758) @@ -0,0 +1,85 @@ +#ifndef MERCURYMEMORY_H +#define MERCURYMEMORY_H + +#include <AlignedBuffer.h> +#include <list> +#include <MSemaphore.h> + +///Memory holder for matrices +template <typename T> +class MercuryMemory +{ + /* Allocates float memory space as one contigous block + to try to take advantage of data prefetching. Some matrix data should get a + free ride into the CPU cache. */ + public: + MercuryMemory(const uint32_t rows) + { + MSemaphoreLock lock(&m_lock); + m_data.Allocate(rows,16); + + for (unsigned int i = 0; i < rows;i++) + m_free.push_back( m_data.Buffer()+i ); + } + +// void Init(); +// static MercuryMatrixMemory& GetInstance(); + T* Allocate() + { + T* m = (T*)0x0; + MSemaphoreLock lock(&m_lock); + if ( m_free.begin() != m_free.end() ) + { + m = m_free.front(); + m_free.pop_front(); + } +// if (m==0x0) *m=*m; //crash if could not allocate + return m; + } + + void Free(T* m) + { + MSemaphoreLock lock(&m_lock); + m_free.push_back(m); + } + + private: +// static const unsigned int rows = 1024; //1024 matrices * 64bytes each = 64kb + AlignedBuffer<T> m_data; + std::list< T* > m_free; + MSemaphore m_lock; +}; + +#endif + +/**************************************************************************** + * Copyright (C) 2010 by Joshua Allen * + * * + * * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * Redistributions in binary form must reproduce the above * + * copyright notice, this list of conditions and the following * + * disclaimer in the documentation and/or other materials provided * + * with the distribution. * + * * Neither the name of the Mercury Engine nor the names of its * + * contributors may be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + ***************************************************************************/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-11-12 20:53:41
|
Revision: 759 http://hgengine.svn.sourceforge.net/hgengine/?rev=759&view=rev Author: axlecrusher Date: 2010-11-12 20:53:35 +0000 (Fri, 12 Nov 2010) Log Message: ----------- Make vertices use memory manager. This is so that vertices are more CPU cache friendly. Vertex data will be 16 byte aligned and will be mostly contagious. If a CPU cache line is 64 bytes, then reading a vertex into cache should bring in the following 3 vertices into the cache. Modified Paths: -------------- Mercury2/src/DataTypes/MTriangle.cpp Mercury2/src/MercuryMemory.h Mercury2/src/MercuryVertex.cpp Mercury2/src/MercuryVertex.h Modified: Mercury2/src/DataTypes/MTriangle.cpp =================================================================== --- Mercury2/src/DataTypes/MTriangle.cpp 2010-11-12 16:59:05 UTC (rev 758) +++ Mercury2/src/DataTypes/MTriangle.cpp 2010-11-12 20:53:35 UTC (rev 759) @@ -3,10 +3,11 @@ #include <stdio.h> MTriangle::MTriangle() -{ - m_verts[0] = 0; - m_verts[1] = 0; - m_verts[2] = 0; +{/* + m_verts[0] = MercuryVertex(0,0,0,0); + m_verts[1] = MercuryVertex(0,0,0,0); + m_verts[2] = MercuryVertex(0,0,0,0); + */ } MTriangle::MTriangle(const MTriangle& t) Modified: Mercury2/src/MercuryMemory.h =================================================================== --- Mercury2/src/MercuryMemory.h 2010-11-12 16:59:05 UTC (rev 758) +++ Mercury2/src/MercuryMemory.h 2010-11-12 20:53:35 UTC (rev 759) @@ -14,40 +14,70 @@ free ride into the CPU cache. */ public: MercuryMemory(const uint32_t rows) + :m_free(NULL),m_rows(rows) { MSemaphoreLock lock(&m_lock); - m_data.Allocate(rows,16); - - for (unsigned int i = 0; i < rows;i++) - m_free.push_back( m_data.Buffer()+i ); + AllocateMoreSpace(m_rows); } -// void Init(); -// static MercuryMatrixMemory& GetInstance(); T* Allocate() { - T* m = (T*)0x0; - MSemaphoreLock lock(&m_lock); - if ( m_free.begin() != m_free.end() ) + T* m = NULL; + MemoryUnit* mu = NULL; { - m = m_free.front(); - m_free.pop_front(); + //keep really short lock + MSemaphoreLock lock(&m_lock); + if ( m_free == NULL ) AllocateMoreSpace(m_rows); + mu = m_free; + m_free=m_free->prev; + if (m_free!=mu->prev) { char* a = NULL; *a=0; } //wtf happened here!?!?! FREE CHANGED DURING OUR LOCK } -// if (m==0x0) *m=*m; //crash if could not allocate + m = mu->mem; + delete mu; + if (m==NULL) { char* a = NULL; *a=0; } //no memory allocated?? return m; } void Free(T* m) { MSemaphoreLock lock(&m_lock); - m_free.push_back(m); + for (MemoryUnit* mu=m_free;mu!=NULL;mu=mu->prev) + { + //probably could some some sorting here to get contigious free and used memory + //if free memory is alwasy given out in order, then used memory will also be in order + if (m==mu->mem) { char* a=NULL;*a=0;} //WTF DOUBLE FREE + } + m_free = new MemoryUnit(m_free,m); } private: -// static const unsigned int rows = 1024; //1024 matrices * 64bytes each = 64kb - AlignedBuffer<T> m_data; - std::list< T* > m_free; + struct MemoryUnit + { + MemoryUnit(MemoryUnit* p, T* m) + :mem(m),prev(p) + { +// if (p!=NULL) p->next = this; + } + T* mem; + MemoryUnit* prev; + }; + + void AllocateMoreSpace(const uint32_t rows) + { + AlignedBuffer<T>* d = new AlignedBuffer<T>(); + d->Allocate(rows,16); + + for (unsigned int i = 0; i < rows;i++) + m_free = new MemoryUnit(m_free,(d->Buffer())+i); + + m_data.push_back(d); + } + + std::list< AlignedBuffer<T>* > m_data; + MemoryUnit* m_free; + MSemaphore m_lock; + unsigned long m_rows; }; #endif Modified: Mercury2/src/MercuryVertex.cpp =================================================================== --- Mercury2/src/MercuryVertex.cpp 2010-11-12 16:59:05 UTC (rev 758) +++ Mercury2/src/MercuryVertex.cpp 2010-11-12 20:53:35 UTC (rev 759) @@ -2,13 +2,27 @@ #include <MercuryUtil.h> #include <MercuryMath.h> +float* MercuryVertex::GetFloatMem() +{ + if (m_memory==NULL) + { + m_memory = new MercuryMemory< FloatRow >(1024); + } +// return new FloatRow; + return (float*)m_memory->Allocate(); +} + MercuryVertex::MercuryVertex() + :m_xyzw(NULL) { + m_xyzw = GetFloatMem(); m_xyzw[0] = m_xyzw[1] = m_xyzw[2] = m_xyzw[3] = 0; } MercuryVertex::MercuryVertex( float ix, float iy, float iz, float iw ) + :m_xyzw(NULL) { + m_xyzw = GetFloatMem(); m_xyzw[0] = ix; m_xyzw[1] = iy; m_xyzw[2] = iz; @@ -16,31 +30,46 @@ } MercuryVertex::MercuryVertex( const float* in3f, float f ) + :m_xyzw(NULL) { + m_xyzw = GetFloatMem(); for (unsigned int i = 0; i < 3; ++i) (*this)[i] = in3f[i]; m_xyzw[3] = f; } MercuryVertex::MercuryVertex( const float* in4f ) + :m_xyzw(NULL) { + m_xyzw = GetFloatMem(); for (unsigned int i = 0; i < 4; ++i) (*this)[i] = in4f[i]; } MercuryVertex::MercuryVertex( const MercuryVertex& v) + :m_xyzw(NULL) { + m_xyzw = GetFloatMem(); for (unsigned int i = 0; i < 4; ++i) (*this)[i] = v[i]; } MercuryVertex::MercuryVertex( const MercuryVertex& v, float w) + :m_xyzw(NULL) { + m_xyzw = GetFloatMem(); for (unsigned int i = 0; i < 3; ++i) (*this)[i] = v[i]; m_xyzw[3] = w; } +MercuryVertex::~MercuryVertex() +{ + if (m_xyzw!=NULL) + m_memory->Free((FloatRow*)m_xyzw); + m_xyzw = NULL; +} + void MercuryVertex::NormalizeSelf() { float imag = 1.0f/Length(); @@ -104,7 +133,7 @@ { //XXX should this use all 4 components? MercuryVertex r; - MMCrossProduct( m_xyzw, p.m_xyzw, r.m_xyzw ); + MMCrossProduct( ToFloatRow(), p.ToFloatRow(), r.ToFloatRow() ); return r; } @@ -141,6 +170,7 @@ return MercuryVertex(x,y,z); } +MercuryMemory< FloatRow >* MercuryVertex::m_memory = NULL; /**************************************************************************** * Copyright (C) 2009 by Joshua Allen * Modified: Mercury2/src/MercuryVertex.h =================================================================== --- Mercury2/src/MercuryVertex.h 2010-11-12 16:59:05 UTC (rev 758) +++ Mercury2/src/MercuryVertex.h 2010-11-12 20:53:35 UTC (rev 759) @@ -10,6 +10,7 @@ #define __inline__ inline #endif +#include <MercuryMemory.h> class MercuryVertex { @@ -20,14 +21,17 @@ MercuryVertex( const float* in4f ); MercuryVertex( const MercuryVertex& v); MercuryVertex( const MercuryVertex& v, float w); + virtual ~MercuryVertex(); ///Direct conversion to float* __inline__ operator float* () { return m_xyzw; } ///Direct conversion to const float* __inline__ operator const float* () const { return m_xyzw; } +// __inline__ float& operator[](unsigned int i) { return m_xyzw[i]; } +// __inline__ const float& operator[](unsigned int i) const { return m_xyzw[i]; } - inline FloatRow& ToFloatRow() { return m_xyzw; } - inline const FloatRow& ToFloatRow() const { return m_xyzw; } + inline FloatRow& ToFloatRow() { return (FloatRow&)*m_xyzw; } + inline const FloatRow& ToFloatRow() const { return (const FloatRow&)*m_xyzw; } inline float GetX() const { return m_xyzw[0]; } inline float GetY() const { return m_xyzw[1]; } @@ -77,6 +81,8 @@ bool operator==(const float f) const; inline bool operator!=(const float f) const { return !(*this == f); } + inline const MercuryVertex& operator=(const MercuryVertex& p) { Copy4f(m_xyzw,p.m_xyzw);return *this; } + ///Obtain the cross product (*this) x p MercuryVertex CrossProduct(const MercuryVertex& p) const; @@ -90,7 +96,11 @@ static MercuryVertex CreateFromString(const MString& s); // float m_xyzw[3]; - FloatRow m_xyzw; +// FloatRow m_xyzw; + private: + float* m_xyzw; + static MercuryMemory< FloatRow >* m_memory; + static float* GetFloatMem(); }; typedef MercuryVertex MercuryVector; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-11-13 21:40:24
|
Revision: 762 http://hgengine.svn.sourceforge.net/hgengine/?rev=762&view=rev Author: axlecrusher Date: 2010-11-13 21:40:17 +0000 (Sat, 13 Nov 2010) Log Message: ----------- expose for use elsewhere Modified Paths: -------------- Mercury2/src/MSemaphore.cpp Mercury2/src/MSemaphore.h Modified: Mercury2/src/MSemaphore.cpp =================================================================== --- Mercury2/src/MSemaphore.cpp 2010-11-13 01:16:27 UTC (rev 761) +++ Mercury2/src/MSemaphore.cpp 2010-11-13 21:40:17 UTC (rev 762) @@ -7,10 +7,6 @@ } #ifndef WIN32 -#define SYNC_OR_AND_FETCH(d,v) __sync_or_and_fetch(d,v) -#define COMPARE_AND_SWAP(d,o,n) __sync_val_compare_and_swap(d,o,n) -#define SYNC_AND_AND_FETCH(d,v) __sync_and_and_fetch(d,v) - unsigned long MSemaphore::ReadAndClear() { return __sync_fetch_and_and(&m_semaphore, 0); @@ -83,10 +79,6 @@ return Old & Value; } -#define SYNC_OR_AND_FETCH(d,v) ((uint32_t)OrAndFetch(d,v)) -#define COMPARE_AND_SWAP(d,o,n) ((uint32_t)InterlockedCompareExchange(d, n, o)) -#define SYNC_AND_AND_FETCH(d,v) ((uint32_t)__sync_and_and_fetch(d,v)) - unsigned long MSemaphore::ReadAndClear() { return MyInterlockedAnd(&m_semaphore, 0); Modified: Mercury2/src/MSemaphore.h =================================================================== --- Mercury2/src/MSemaphore.h 2010-11-13 01:16:27 UTC (rev 761) +++ Mercury2/src/MSemaphore.h 2010-11-13 21:40:17 UTC (rev 762) @@ -1,92 +1,106 @@ -#ifndef MSEMAPHORE_H -#define MSEMAPHORE_H - -#include <global.h> - -#ifdef WIN32 -#include <windows.h> -#endif - -class MSemaphore -{ - public: - MSemaphore(); - - unsigned long Read(); - unsigned long ReadAndClear(); - unsigned long Decrement(); - unsigned long Increment(); - void WaitAndSet(uint32_t value, uint32_t newVal); - - void Wait(); - void UnLock(); - private: - - //what exactly needs to be volatile? - uint32_t m_lockCount; -#ifndef WIN32 - uint32_t m_semaphore; -#else - volatile LONG m_semaphore; //align to 32bit boundary -#endif -}; - -class MSemaphoreLock -{ - public: - MSemaphoreLock(MSemaphore* s); - ~MSemaphoreLock(); - private: - MSemaphore* m_s; -}; - -class MSemaphoreIncOnDestroy -{ - public: - MSemaphoreIncOnDestroy(MSemaphore* s); - ~MSemaphoreIncOnDestroy(); - private: - MSemaphore* m_s; -}; - -class MSemaphoreDecOnDestroy -{ - public: - MSemaphoreDecOnDestroy(MSemaphore* s); - ~MSemaphoreDecOnDestroy(); - private: - MSemaphore* m_s; -}; - -#endif -/**************************************************************************** - * Copyright (C) 2008 by Joshua Allen * - * * - * * - * All rights reserved. * - * * - * Redistribution and use in source and binary forms, with or without * - * modification, are permitted provided that the following conditions * - * are met: * - * * Redistributions of source code must retain the above copyright * - * notice, this list of conditions and the following disclaimer. * - * * Redistributions in binary form must reproduce the above * - * copyright notice, this list of conditions and the following * - * disclaimer in the documentation and/or other materials provided * - * with the distribution. * - * * Neither the name of the Mercury Engine nor the names of its * - * contributors may be used to endorse or promote products derived * - * from this software without specific prior written permission. * - * * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - ***************************************************************************/ +#ifndef MSEMAPHORE_H +#define MSEMAPHORE_H + +#include <global.h> + +#ifdef WIN32 +#include <windows.h> +#endif + +#ifndef WIN32 + +#define SYNC_OR_AND_FETCH(d,v) __sync_or_and_fetch(d,v) +#define COMPARE_AND_SWAP(d,o,n) __sync_val_compare_and_swap(d,o,n) +#define SYNC_AND_AND_FETCH(d,v) __sync_and_and_fetch(d,v) + +#else + +#define SYNC_OR_AND_FETCH(d,v) ((uint32_t)OrAndFetch(d,v)) +#define COMPARE_AND_SWAP(d,o,n) ((uint32_t)InterlockedCompareExchange(d, n, o)) +#define SYNC_AND_AND_FETCH(d,v) ((uint32_t)__sync_and_and_fetch(d,v)) + +#endif + +class MSemaphore +{ + public: + MSemaphore(); + + unsigned long Read(); + unsigned long ReadAndClear(); + unsigned long Decrement(); + unsigned long Increment(); + void WaitAndSet(uint32_t value, uint32_t newVal); + + void Wait(); + void UnLock(); + private: + + //what exactly needs to be volatile? + uint32_t m_lockCount; +#ifndef WIN32 + uint32_t m_semaphore; +#else + volatile LONG m_semaphore; //align to 32bit boundary +#endif +}; + +class MSemaphoreLock +{ + public: + MSemaphoreLock(MSemaphore* s); + ~MSemaphoreLock(); + private: + MSemaphore* m_s; +}; + +class MSemaphoreIncOnDestroy +{ + public: + MSemaphoreIncOnDestroy(MSemaphore* s); + ~MSemaphoreIncOnDestroy(); + private: + MSemaphore* m_s; +}; + +class MSemaphoreDecOnDestroy +{ + public: + MSemaphoreDecOnDestroy(MSemaphore* s); + ~MSemaphoreDecOnDestroy(); + private: + MSemaphore* m_s; +}; + +#endif +/**************************************************************************** + * Copyright (C) 2008 by Joshua Allen * + * * + * * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * Redistributions in binary form must reproduce the above * + * copyright notice, this list of conditions and the following * + * disclaimer in the documentation and/or other materials provided * + * with the distribution. * + * * Neither the name of the Mercury Engine nor the names of its * + * contributors may be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + ***************************************************************************/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-11-13 21:40:58
|
Revision: 763 http://hgengine.svn.sourceforge.net/hgengine/?rev=763&view=rev Author: axlecrusher Date: 2010-11-13 21:40:52 +0000 (Sat, 13 Nov 2010) Log Message: ----------- go back to just using the stack Modified Paths: -------------- Mercury2/src/MercuryVertex.cpp Mercury2/src/MercuryVertex.h Modified: Mercury2/src/MercuryVertex.cpp =================================================================== --- Mercury2/src/MercuryVertex.cpp 2010-11-13 21:40:17 UTC (rev 762) +++ Mercury2/src/MercuryVertex.cpp 2010-11-13 21:40:52 UTC (rev 763) @@ -1,28 +1,28 @@ #include <MercuryVertex.h> #include <MercuryUtil.h> #include <MercuryMath.h> - +/* float* MercuryVertex::GetFloatMem() { if (m_memory==NULL) { m_memory = new MercuryMemory< FloatRow >(1024); } -// return new FloatRow; - return (float*)m_memory->Allocate(); + return new FloatRow; +// return (float*)m_memory->Allocate(); } - +*/ MercuryVertex::MercuryVertex() - :m_xyzw(NULL) +// :m_xyzw(NULL) { - m_xyzw = GetFloatMem(); +// m_xyzw = GetFloatMem(); m_xyzw[0] = m_xyzw[1] = m_xyzw[2] = m_xyzw[3] = 0; } MercuryVertex::MercuryVertex( float ix, float iy, float iz, float iw ) - :m_xyzw(NULL) +// :m_xyzw(NULL) { - m_xyzw = GetFloatMem(); +// m_xyzw = GetFloatMem(); m_xyzw[0] = ix; m_xyzw[1] = iy; m_xyzw[2] = iz; @@ -30,46 +30,47 @@ } MercuryVertex::MercuryVertex( const float* in3f, float f ) - :m_xyzw(NULL) +// :m_xyzw(NULL) { - m_xyzw = GetFloatMem(); +// m_xyzw = GetFloatMem(); for (unsigned int i = 0; i < 3; ++i) (*this)[i] = in3f[i]; m_xyzw[3] = f; } MercuryVertex::MercuryVertex( const float* in4f ) - :m_xyzw(NULL) +// :m_xyzw(NULL) { - m_xyzw = GetFloatMem(); +// m_xyzw = GetFloatMem(); for (unsigned int i = 0; i < 4; ++i) (*this)[i] = in4f[i]; } MercuryVertex::MercuryVertex( const MercuryVertex& v) - :m_xyzw(NULL) +// :m_xyzw(NULL) { - m_xyzw = GetFloatMem(); +// m_xyzw = GetFloatMem(); for (unsigned int i = 0; i < 4; ++i) (*this)[i] = v[i]; } MercuryVertex::MercuryVertex( const MercuryVertex& v, float w) - :m_xyzw(NULL) +// :m_xyzw(NULL) { - m_xyzw = GetFloatMem(); +// m_xyzw = GetFloatMem(); for (unsigned int i = 0; i < 3; ++i) (*this)[i] = v[i]; m_xyzw[3] = w; } - +/* MercuryVertex::~MercuryVertex() { - if (m_xyzw!=NULL) - m_memory->Free((FloatRow*)m_xyzw); - m_xyzw = NULL; +// if (m_xyzw!=NULL) +// delete m_xyzw; +// m_memory->Free((FloatRow*)m_xyzw); +// m_xyzw = NULL; } - +*/ void MercuryVertex::NormalizeSelf() { float imag = 1.0f/Length(); @@ -170,7 +171,7 @@ return MercuryVertex(x,y,z); } -MercuryMemory< FloatRow >* MercuryVertex::m_memory = NULL; +//MercuryMemory< FloatRow >* MercuryVertex::m_memory = NULL; /**************************************************************************** * Copyright (C) 2009 by Joshua Allen * Modified: Mercury2/src/MercuryVertex.h =================================================================== --- Mercury2/src/MercuryVertex.h 2010-11-13 21:40:17 UTC (rev 762) +++ Mercury2/src/MercuryVertex.h 2010-11-13 21:40:52 UTC (rev 763) @@ -21,7 +21,7 @@ MercuryVertex( const float* in4f ); MercuryVertex( const MercuryVertex& v); MercuryVertex( const MercuryVertex& v, float w); - virtual ~MercuryVertex(); +// virtual ~MercuryVertex(); ///Direct conversion to float* __inline__ operator float* () { return m_xyzw; } @@ -96,11 +96,11 @@ static MercuryVertex CreateFromString(const MString& s); // float m_xyzw[3]; -// FloatRow m_xyzw; private: - float* m_xyzw; - static MercuryMemory< FloatRow >* m_memory; - static float* GetFloatMem(); + FloatRow m_xyzw; +// float* m_xyzw; +// static MercuryMemory< FloatRow >* m_memory; +// static float* GetFloatMem(); }; typedef MercuryVertex MercuryVector; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-11-13 21:41:34
|
Revision: 764 http://hgengine.svn.sourceforge.net/hgengine/?rev=764&view=rev Author: axlecrusher Date: 2010-11-13 21:41:24 +0000 (Sat, 13 Nov 2010) Log Message: ----------- Use unaligned memory operations Modified Paths: -------------- Mercury2/src/MercuryMath.cpp Mercury2/src/MercuryMath.h Modified: Mercury2/src/MercuryMath.cpp =================================================================== --- Mercury2/src/MercuryMath.cpp 2010-11-13 21:40:52 UTC (rev 763) +++ Mercury2/src/MercuryMath.cpp 2010-11-13 21:41:24 UTC (rev 764) @@ -176,37 +176,37 @@ void Mul4f(const FloatRow& first, const FloatRow& second, FloatRow& out) { __m128 a,b,o; - a = _mm_load_ps(first); - b = _mm_load_ps(second); + a = _mm_loadu_ps(first); + b = _mm_loadu_ps(second); o = _mm_mul_ps( a, b ); - _mm_store_ps(out,o); + _mm_storeu_ps(out,o); } void Div4f(const FloatRow& first, const FloatRow& second, FloatRow& out) { __m128 a,b,o; - a = _mm_load_ps(first); - b = _mm_load_ps(second); + a = _mm_loadu_ps(first); + b = _mm_loadu_ps(second); o = _mm_div_ps( a, b ); - _mm_store_ps(out,o); + _mm_storeu_ps(out,o); } void Add4f(const FloatRow& first, const FloatRow& second, FloatRow& out) { __m128 a,b,o; - a = _mm_load_ps(first); - b = _mm_load_ps(second); + a = _mm_loadu_ps(first); + b = _mm_loadu_ps(second); o = _mm_add_ps( a, b ); - _mm_store_ps(out,o); + _mm_storeu_ps(out,o); } void Sub4f(const FloatRow& first, const FloatRow& second, FloatRow& out) { __m128 a,b,o; - a = _mm_load_ps(first); - b = _mm_load_ps(second); + a = _mm_loadu_ps(first); + b = _mm_loadu_ps(second); o = _mm_sub_ps( a, b ); - _mm_store_ps(out,o); + _mm_storeu_ps(out,o); } void MatrixMultiply4f( const FloatRow* in1, const FloatRow* in2, FloatRow* out) @@ -327,7 +327,13 @@ { __m128 tmp,tmp2, XY, pp; - pp=_mm_load_ps(p); + //load and loadu seem to run at nearly the same speed + //see benchmark file + pp=_mm_loadu_ps(p); +// pp=_mm_load_ps(p); + + //this function can run long so try to move the output clocer to the CPU while function is running + PREFETCH((const char*)out,_MM_HINT_T1); //compute term X and term Y and store them in the low order of XY XY = Hadd4( _mm_mul_ps( _mm_load_ps(matrix[0]), pp ) ); //compute X @@ -343,7 +349,7 @@ //and shuffle the low order of out into the high order of out tmp = _mm_movelh_ps(XY, pp); - _mm_store_ps(out, tmp); + _mm_storeu_ps(out, tmp); } /* void ZeroFloatRow(FloatRow& r) Modified: Mercury2/src/MercuryMath.h =================================================================== --- Mercury2/src/MercuryMath.h 2010-11-13 21:40:52 UTC (rev 763) +++ Mercury2/src/MercuryMath.h 2010-11-13 21:41:24 UTC (rev 764) @@ -1,157 +1,158 @@ -#ifndef _MERCURYMATH_H +#ifndef _MERCURYMATH_H #define _MERCURYMATH_H - -#include <math.h> -#include <string.h> - -#ifdef HGENGINE -#ifndef WIN32 -#include <configuration.h> -#endif -#endif - + +#include <math.h> +#include <string.h> + +#ifdef HGENGINE +#ifndef WIN32 +#include <configuration.h> +#endif +#endif + #if defined(__GNUC__) #define VC_ALIGN(n) #define CC_ALIGN(n) __attribute__((aligned(n))) #else #define VC_ALIGN(n) __declspec(align(n)) #define CC_ALIGN(n) -#endif - -#ifdef USE_SSE -#include <xmmintrin.h> -#define PREFETCH(a,sel) _mm_prefetch(a,sel); //prefetch a cache line (64 bytes) -#else -#define PREFETCH(a,sel) ; //prefetch a cache line (64 bytes) -#endif -/* -VC_ALIGN(16) class FloatRow -{ - public: - inline operator float*() { return (float*)&m_floats; } - inline operator const float*() const { return (const float*)&m_floats; } - -#ifndef USE_SSE - float m_floats[4]; -#else - inline FloatRow& operator=(const __m128& f) { m_floats=f; return *this; } - - inline operator __m128&() { return m_floats; } - inline operator const __m128&() const { return m_floats; } -// __m128 m_floats __attribute__((aligned(16))); - __m128 m_floats; -#endif -} CC_ALIGN(16); -*/ - -typedef VC_ALIGN(16) float FloatRow[4] CC_ALIGN(16); - -#ifdef WIN32 -#include <limits> -#define INFINITY (std::numeric_limits<float>::infinity()) -#else -#define MAXINT (0x7FFFFFFF) -#endif - - -void ZeroFloatRow(FloatRow& r); - -#define DEGRAD 0.01745329251994329576f //degree to radian -#define RADDEG 57.2957795130823208767f //radian to degree -#define Q_PI 3.14159265358979323846f - -template<typename t, unsigned i> -inline void COPY(const t* s, t*d) -{ - d[i-1] = s[i-1]; - COPY<t,i-1>(s,d); -} - -template<> inline void COPY<float,0>(const float* s, float* d) -{ - d[0] = s[0]; -} - -#if defined(WIN32) -//In win32, sin works faster than sinf and similar functions -#define SIN( x ) float( sin ( x ) ) -#define COS( x ) float( cos ( x ) ) -#define ATAN2( x, y ) float( atan2( x, y ) ) -#define ASIN( x ) float( asin ( x ) ) -#define ACOS( x ) float( acos ( x ) ) -#define SQRT( x ) float( sqrt ( x ) ) -#define TAN( x ) float( tan ( x ) ) -#define ABS( x ) float( ((x<0)?(-x):(x)) ) -inline int LRINTF(float x) { int r = (int)x; (x-r)>=0.5?++r:0; return r; }; -#else -//On other OSes in general, sinf works faster than floating a sin -#define SIN( x ) sinf( x ) -#define COS( x ) cosf( x ) -#define ATAN2( x, y ) atan2f( x, y ) -#define ASIN( x ) asinf ( x ) -#define ACOS( x ) acosf ( x ) -#define SQRT( x ) sqrtf( x ) -#define TAN( x ) tanf( x ) -#define ABS( x ) ((x<0)?(-x):(x)) -#define LRINTF( x ) lrintf( x ) -#endif - -#define SQ(x) ((x)*(x)); - -//#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) - -void Mul4f(const FloatRow& first, const FloatRow& second, FloatRow& out); -void Div4f(const FloatRow& first, const FloatRow& second, FloatRow& out); -void Add4f(const FloatRow& first, const FloatRow& second, FloatRow& out); -void Sub4f(const FloatRow& first, const FloatRow& second, FloatRow& out); -inline void Copy4f( void * dest, const void * source ) { memcpy(dest,source,16); } -inline void Copy8f( void * dest, const void * source ) { memcpy(dest,source,32); } -inline void Copy16f( void * dest, const void * source ) { memcpy(dest,source,64); } -void MatrixMultiply4f ( const FloatRow* in1, const FloatRow* in2, FloatRow* out ); -void VectorMultiply4f(const FloatRow* matrix, const FloatRow& p, FloatRow& out ); -void TransposeMatrix(const FloatRow* matrix, FloatRow* out); -void MMCrossProduct( const FloatRow& r1, const FloatRow& r2, FloatRow& result); -void LoadIdentity(FloatRow* matrix); - -//http://graphics.stanford.edu/~seander/bithacks.html -inline unsigned int SetBit(unsigned int x, unsigned int mask, bool t) -{ -#if defined(WIN32) - #pragma warning( disable : 4804 ) -#endif - return ((x & ~mask) | (-t & mask)); /*superscalar CPU version*/ -} -inline bool GetBit(unsigned int x, unsigned int mask) { return ((x & mask)>0); } - -//void Float2FloatRow(const float* f, FloatRow& r); -//void FloatRow2Float(const FloatRow& fr, float* f); - -const FloatRow gfrZero = { 0.f, 0.f, 0.f, 0.f }; - -#endif - -/* - * (c) 2006 Joshua Allen - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - +#endif + +#ifdef USE_SSE +#include <xmmintrin.h> +#define PREFETCH(a,sel) _mm_prefetch(a,sel); //prefetch a cache line (64 bytes) +#else +#define PREFETCH(a,sel) ; //prefetch a cache line (64 bytes) +#endif +/* +VC_ALIGN(16) class FloatRow +{ + public: + inline operator float*() { return (float*)&m_floats; } + inline operator const float*() const { return (const float*)&m_floats; } + +#ifndef USE_SSE + float m_floats[4]; +#else + inline FloatRow& operator=(const __m128& f) { m_floats=f; return *this; } + + inline operator __m128&() { return m_floats; } + inline operator const __m128&() const { return m_floats; } +// __m128 m_floats __attribute__((aligned(16))); + __m128 m_floats; +#endif +} CC_ALIGN(16); +*/ + +typedef VC_ALIGN(16) float FloatRow[4] CC_ALIGN(16); +//typedef float FloatRow[4]; + +#ifdef WIN32 +#include <limits> +#define INFINITY (std::numeric_limits<float>::infinity()) +#else +#define MAXINT (0x7FFFFFFF) +#endif + + +void ZeroFloatRow(FloatRow& r); + +#define DEGRAD 0.01745329251994329576f //degree to radian +#define RADDEG 57.2957795130823208767f //radian to degree +#define Q_PI 3.14159265358979323846f + +template<typename t, unsigned i> +inline void COPY(const t* s, t*d) +{ + d[i-1] = s[i-1]; + COPY<t,i-1>(s,d); +} + +template<> inline void COPY<float,0>(const float* s, float* d) +{ + d[0] = s[0]; +} + +#if defined(WIN32) +//In win32, sin works faster than sinf and similar functions +#define SIN( x ) float( sin ( x ) ) +#define COS( x ) float( cos ( x ) ) +#define ATAN2( x, y ) float( atan2( x, y ) ) +#define ASIN( x ) float( asin ( x ) ) +#define ACOS( x ) float( acos ( x ) ) +#define SQRT( x ) float( sqrt ( x ) ) +#define TAN( x ) float( tan ( x ) ) +#define ABS( x ) float( ((x<0)?(-x):(x)) ) +inline int LRINTF(float x) { int r = (int)x; (x-r)>=0.5?++r:0; return r; }; +#else +//On other OSes in general, sinf works faster than floating a sin +#define SIN( x ) sinf( x ) +#define COS( x ) cosf( x ) +#define ATAN2( x, y ) atan2f( x, y ) +#define ASIN( x ) asinf ( x ) +#define ACOS( x ) acosf ( x ) +#define SQRT( x ) sqrtf( x ) +#define TAN( x ) tanf( x ) +#define ABS( x ) ((x<0)?(-x):(x)) +#define LRINTF( x ) lrintf( x ) +#endif + +#define SQ(x) ((x)*(x)); + +//#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) + +void Mul4f(const FloatRow& first, const FloatRow& second, FloatRow& out); +void Div4f(const FloatRow& first, const FloatRow& second, FloatRow& out); +void Add4f(const FloatRow& first, const FloatRow& second, FloatRow& out); +void Sub4f(const FloatRow& first, const FloatRow& second, FloatRow& out); +inline void Copy4f( void * dest, const void * source ) { memcpy(dest,source,16); } +inline void Copy8f( void * dest, const void * source ) { memcpy(dest,source,32); } +inline void Copy16f( void * dest, const void * source ) { memcpy(dest,source,64); } +void MatrixMultiply4f ( const FloatRow* in1, const FloatRow* in2, FloatRow* out ); +void VectorMultiply4f(const FloatRow* matrix, const FloatRow& p, FloatRow& out ); +void TransposeMatrix(const FloatRow* matrix, FloatRow* out); +void MMCrossProduct( const FloatRow& r1, const FloatRow& r2, FloatRow& result); +void LoadIdentity(FloatRow* matrix); + +//http://graphics.stanford.edu/~seander/bithacks.html +inline unsigned int SetBit(unsigned int x, unsigned int mask, bool t) +{ +#if defined(WIN32) + #pragma warning( disable : 4804 ) +#endif + return ((x & ~mask) | (-t & mask)); /*superscalar CPU version*/ +} +inline bool GetBit(unsigned int x, unsigned int mask) { return ((x & mask)>0); } + +//void Float2FloatRow(const float* f, FloatRow& r); +//void FloatRow2Float(const FloatRow& fr, float* f); + +const FloatRow gfrZero = { 0.f, 0.f, 0.f, 0.f }; + +#endif + +/* + * (c) 2006 Joshua Allen + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-11-13 21:42:31
|
Revision: 765 http://hgengine.svn.sourceforge.net/hgengine/?rev=765&view=rev Author: axlecrusher Date: 2010-11-13 21:42:25 +0000 (Sat, 13 Nov 2010) Log Message: ----------- add benchmark so that we can keep track of tests that we do Added Paths: ----------- Mercury2/src/Benchmark.cpp Mercury2/src/Benchmark.h Added: Mercury2/src/Benchmark.cpp =================================================================== --- Mercury2/src/Benchmark.cpp (rev 0) +++ Mercury2/src/Benchmark.cpp 2010-11-13 21:42:25 UTC (rev 765) @@ -0,0 +1,44 @@ +#include <Benchmark.h> +#include <stdio.h> +#include <stdlib.h> + +void BenchmarkSSELoad() +{ + /*_mm_load_ps and _mm_loadu_ps seem to run at nearly the same speed + _mm_loadu_ps 5.886555ns vs _mm_load_ps 5.564690ns + */ + MercuryTimer start; + const unsigned long c = 1024*1024*20; + FloatRow* d = new FloatRow[c]; + //d = (FloatRow*)(((char*)d)+4); + printf("%d\n", ((unsigned long)d)%16); + __m128 pp; + unsigned long* idx = new unsigned long[c]; + for (int x = 0; x<c;++x) + { + unsigned int r = (unsigned int)rand(); + idx[c] = r%c; + } + + double tu, ta; + tu = ta = 0; + for (int x = 0; x<10;++x) + { + start.Touch(); + for (unsigned int i = 0; i < c;++i) + { + pp=_mm_loadu_ps(d[i]); + _mm_storeu_ps(d[i],pp); + } + tu += start.Touch()*1000000000; //to nano second + for (unsigned int i = 0; i < c;++i) + { + pp=_mm_load_ps(d[i]); + _mm_store_ps(d[i],pp); + } + ta += start.Touch()*1000000000; //to nano second + } + printf("loadu %f\n", tu/float(c)/10/2); + printf("load %f\n", ta/float(c)/10/2); + exit(0); +} \ No newline at end of file Added: Mercury2/src/Benchmark.h =================================================================== --- Mercury2/src/Benchmark.h (rev 0) +++ Mercury2/src/Benchmark.h 2010-11-13 21:42:25 UTC (rev 765) @@ -0,0 +1,41 @@ +#ifndef MBENCHMARK_H +#define MBENCHMARK_H + +#include <MercuryTimer.h> +#include <MercuryMath.h> + +void BenchmarkSSELoad(); + +#endif + +/**************************************************************************** + * Copyright (C) 2010 by Joshua Allen * + * * + * * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * Redistributions in binary form must reproduce the above * + * copyright notice, this list of conditions and the following * + * disclaimer in the documentation and/or other materials provided * + * with the distribution. * + * * Neither the name of the Mercury Engine nor the names of its * + * contributors may be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + ***************************************************************************/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-11-21 04:53:01
|
Revision: 767 http://hgengine.svn.sourceforge.net/hgengine/?rev=767&view=rev Author: axlecrusher Date: 2010-11-21 04:52:54 +0000 (Sun, 21 Nov 2010) Log Message: ----------- Change active texture stack to an array based stack. This is much faster and avoids a lot of things that std::list does, like issuing many new statements. Modified Paths: -------------- Mercury2/src/RenderGraph.cpp Mercury2/src/Texture.cpp Mercury2/src/Texture.h Added Paths: ----------- Mercury2/src/ArrayStack.h Added: Mercury2/src/ArrayStack.h =================================================================== --- Mercury2/src/ArrayStack.h (rev 0) +++ Mercury2/src/ArrayStack.h 2010-11-21 04:52:54 UTC (rev 767) @@ -0,0 +1,66 @@ +#ifndef ARRAYSTACK_H +#define ARRAYSTACK_H + +template <typename T> +class ArrayStack +{ + public: + ArrayStack(unsigned long size) + :m_stack(NULL), m_nextSpot(0),m_size(size) + { + m_stack = new T[m_size]; + }; + + ~ArrayStack() + { + delete[] m_stack; + } + + void Push(T x) { m_stack[m_nextSpot++] = x; } + + void Pop() { --m_nextSpot; } + + T Top() { return m_stack[m_nextSpot-1]; } + + unsigned long Depth() const { return m_nextSpot; } + + T operator[](unsigned long i) const { return m_stack[i]; } + + private: + T* m_stack; + unsigned long m_nextSpot; + unsigned long m_size; +}; + +#endif +/**************************************************************************** + * Copyright (C) 2010 by Joshua Allen * + * * + * * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * Redistributions in binary form must reproduce the above * + * copyright notice, this list of conditions and the following * + * disclaimer in the documentation and/or other materials provided * + * with the distribution. * + * * Neither the name of the Mercury Engine nor the names of its * + * contributors may be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + ***************************************************************************/ Modified: Mercury2/src/RenderGraph.cpp =================================================================== --- Mercury2/src/RenderGraph.cpp 2010-11-21 04:01:56 UTC (rev 766) +++ Mercury2/src/RenderGraph.cpp 2010-11-21 04:52:54 UTC (rev 767) @@ -154,10 +154,9 @@ void StoreRenderState::Save() { //get assets for current textures - const std::list< Texture* >& textures = Texture::GetActiveTextures(); - std::list< Texture* >::const_iterator i = textures.begin(); - for (;i != textures.end(); ++i) - Assets.push_back( *i ); + const ArrayStack< Texture* >& textures = Texture::GetActiveTextures(); + for (unsigned short i = 0; i<textures.Depth(); ++i) + Assets.push_back( textures[i] ); //save the active shader Shader* s = Shader::GetCurrentShader(); Modified: Mercury2/src/Texture.cpp =================================================================== --- Mercury2/src/Texture.cpp 2010-11-21 04:01:56 UTC (rev 766) +++ Mercury2/src/Texture.cpp 2010-11-21 04:52:54 UTC (rev 767) @@ -191,8 +191,8 @@ sa.value.iSampler = m_numActiveTextures; Shader::SetAttribute( ssprintf("HG_Texture%d", m_numActiveTextures), sa); - m_activeTextures.push_back(this); - + m_activeTextures.Push(this); + ++m_numActiveTextures; } @@ -202,7 +202,7 @@ --m_numActiveTextures; Shader::RemoveAttribute( ssprintf("HG_Texture%d", m_numActiveTextures) ); - m_activeTextures.pop_back(); + m_activeTextures.Pop(); // Deactivate(GL_TEXTURE0 + m_numActiveTextures); } @@ -351,7 +351,7 @@ bool Texture::m_initTextureSuccess = false; uint8_t Texture::m_numActiveTextures = 0; uint32_t Texture::m_textureBinds = 0; -std::list< Texture* > Texture::m_activeTextures; +ArrayStack< Texture* > Texture::m_activeTextures(Texture::TextureStackDepth); Texture** Texture::m_lastBound = NULL; uint8_t Texture::m_maxActiveTextures = 0; Modified: Mercury2/src/Texture.h =================================================================== --- Mercury2/src/Texture.h 2010-11-21 04:01:56 UTC (rev 766) +++ Mercury2/src/Texture.h 2010-11-21 04:52:54 UTC (rev 767) @@ -4,6 +4,8 @@ #include <MercuryAsset.h> #include <RawImageData.h> +#include <ArrayStack.h> + enum TextureFilterMode { TF_NONE, @@ -13,6 +15,8 @@ class Texture : public MercuryAsset { + private: + static const unsigned int TextureStackDepth = 16; public: Texture( const MString & key, bool bInstanced ); virtual ~Texture(); @@ -39,7 +43,7 @@ static MAutoPtr< Texture > LoadFromFile(const MString& path); static MAutoPtr< Texture > LoadDynamicTexture(const MString& name); - static const std::list< Texture* >& GetActiveTextures() { return m_activeTextures; } + static const ArrayStack< Texture* >& GetActiveTextures() { return m_activeTextures; } void SetRawData(RawImageData* raw); @@ -72,7 +76,7 @@ static bool m_initTextureSuccess; static uint8_t m_numActiveTextures; static uint32_t m_textureBinds; - static std::list< Texture* > m_activeTextures; + static ArrayStack< Texture* > m_activeTextures; static uint8_t m_maxActiveTextures; static Texture** m_lastBound; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-11-21 14:22:40
|
Revision: 768 http://hgengine.svn.sourceforge.net/hgengine/?rev=768&view=rev Author: axlecrusher Date: 2010-11-21 14:22:34 +0000 (Sun, 21 Nov 2010) Log Message: ----------- Make an array of strings that can be used to set ShaderAttribute. This removes a lot of ssprintf statements, malloc, and free calls. Provides a noticeable boost in performance. Modified Paths: -------------- Mercury2/src/Texture.cpp Mercury2/src/Texture.h Modified: Mercury2/src/Texture.cpp =================================================================== --- Mercury2/src/Texture.cpp 2010-11-21 04:52:54 UTC (rev 767) +++ Mercury2/src/Texture.cpp 2010-11-21 14:22:34 UTC (rev 768) @@ -19,6 +19,9 @@ { m_initTextureSuccess = true; m_numActiveTextures = 0; + m_shaderBindPoints = new MString[Texture::TextureStackDepth]; + for (unsigned short i = 0; i < Texture::TextureStackDepth; ++i) + m_shaderBindPoints[i] = ssprintf("HG_Texture%d", m_numActiveTextures); } SetIgnoreCull( true ); @@ -189,7 +192,7 @@ ShaderAttribute sa; sa.type = ShaderAttribute::TYPE_SAMPLER; sa.value.iSampler = m_numActiveTextures; - Shader::SetAttribute( ssprintf("HG_Texture%d", m_numActiveTextures), sa); + Shader::SetAttribute( m_shaderBindPoints[m_numActiveTextures], sa); m_activeTextures.Push(this); @@ -201,15 +204,25 @@ //Everything needs to be done in reverse of BindTexture() --m_numActiveTextures; - Shader::RemoveAttribute( ssprintf("HG_Texture%d", m_numActiveTextures) ); + Shader::RemoveAttribute( m_shaderBindPoints[m_numActiveTextures] ); m_activeTextures.Pop(); // Deactivate(GL_TEXTURE0 + m_numActiveTextures); } +void Texture::ActiveTexture(uint32_t i) +{ + static uint32_t active = 0; + if (active!=i) + { + GLCALL( glActiveTexture( i ) ); + } + active = i; +} + void Texture::Activate(uint32_t textureResource) { - GLCALL( glActiveTexture( textureResource ) ); + ActiveTexture(textureResource); // GLCALL( glClientActiveTextureARB(textureResource) ); //XXX: Note to self, this seems to be causing a crash, look into it. GLCALL( glEnableClientState(GL_TEXTURE_COORD_ARRAY) ); GLCALL( glEnable( GL_TEXTURE_2D ) ); @@ -217,7 +230,7 @@ void Texture::Deactivate(uint32_t textureResource) { - GLCALL( glActiveTexture( textureResource ) ); + ActiveTexture(textureResource); // GLCALL( glClientActiveTextureARB(textureResource) ); GLCALL( glDisableClientState(GL_TEXTURE_COORD_ARRAY) ); GLCALL( glDisable( GL_TEXTURE_2D ) ); @@ -228,7 +241,7 @@ { for (uint8_t i = 0; i < m_numActiveTextures; ++i) { - GLCALL( glActiveTexture( GL_TEXTURE0+i ) ); + ActiveTexture(GL_TEXTURE0+i); // GLCALL( glClientActiveTextureARB(GL_TEXTURE0+i) ); //XXX: Note to self, this seems to be causing a crash, look into it. GLCALL( glTexCoordPointer(2, GL_FLOAT, stride, BUFFER_OFFSET(uvByteOffset)) ); } @@ -355,6 +368,8 @@ Texture** Texture::m_lastBound = NULL; uint8_t Texture::m_maxActiveTextures = 0; +MString* Texture::m_shaderBindPoints = NULL; + /*************************************************************************** * Copyright (C) 2008 by Joshua Allen * * * Modified: Mercury2/src/Texture.h =================================================================== --- Mercury2/src/Texture.h 2010-11-21 04:52:54 UTC (rev 767) +++ Mercury2/src/Texture.h 2010-11-21 14:22:34 UTC (rev 768) @@ -49,6 +49,7 @@ static void ApplyActiveTextures(uint16_t stride, uint8_t uvByteOffset); static void DisableUnusedTextures(); + static void ActiveTexture(uint32_t i); static MString GenKey(const MString& k, const XMLNode* n); @@ -77,6 +78,7 @@ static uint8_t m_numActiveTextures; static uint32_t m_textureBinds; static ArrayStack< Texture* > m_activeTextures; + static MString* m_shaderBindPoints; static uint8_t m_maxActiveTextures; static Texture** m_lastBound; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-11-21 19:38:25
|
Revision: 769 http://hgengine.svn.sourceforge.net/hgengine/?rev=769&view=rev Author: axlecrusher Date: 2010-11-21 19:38:18 +0000 (Sun, 21 Nov 2010) Log Message: ----------- use lock free stack to reduce locks in MercuryMemory to near zero Modified Paths: -------------- Mercury2/src/MSemaphore.h Mercury2/src/MercuryMemory.h Added Paths: ----------- Mercury2/src/MStack.h Modified: Mercury2/src/MSemaphore.h =================================================================== --- Mercury2/src/MSemaphore.h 2010-11-21 14:22:34 UTC (rev 768) +++ Mercury2/src/MSemaphore.h 2010-11-21 19:38:18 UTC (rev 769) @@ -19,6 +19,12 @@ #define COMPARE_AND_SWAP(d,o,n) ((uint32_t)InterlockedCompareExchange(d, n, o)) #define SYNC_AND_AND_FETCH(d,v) ((uint32_t)__sync_and_and_fetch(d,v)) +inline void* CAS_PTR(volatile void** d, void* e, void* c) +{ + //these variables must be 32 bit aligned on x86 and 64 bit aligned on x64 + return InterlockedCompareExchangePointer((volatile PVOID*)d,e,c); +} + #endif class MSemaphore Added: Mercury2/src/MStack.h =================================================================== --- Mercury2/src/MStack.h (rev 0) +++ Mercury2/src/MStack.h 2010-11-21 19:38:18 UTC (rev 769) @@ -0,0 +1,117 @@ +#ifndef MSTACK_H +#define MSTACK_H + +#include <MSemaphore.h> + +template <typename T> +class MStack +{ + private: + struct Container + { + Container() + :m_next(NULL) + { } + T m_data; + volatile Container* m_next; + }; + + volatile Container* m_head; + volatile Container* m_freeContainers; + + // use instead of calling new Container() + Container* GetContainer() + { + Container* a = (Container*)m_freeContainers; + if (a==NULL) return new Container(); //make new container, don't care if a has changed since read + if ( CAS_PTR((volatile void**)&m_freeContainers,(void*)a->m_next,a)==a ) //true if swap made + return a; + return new Container(); + } + + //use instead of calling delete Container + void SaveContainerForFuture(Container* c) + { + do + { + c->m_next = m_freeContainers; + } + while( CAS_PTR((volatile void**)&m_freeContainers,c,(void*)c->m_next)!=c->m_next ); + } + + public: + MStack() + :m_head(NULL), m_freeContainers(NULL) + { + } + + void push(const T& data) + { + Container* a = GetContainer(); + a->m_data = data; + do + { + a->m_next = m_head; + } while ( CAS_PTR((volatile void**)&m_head,a,(void*)a->m_next)!=a->m_next ); + } + + bool pop() + { + if (m_head==NULL) return false; + Container* a = NULL; + do + { + a = m_head; + } while ( CAS_PTR((volatile void**)&m_head,(void*)a->m_next,a)!=a ); + SaveContainerForFuture(a); + return true; + } + + bool pop_get(T& d) + { + if (m_head==NULL) return false; + Container* a = NULL; + do + { + a = (Container*)m_head; + } while ( CAS_PTR((volatile void**)&m_head,(void*)a->m_next,a)!=a ); + d = a->m_data; + SaveContainerForFuture(a); + return true; + } + + inline bool empty() const { return m_head==NULL; } +}; + +#endif +/**************************************************************************** + * Copyright (C) 2010 by Joshua Allen * + * * + * * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * Redistributions in binary form must reproduce the above * + * copyright notice, this list of conditions and the following * + * disclaimer in the documentation and/or other materials provided * + * with the distribution. * + * * Neither the name of the Mercury Engine nor the names of its * + * contributors may be used to endorse or promote products derived * + * from this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + ***************************************************************************/ Modified: Mercury2/src/MercuryMemory.h =================================================================== --- Mercury2/src/MercuryMemory.h 2010-11-21 14:22:34 UTC (rev 768) +++ Mercury2/src/MercuryMemory.h 2010-11-21 19:38:18 UTC (rev 769) @@ -5,6 +5,8 @@ #include <list> #include <MSemaphore.h> +#include <MStack.h> + ///Memory holder for matrices template <typename T> class MercuryMemory @@ -14,105 +16,37 @@ free ride into the CPU cache. */ public: MercuryMemory(const uint32_t rows) - :m_freeMem(NULL),m_freeUnit(NULL),m_rows(rows) + :m_rows(rows) { -// m_lock.Wait(); AllocateMoreSpace(m_rows); -// m_lock.UnLock(); } T* Allocate() { T* m = NULL; - MemoryUnit* mu = NULL; - //keep really short lock - m_lock.Wait(); - if ( m_freeMem == NULL ) m_freeMem = AllocateMoreSpace(m_rows); - - //get record of free memory spot - mu = m_freeMem; - m_freeMem=m_freeMem->prev; - m = (T*)mu->mem; - - SaveFreeUnit(mu); - m_lock.UnLock(); -// delete mu; - -// if (m==NULL) { char* a = NULL; *a=0; } //no memory allocated?? + while ( !m_freeData.pop_get(m) ) AllocateMoreSpace(m_rows); return m; } - void Free(T* m) - { - m_lock.Wait(); -// for (MemoryUnit* mu=m_freeMem;mu!=NULL;mu=mu->prev) -// { - //probably could some some sorting here to get contigious free and used memory - //if free memory is alwasy given out in order, then used memory will also be in order -// if (m==mu->mem) { char* a=NULL;*a=0;} //WTF DOUBLE FREE -// } -// m_freeMem = new MemoryUnit(m_freeMem,m); + inline void Free(T* m) { m_freeData.push(m); } -/* - MemoryUnit* mu = m_freeUnit; - m_freeUnit = m_freeUnit->prev; //set top free unit to next free unit - //setup unit and add it to the top of the free memory - mu->prev = m_freeMem; - mu->mem = m; -*/ TakeFreeUnit(m); - - m_lock.UnLock(); - } - private: - struct MemoryUnit - { - MemoryUnit(MemoryUnit* p, void* m) - :mem(m),prev(p) - { -// if (p!=NULL) p->next = this; - } -// T* mem; - void* mem; - MemoryUnit* prev; - }; - MemoryUnit* AllocateMoreSpace(const uint32_t rows) + void AllocateMoreSpace(const uint32_t rows) { - MemoryUnit* mu = NULL; - AlignedBuffer<T>* d = new AlignedBuffer<T>(); d->Allocate(rows,16); - m_lock.Wait(); + m_lock.Wait(); //required m_data.push_back(d); - m_lock.UnLock(); + m_lock.UnLock(); //required for (unsigned int i = 0; i < rows;i++) - mu = new MemoryUnit(mu,(d->Buffer())+i); - return mu; + m_freeData.push(d->Buffer()+i); } - inline void TakeFreeUnit(T* m) - { - MemoryUnit* mu = m_freeUnit; - m_freeUnit = m_freeUnit->prev; //set top free unit to next free unit - //setup unit and add it to the top of the free memory - mu->prev = m_freeMem; - mu->mem = m; - m_freeMem = mu; - } - - void SaveFreeUnit(MemoryUnit* mu) - { - mu->mem = NULL; - mu->prev = m_freeUnit; - m_freeUnit = mu; - } - std::list< AlignedBuffer<T>* > m_data; - MemoryUnit* m_freeMem; //Free template memory - MemoryUnit* m_freeUnit; //Free MemoryUnits, for when + MStack< T* > m_freeData; MSemaphore m_lock; unsigned long m_rows; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-12-17 22:23:23
|
Revision: 771 http://hgengine.svn.sourceforge.net/hgengine/?rev=771&view=rev Author: axlecrusher Date: 2010-12-17 21:57:04 +0000 (Fri, 17 Dec 2010) Log Message: ----------- Macro out the glGetError and reduce redundant matrix loads Modified Paths: -------------- Mercury2/src/GLHeaders.h Mercury2/src/GLHelpers.cpp Modified: Mercury2/src/GLHeaders.h =================================================================== --- Mercury2/src/GLHeaders.h 2010-11-23 03:04:17 UTC (rev 770) +++ Mercury2/src/GLHeaders.h 2010-12-17 21:57:04 UTC (rev 771) @@ -24,12 +24,16 @@ #include <MercuryLog.h> +#if DO_GLERRORCHECK #define GLERRORCHECK { \ uint32_t e = GLCALL( glGetError() ); \ if ( e != GL_NO_ERROR ) { \ LOG.Write(ssprintf("GL Error:%s", GlError2String(e).c_str())); \ printf("GL Error:%s", GlError2String(e).c_str()); \ assert(0); } } +#else +#define GLERRORCHECK ; +#endif #define CHECKFBO { \ uint32_t e = GLCALL( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) ); \ Modified: Mercury2/src/GLHelpers.cpp =================================================================== --- Mercury2/src/GLHelpers.cpp 2010-11-23 03:04:17 UTC (rev 770) +++ Mercury2/src/GLHelpers.cpp 2010-12-17 21:57:04 UTC (rev 771) @@ -43,10 +43,15 @@ void glLoadMatrix(const MercuryMatrix& m) { + static const MercuryMatrix* lp = NULL; static MercuryMatrix l; l = m; l.Transpose(); - glLoadMatrixf( l.Ptr() ); + if ( lp != &m ) + { + GLCALL( glLoadMatrixf( l.Ptr() ) ); + } + lp = &m; } MercuryMatrix glGetMatrix(unsigned int m) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <axl...@us...> - 2010-12-18 00:10:25
|
Revision: 772 http://hgengine.svn.sourceforge.net/hgengine/?rev=772&view=rev Author: axlecrusher Date: 2010-12-18 00:10:19 +0000 (Sat, 18 Dec 2010) Log Message: ----------- MString to char[]. MString does not seem to work correctly in constant time with optimizations turned on. Modified Paths: -------------- Mercury2/src/MercuryFileDriverMem.cpp Mercury2/src/MercuryFileDriverPacked.cpp Mercury2/src/MercuryFileDriverZipped.cpp Modified: Mercury2/src/MercuryFileDriverMem.cpp =================================================================== --- Mercury2/src/MercuryFileDriverMem.cpp 2010-12-17 21:57:04 UTC (rev 771) +++ Mercury2/src/MercuryFileDriverMem.cpp 2010-12-18 00:10:19 UTC (rev 772) @@ -1,6 +1,6 @@ #include <MercuryFileDriverMem.h> -const MString MemoryFileName = "memory.zip"; +const char MemoryFileName[] = "memory.zip"; /********************FILE DRIVER MEMORY********************/ Modified: Mercury2/src/MercuryFileDriverPacked.cpp =================================================================== --- Mercury2/src/MercuryFileDriverPacked.cpp 2010-12-17 21:57:04 UTC (rev 771) +++ Mercury2/src/MercuryFileDriverPacked.cpp 2010-12-18 00:10:19 UTC (rev 772) @@ -2,7 +2,7 @@ #include <MercuryVector.h> #include <string.h> -const MString PackagePrefix = "Packages/"; +const char PackagePrefix[] = "Packages/"; MercuryFileObjectPacked::~MercuryFileObjectPacked() { @@ -103,7 +103,7 @@ MVector< MString > out; MercuryFileDriver::Init(); - FILEMAN.ListDirectory( PackagePrefix+"*.*", out, false ); + FILEMAN.ListDirectory( MString(PackagePrefix)+"*.*", out, false ); for ( unsigned i = 0; i < out.size(); i++ ) { Modified: Mercury2/src/MercuryFileDriverZipped.cpp =================================================================== --- Mercury2/src/MercuryFileDriverZipped.cpp 2010-12-17 21:57:04 UTC (rev 771) +++ Mercury2/src/MercuryFileDriverZipped.cpp 2010-12-18 00:10:19 UTC (rev 772) @@ -12,7 +12,7 @@ # endif #endif -const MString PackagePrefix = "Packages/"; +const char PackagePrefix[] = "Packages/"; /********************FILE DRIVER ZIPPED*******************/ @@ -172,7 +172,7 @@ MercuryFileDriver::Init(); - FILEMAN.ListDirectory( PackagePrefix+"*.zip", out, false ); + FILEMAN.ListDirectory( MString(PackagePrefix)+"*.zip", out, false ); for ( i = 0; i < out.size(); i++ ) out[i] = PackagePrefix + out[i]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |