123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514 |
- #ifndef __SOFTWARECACHE_H__
- #define __SOFTWARECACHE_H__
- #pragma warning( disable : 4324 ) // structure was padded due to __declspec(align())
- extern uint32 globalDmaTag;
- #define MAX_DMA_SIZE ( 1 << 14 )
- #define ODS_ROUND16( x ) ( ( x + 15 ) & ~15 )
- enum streamBufferType_t {
- SBT_DOUBLE = 2,
- SBT_QUAD = 4
- };
- /*
- ================================================================================================
- non-SPU code
- ================================================================================================
- */
- /*
- ================================================
- idSoftwareCache
- ================================================
- */
- template< typename _type_, int _entries_ = 8, int _associativity_ = 4, bool aligned = false >
- class ALIGNTYPE128 idSoftwareCache {
- public:
- void Prefetch( const _type_ * obj ) {
- ::Prefetch( obj, 0 );
- }
- };
- template< typename _type_ >
- class idODSObject {
- public:
- idODSObject( const _type_ * obj ) : objectPtr( obj ) {}
- operator const _type_ & () const { return *objectPtr; }
- const _type_ * operator->() const { return objectPtr; }
- const _type_ & Get() const { return *objectPtr; }
- const _type_ * Ptr() const { return objectPtr; }
- const _type_ * OriginalPtr() const { return objectPtr; }
- private:
- const _type_ * objectPtr;
- };
- template< typename _type_, typename _cache_ >
- class idODSCachedObject {
- public:
- idODSCachedObject( const _type_ * obj, _cache_ & cache ) : objectPtr( obj ) {}
- operator const _type_ & () const { return *objectPtr; }
- const _type_ * operator->() const { return objectPtr; }
- const _type_ & Get() const { return *objectPtr; }
- const _type_ * Ptr() const { return objectPtr; }
- const _type_ * OriginalPtr() const { return objectPtr; }
- private:
- const _type_ * objectPtr;
- };
- template< typename _type_, int max >
- class idODSArray {
- public:
- idODSArray( const _type_ * array, int num ) : arrayPtr( array ), arrayNum( num ) {
- assert( num <= max );
- Prefetch( array, 0 );
- }
- const _type_ & operator[]( int index ) const {
- assert( index >= 0 && index < arrayNum );
- return arrayPtr[index];
- }
- const _type_ * Ptr() const { return arrayPtr; }
- const int Num() const { return arrayNum; }
- private:
- const _type_ * arrayPtr;
- int arrayNum;
- };
- template< typename _elemType_, typename _indexType_, int max >
- class idODSIndexedArray {
- public:
- idODSIndexedArray( const _elemType_ * array, const _indexType_ * index, int num ) : arrayNum( num ) {
- assert( num <= max );
- for ( int i = 0; i < num; i++ ) {
- Prefetch( arrayPtr, abs( index[i] ) * sizeof( _elemType_ ) );
- arrayPtr[i] = array + abs( index[i] );
- }
- }
- const _elemType_ & operator[]( int index ) const {
- assert( index >= 0 && index < arrayNum );
- return * arrayPtr[index];
- }
- void ReplicateUpToMultipleOfFour() {
- assert( ( max & 3 ) == 0 );
- while( ( arrayNum & 3 ) != 0 ) {
- arrayPtr[arrayNum++] = arrayPtr[0];
- }
- }
- private:
- const _elemType_ * arrayPtr[max];
- int arrayNum;
- };
- template< typename _type_, int _bufferSize_ >
- class ALIGNTYPE16 idODSStreamedOutputArray {
- public:
- idODSStreamedOutputArray( _type_ * array, int * numElements, int maxElements ) :
- localNum( 0 ),
- outArray( array ),
- outNum( numElements ),
- outMax( maxElements ) {
- compile_time_assert( CONST_ISPOWEROFTWO( _bufferSize_ ) );
- compile_time_assert( ( ( _bufferSize_ * sizeof( _type_ ) ) & 15 ) == 0 );
- compile_time_assert( _bufferSize_ * sizeof( _type_ ) < MAX_DMA_SIZE );
- assert_16_byte_aligned( array );
- }
- ~idODSStreamedOutputArray() {
- *outNum = localNum;
- }
- int Num() const { return localNum; }
- void Append( _type_ element ) { assert( localNum < outMax ); outArray[localNum++] = element; }
- _type_ & Alloc() { assert( localNum < outMax ); return outArray[localNum++]; }
- private:
- int localNum;
- _type_ * outArray;
- int * outNum;
- int outMax;
- };
- template< typename _type_, int _bufferSize_, streamBufferType_t _sbt_ = SBT_DOUBLE, int _roundUpToMultiple_ = 1 >
- class ALIGNTYPE16 idODSStreamedArray {
- public:
- idODSStreamedArray( const _type_ * array, const int numElements ) :
- cachedArrayStart( 0 ),
- cachedArrayEnd( 0 ),
- streamArrayEnd( 0 ),
- inArray( array ),
- inArrayNum( numElements ),
- inArrayNumRoundedUp( numElements ) {
- compile_time_assert( CONST_ISPOWEROFTWO( _bufferSize_ ) );
- compile_time_assert( ( ( _bufferSize_ * sizeof( _type_ ) ) & 15 ) == 0 );
- compile_time_assert( _bufferSize_ * sizeof( _type_ ) < MAX_DMA_SIZE );
- compile_time_assert( _roundUpToMultiple_ >= 1 );
- assert_16_byte_aligned( array );
- assert( (uintptr_t)array > _bufferSize_ * sizeof( _type_ ) );
-
- FetchNextBatch();
-
-
- inArrayNumRoundedUp += _roundUpToMultiple_ - 1;
- inArrayNumRoundedUp -= inArrayNumRoundedUp % ( ( _roundUpToMultiple_ > 1 ) ? _roundUpToMultiple_ : 1 );
- }
- ~idODSStreamedArray() {
-
- FlushArray( inArray, cachedArrayStart * sizeof( _type_ ), cachedArrayEnd * sizeof( _type_ ) );
- }
-
-
-
-
-
-
-
- int FetchNextBatch() {
-
- if ( cachedArrayEnd < inArrayNum ) {
- cachedArrayEnd = streamArrayEnd;
- cachedArrayStart = Max( cachedArrayEnd - _bufferSize_ * ( _sbt_ - 1 ), 0 );
-
- FlushArray( inArray, ( cachedArrayStart - _bufferSize_ ) * sizeof( _type_ ), cachedArrayStart * sizeof( _type_ ) );
-
- if ( streamArrayEnd < inArrayNum ) {
- streamArrayEnd = Min( streamArrayEnd + _bufferSize_, inArrayNum );
- for ( unsigned int offset = cachedArrayEnd * sizeof( _type_ ); offset < streamArrayEnd * sizeof( _type_ ); offset += CACHE_LINE_SIZE ) {
- Prefetch( inArray, offset );
- }
- }
- }
- return ( cachedArrayEnd == inArrayNum ) ? inArrayNumRoundedUp : cachedArrayEnd;
- }
-
-
-
-
-
-
- const _type_ & operator[]( int index ) const {
- assert( ( index >= cachedArrayStart && index < cachedArrayEnd ) || ( cachedArrayEnd == inArrayNum && index >= inArrayNum && index < inArrayNumRoundedUp ) );
- if ( _roundUpToMultiple_ > 1 ) {
- index &= ( index - inArrayNum ) >> 31;
- }
- return inArray[index];
- }
- private:
- int cachedArrayStart;
- int cachedArrayEnd;
- int streamArrayEnd;
- const _type_ * inArray;
- int inArrayNum;
- int inArrayNumRoundedUp;
- static void FlushArray( const void * flushArray, int flushStart, int flushEnd ) {
- #if 0
-
-
-
-
- const uintptr_t arrayAddress = (uintptr_t)flushArray;
- const uintptr_t arrayFlushBase = ( arrayAddress + CACHE_LINE_SIZE - 1 ) & ~( CACHE_LINE_SIZE - 1 );
- const uintptr_t arrayFlushStart = ( arrayAddress + flushStart ) & ~( CACHE_LINE_SIZE - 1 );
- const uintptr_t arrayFlushEnd = ( arrayAddress + flushEnd ) & ~( CACHE_LINE_SIZE - 1 );
- for ( uintptr_t offset = Max( arrayFlushBase, arrayFlushStart ); offset < arrayFlushEnd; offset += CACHE_LINE_SIZE ) {
- FlushCacheLine( flushArray, offset - arrayAddress );
- }
- #endif
- }
- };
- template< typename _elemType_, typename _indexType_, int _bufferSize_, streamBufferType_t _sbt_ = SBT_DOUBLE, int _roundUpToMultiple_ = 1 >
- class ALIGNTYPE16 idODSStreamedIndexedArray {
- public:
- idODSStreamedIndexedArray( const _elemType_ * array, const int numElements, const _indexType_ * index, const int numIndices ) :
- cachedArrayStart( 0 ),
- cachedArrayEnd( 0 ),
- streamArrayEnd( 0 ),
- cachedIndexStart( 0 ),
- cachedIndexEnd( 0 ),
- streamIndexEnd( 0 ),
- inArray( array ),
- inArrayNum( numElements ),
- inIndex( index ),
- inIndexNum( numIndices ),
- inIndexNumRoundedUp( numIndices ) {
- compile_time_assert( CONST_ISPOWEROFTWO( _bufferSize_ ) );
- compile_time_assert( ( ( _bufferSize_ * sizeof( _indexType_ ) ) & 15 ) == 0 );
- compile_time_assert( _bufferSize_ * sizeof( _indexType_ ) < MAX_DMA_SIZE );
- compile_time_assert( _bufferSize_ * sizeof( _elemType_ ) < MAX_DMA_SIZE );
- compile_time_assert( ( sizeof( _elemType_ ) & 15 ) == 0 );
- compile_time_assert( _roundUpToMultiple_ >= 1 );
- assert_16_byte_aligned( index );
- assert_16_byte_aligned( array );
- assert( (uintptr_t)index > _bufferSize_ * sizeof( _indexType_ ) );
- assert( (uintptr_t)array > _bufferSize_ * sizeof( _elemType_ ) );
-
- FetchNextBatch();
-
- FetchNextBatch();
-
-
- inIndexNumRoundedUp += _roundUpToMultiple_ - 1;
- inIndexNumRoundedUp -= inIndexNumRoundedUp % ( ( _roundUpToMultiple_ > 1 ) ? _roundUpToMultiple_ : 1 );
- }
- ~idODSStreamedIndexedArray() {
-
- FlushArray( inIndex, cachedIndexStart * sizeof( _indexType_ ), cachedIndexEnd * sizeof( _indexType_ ) );
-
- FlushArray( inArray, cachedArrayStart * sizeof( _elemType_ ), cachedArrayEnd * sizeof( _elemType_ ) );
- }
-
-
-
-
-
-
-
- int FetchNextBatch() {
-
- if ( cachedArrayEnd < inIndexNum ) {
- if ( streamIndexEnd > 0 ) {
- cachedArrayEnd = streamArrayEnd;
- cachedArrayStart = Max( cachedArrayEnd - _bufferSize_ * ( _sbt_ - 1 ), 0 );
- cachedIndexEnd = streamIndexEnd;
- cachedIndexStart = Max( cachedIndexEnd - _bufferSize_ * ( _sbt_ - 1 ), 0 );
-
- FlushArray( inIndex, ( cachedIndexStart - _bufferSize_ ) * sizeof( _indexType_ ), cachedIndexStart * sizeof( _indexType_ ) );
-
- FlushArray( inArray, ( cachedArrayStart - _bufferSize_ ) * sizeof( _elemType_ ), cachedArrayStart * sizeof( _elemType_ ) );
-
- if ( streamArrayEnd < inIndexNum ) {
- streamArrayEnd = cachedIndexEnd;
- for ( int i = cachedArrayEnd; i < streamArrayEnd; i++ ) {
- assert( i >= cachedIndexStart && i < cachedIndexEnd );
- assert( inIndex[i] >= 0 && inIndex[i] < inArrayNum );
- Prefetch( inArray, inIndex[i] * sizeof( _elemType_ ) );
- }
- }
- }
-
- if ( streamIndexEnd < inIndexNum ) {
- streamIndexEnd = Min( streamIndexEnd + _bufferSize_, inIndexNum );
- for ( unsigned int offset = cachedIndexEnd * sizeof( _indexType_ ); offset < streamIndexEnd * sizeof( _indexType_ ); offset += CACHE_LINE_SIZE ) {
- Prefetch( inIndex, offset );
- }
- }
- }
- return ( cachedArrayEnd == inIndexNum ) ? inIndexNumRoundedUp : cachedArrayEnd;
- }
-
-
-
-
-
-
- const _elemType_ & operator[]( int index ) const {
- assert( ( index >= cachedArrayStart && index < cachedArrayEnd ) || ( cachedArrayEnd == inIndexNum && index >= inIndexNum && index < inIndexNumRoundedUp ) );
- if ( _roundUpToMultiple_ > 1 ) {
- index &= ( index - inIndexNum ) >> 31;
- }
- return inArray[inIndex[index]];
- }
- private:
- int cachedArrayStart;
- int cachedArrayEnd;
- int streamArrayEnd;
- int cachedIndexStart;
- int cachedIndexEnd;
- int streamIndexEnd;
- const _elemType_ * inArray;
- int inArrayNum;
- const _indexType_ * inIndex;
- int inIndexNum;
- int inIndexNumRoundedUp;
- static void FlushArray( const void * flushArray, int flushStart, int flushEnd ) {
- #if 0
-
-
-
-
- const uintptr_t arrayAddress = (uintptr_t)flushArray;
- const uintptr_t arrayFlushBase = ( arrayAddress + CACHE_LINE_SIZE - 1 ) & ~( CACHE_LINE_SIZE - 1 );
- const uintptr_t arrayFlushStart = ( arrayAddress + flushStart ) & ~( CACHE_LINE_SIZE - 1 );
- const uintptr_t arrayFlushEnd = ( arrayAddress + flushEnd ) & ~( CACHE_LINE_SIZE - 1 );
- for ( uintptr_t offset = Max( arrayFlushBase, arrayFlushStart ); offset < arrayFlushEnd; offset += CACHE_LINE_SIZE ) {
- FlushCacheLine( flushArray, offset - arrayAddress );
- }
- #endif
- }
- };
- #endif // !__SOFTWARECACHE_H__
|