Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

205 lines
6.5 KiB

//========== Copyright © 2010, Valve Corporation, All rights reserved. ========
// Global GCM-related state
//
#ifndef _PS3GCMSTATE_H_INC_
#define _PS3GCMSTATE_H_INC_
#include "ps3/ps3gcmmemory.h"
#include <cell/gcm.h>
#include "bitmap/imageformat.h"
#include "ps3/ps3_gcm_shared.h"
class CPs3gcmGlobalState
{
public:
void * m_pIoAddress; // RSX IO buffer, base address
uint32 m_nIoSize; // RSX IO total size [including CMD buffer]
uint32 m_nIoSizeNotPreallocated; // the io total size that wasn't pre-allocated in initialization
uint32 m_nCmdSize; // RSX CMD buffer total size [including first reserved 4K]
uint32 const volatile *m_pCurrentCmdBufferSegmentRSX; // Begin offset of current CMD buffer segment being processed by RSX
#if GCM_CTX_UNSAFE_MODE
uint32 *m_pCurrentCmdBufferUnflushedBeginRSX; // Marks beginning of not yet flushed RSX buffer
#endif
void * m_pLocalBaseAddress; // RSX Local Memory Base Address
uint32 m_nLocalBaseOffset; // cellGcmAddressToOffset( m_pLocalBaseAddress )
uint32 m_nLocalSize; // RSX Local Memory Size
uint16 m_nRenderSize[2]; // with & height of the render buffer
float m_flRenderAspect; // aspect ratio of the output device
uint32 m_nIoOffsetDelta; // add this to EA to get Io Offset
uint32 m_nSurfaceRenderPitch;
// this is used to allocate permanent cmd buffers; to be cleared when level reloads, hopefully won't need anything more complicated than that
// but if we do, we can make a page-chain-based (page from 128 bytes) allocator with reference count per page
// NOTE: the buffer MUST have 1KB padding in the end to prevent overfetch RSX crash!
CellGcmContextData m_cmdBufferPermContext;
// vertex and index data buffer
void * m_pRsxDataTransferBuffer;
uint32 m_nRsxDataTransferBufferSize;
// main memory pool buffer
void * m_pRsxMainMemoryPoolBuffer;
uint32 m_nRsxMainMemoryPoolBufferSize;
// special texture to support debug stripes
CPs3gcmLocalMemoryBlock m_debugStripeImageBuffer;
uint32 m_nCmdBufferRefCount; // how many buffers are referenced?
CPs3gcmDisplay m_display; // m_display objects that are created automatically
CPs3gcmLocalMemoryBlock m_pShaderPsEmptyBuffer;
CgBinaryProgram *m_pShaderPsEmpty; // empty pixel shader
uint32 m_nIoLocalOffsetEmptyFragmentProgramSetupRoutine;
uint32 m_nFlushCounter;
float m_flAllocatorStallTimeWaitingRSX; // how long allocator ended up waiting for RSX
public:
int32 Init();
void Shutdown();
void DrawDebugStripe( uint nScreenX, uint nScreenY, uint nStripeY, uint nStripeWidth, uint nStripeHeight, int nNext = 0 );
// pre-allocate memory before command buffer is allocated
void * IoMemoryPrealloc( uint nAlign, uint nSize );
void * IoSlackAlloc( uint nAlign, uint nSize );
void IoSlackFree( void * eaMemory );
bool IsIoMemory( void * eaMemory );
uintp CmdBufferToIoOffset( void *pCmdBuffer );
CellGcmContextData* CmdBufferAlloc( );
void CmdBufferFreeOffset( uint32 );
enum CmdBufferFlushType_t
{
kFlushForcefully,
kFlushEndFrame
};
void CmdBufferFlush( CmdBufferFlushType_t eFlushType );
void CmdBufferFinish();
void CmdBufferReservationCallback( struct CellGcmContextData *context );
uint32 GetRsxControlNextReferenceValue();
// Note:
// Height alignment must be 32 for tiled surfaces on RSX
// 128 for Edge Post MLAA
// 64 for Edge Post MLAA with EDGE_POST_MLAA_MODE_TRANSPOSE_64 flag set
uint GetRenderSurfaceBytes( uint nHeightAlignment = 32 ) const { return m_nSurfaceRenderPitch * AlignValue( m_nRenderSize[1], nHeightAlignment ); }
protected:
void CreateDebugStripeTextureBuffer();
void CreateEmptyPixelShader();
void CreateRsxBuffers();
void CreateIoBuffers();
int InitVideo();
int InitGcm();
};
inline uintp CPs3gcmGlobalState::CmdBufferToIoOffset( void * pCmdBuffer )
{
uintp nIoOffset = uintp( pCmdBuffer ) + m_nIoOffsetDelta;
Assert( ( uintp( pCmdBuffer ) >= uintp( m_cmdBufferPermContext.begin ) && uintp( pCmdBuffer ) < uintp( m_cmdBufferPermContext.end ) ) // can be a perm context buffer
|| ( nIoOffset >= 4096 && nIoOffset <= m_nCmdSize ) ); // or it can be the main cmd buffer (SYSring)
return nIoOffset;
}
inline CellGcmContextData* CPs3gcmGlobalState::CmdBufferAlloc( )
{
m_nCmdBufferRefCount++;
return &m_cmdBufferPermContext;
}
inline void CPs3gcmGlobalState::CmdBufferFreeOffset( uint32 )
{
if( !--m_nCmdBufferRefCount )
{
m_cmdBufferPermContext.current = m_cmdBufferPermContext.begin;
}
}
extern CPs3gcmGlobalState g_ps3gcmGlobalState;
//////////////////////////////////////////////////////////////////////////
//
// inline implementations of PPU-only stuff
//
inline char * CPs3gcmLocalMemoryBlock::DataInLocalMemory() const
{
Assert( IsLocalMemory() );
return
( m_nLocalMemoryOffset - g_ps3gcmGlobalState.m_nLocalBaseOffset ) +
( char * ) g_ps3gcmGlobalState.m_pLocalBaseAddress;
}
inline char * CPs3gcmLocalMemoryBlock::DataInMainMemory() const
{
Assert( !IsLocalMemory() && IsRsxMappedMemory() );
return
m_nLocalMemoryOffset +
( ( char * ) g_ps3gcmGlobalState.m_pIoAddress );
}
inline char * CPs3gcmLocalMemoryBlock::DataInMallocMemory() const
{
Assert( !IsLocalMemory() && !IsRsxMappedMemory() );
return ( char * ) m_nLocalMemoryOffset;
}
inline char * CPs3gcmLocalMemoryBlock::DataInAnyMemory() const
{
switch ( PS3GCMALLOCATIONPOOL( m_uType ) )
{
default: return DataInLocalMemory();
case kGcmAllocPoolMainMemory: return DataInMainMemory();
case kGcmAllocPoolMallocMemory: return DataInMallocMemory();
}
}
// Allow shaderapi to query GPU memory stats:
extern void GetGPUMemoryStats( GPUMemoryStats &stats );
class CmdSubBuffer: public CellGcmContextData
{
public:
static int32_t DoNothing( struct CellGcmContextData *pContext, uint32_t nWords )
{
Error( "CmdSubBuffer callback @%p: trying to allocate %u words\n", pContext, nWords );
return CELL_ERROR_ERROR_FLAG;
}
CmdSubBuffer( uint32 * pBuffer, uint nAllocateWords )
{
this->current = this->begin = pBuffer;
this->end = this->begin + nAllocateWords;
this->callback = DoNothing;
}
~CmdSubBuffer()
{
Assert( this->current == this->end );
}
};
extern uint32 CalculateMemorySizeFromCmdLineParam( char const *pCmdParamName, uint32 nDefaultValue, uint32 nMinValue = 0 );
inline bool CPs3gcmGlobalState::IsIoMemory( void * eaMemory )
{
return uintp( eaMemory ) >= uintp( m_pIoAddress ) && uintp( eaMemory ) <= uintp( m_pIoAddress ) + m_nIoSize;
}
#endif // _PS3GCMSTATE_H_INC_