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

  1. //========== Copyright � 2010, Valve Corporation, All rights reserved. ========
  2. // Global GCM-related state
  3. //
  4. #ifndef _PS3GCMSTATE_H_INC_
  5. #define _PS3GCMSTATE_H_INC_
  6. #include "ps3/ps3gcmmemory.h"
  7. #include <cell/gcm.h>
  8. #include "bitmap/imageformat.h"
  9. #include "ps3/ps3_gcm_shared.h"
  10. class CPs3gcmGlobalState
  11. {
  12. public:
  13. void * m_pIoAddress; // RSX IO buffer, base address
  14. uint32 m_nIoSize; // RSX IO total size [including CMD buffer]
  15. uint32 m_nIoSizeNotPreallocated; // the io total size that wasn't pre-allocated in initialization
  16. uint32 m_nCmdSize; // RSX CMD buffer total size [including first reserved 4K]
  17. uint32 const volatile *m_pCurrentCmdBufferSegmentRSX; // Begin offset of current CMD buffer segment being processed by RSX
  18. #if GCM_CTX_UNSAFE_MODE
  19. uint32 *m_pCurrentCmdBufferUnflushedBeginRSX; // Marks beginning of not yet flushed RSX buffer
  20. #endif
  21. void * m_pLocalBaseAddress; // RSX Local Memory Base Address
  22. uint32 m_nLocalBaseOffset; // cellGcmAddressToOffset( m_pLocalBaseAddress )
  23. uint32 m_nLocalSize; // RSX Local Memory Size
  24. uint16 m_nRenderSize[2]; // with & height of the render buffer
  25. float m_flRenderAspect; // aspect ratio of the output device
  26. uint32 m_nIoOffsetDelta; // add this to EA to get Io Offset
  27. uint32 m_nSurfaceRenderPitch;
  28. // this is used to allocate permanent cmd buffers; to be cleared when level reloads, hopefully won't need anything more complicated than that
  29. // but if we do, we can make a page-chain-based (page from 128 bytes) allocator with reference count per page
  30. // NOTE: the buffer MUST have 1KB padding in the end to prevent overfetch RSX crash!
  31. CellGcmContextData m_cmdBufferPermContext;
  32. // vertex and index data buffer
  33. void * m_pRsxDataTransferBuffer;
  34. uint32 m_nRsxDataTransferBufferSize;
  35. // main memory pool buffer
  36. void * m_pRsxMainMemoryPoolBuffer;
  37. uint32 m_nRsxMainMemoryPoolBufferSize;
  38. // special texture to support debug stripes
  39. CPs3gcmLocalMemoryBlock m_debugStripeImageBuffer;
  40. uint32 m_nCmdBufferRefCount; // how many buffers are referenced?
  41. CPs3gcmDisplay m_display; // m_display objects that are created automatically
  42. CPs3gcmLocalMemoryBlock m_pShaderPsEmptyBuffer;
  43. CgBinaryProgram *m_pShaderPsEmpty; // empty pixel shader
  44. uint32 m_nIoLocalOffsetEmptyFragmentProgramSetupRoutine;
  45. uint32 m_nFlushCounter;
  46. float m_flAllocatorStallTimeWaitingRSX; // how long allocator ended up waiting for RSX
  47. public:
  48. int32 Init();
  49. void Shutdown();
  50. void DrawDebugStripe( uint nScreenX, uint nScreenY, uint nStripeY, uint nStripeWidth, uint nStripeHeight, int nNext = 0 );
  51. // pre-allocate memory before command buffer is allocated
  52. void * IoMemoryPrealloc( uint nAlign, uint nSize );
  53. void * IoSlackAlloc( uint nAlign, uint nSize );
  54. void IoSlackFree( void * eaMemory );
  55. bool IsIoMemory( void * eaMemory );
  56. uintp CmdBufferToIoOffset( void *pCmdBuffer );
  57. CellGcmContextData* CmdBufferAlloc( );
  58. void CmdBufferFreeOffset( uint32 );
  59. enum CmdBufferFlushType_t
  60. {
  61. kFlushForcefully,
  62. kFlushEndFrame
  63. };
  64. void CmdBufferFlush( CmdBufferFlushType_t eFlushType );
  65. void CmdBufferFinish();
  66. void CmdBufferReservationCallback( struct CellGcmContextData *context );
  67. uint32 GetRsxControlNextReferenceValue();
  68. // Note:
  69. // Height alignment must be 32 for tiled surfaces on RSX
  70. // 128 for Edge Post MLAA
  71. // 64 for Edge Post MLAA with EDGE_POST_MLAA_MODE_TRANSPOSE_64 flag set
  72. uint GetRenderSurfaceBytes( uint nHeightAlignment = 32 ) const { return m_nSurfaceRenderPitch * AlignValue( m_nRenderSize[1], nHeightAlignment ); }
  73. protected:
  74. void CreateDebugStripeTextureBuffer();
  75. void CreateEmptyPixelShader();
  76. void CreateRsxBuffers();
  77. void CreateIoBuffers();
  78. int InitVideo();
  79. int InitGcm();
  80. };
  81. inline uintp CPs3gcmGlobalState::CmdBufferToIoOffset( void * pCmdBuffer )
  82. {
  83. uintp nIoOffset = uintp( pCmdBuffer ) + m_nIoOffsetDelta;
  84. Assert( ( uintp( pCmdBuffer ) >= uintp( m_cmdBufferPermContext.begin ) && uintp( pCmdBuffer ) < uintp( m_cmdBufferPermContext.end ) ) // can be a perm context buffer
  85. || ( nIoOffset >= 4096 && nIoOffset <= m_nCmdSize ) ); // or it can be the main cmd buffer (SYSring)
  86. return nIoOffset;
  87. }
  88. inline CellGcmContextData* CPs3gcmGlobalState::CmdBufferAlloc( )
  89. {
  90. m_nCmdBufferRefCount++;
  91. return &m_cmdBufferPermContext;
  92. }
  93. inline void CPs3gcmGlobalState::CmdBufferFreeOffset( uint32 )
  94. {
  95. if( !--m_nCmdBufferRefCount )
  96. {
  97. m_cmdBufferPermContext.current = m_cmdBufferPermContext.begin;
  98. }
  99. }
  100. extern CPs3gcmGlobalState g_ps3gcmGlobalState;
  101. //////////////////////////////////////////////////////////////////////////
  102. //
  103. // inline implementations of PPU-only stuff
  104. //
  105. inline char * CPs3gcmLocalMemoryBlock::DataInLocalMemory() const
  106. {
  107. Assert( IsLocalMemory() );
  108. return
  109. ( m_nLocalMemoryOffset - g_ps3gcmGlobalState.m_nLocalBaseOffset ) +
  110. ( char * ) g_ps3gcmGlobalState.m_pLocalBaseAddress;
  111. }
  112. inline char * CPs3gcmLocalMemoryBlock::DataInMainMemory() const
  113. {
  114. Assert( !IsLocalMemory() && IsRsxMappedMemory() );
  115. return
  116. m_nLocalMemoryOffset +
  117. ( ( char * ) g_ps3gcmGlobalState.m_pIoAddress );
  118. }
  119. inline char * CPs3gcmLocalMemoryBlock::DataInMallocMemory() const
  120. {
  121. Assert( !IsLocalMemory() && !IsRsxMappedMemory() );
  122. return ( char * ) m_nLocalMemoryOffset;
  123. }
  124. inline char * CPs3gcmLocalMemoryBlock::DataInAnyMemory() const
  125. {
  126. switch ( PS3GCMALLOCATIONPOOL( m_uType ) )
  127. {
  128. default: return DataInLocalMemory();
  129. case kGcmAllocPoolMainMemory: return DataInMainMemory();
  130. case kGcmAllocPoolMallocMemory: return DataInMallocMemory();
  131. }
  132. }
  133. // Allow shaderapi to query GPU memory stats:
  134. extern void GetGPUMemoryStats( GPUMemoryStats &stats );
  135. class CmdSubBuffer: public CellGcmContextData
  136. {
  137. public:
  138. static int32_t DoNothing( struct CellGcmContextData *pContext, uint32_t nWords )
  139. {
  140. Error( "CmdSubBuffer callback @%p: trying to allocate %u words\n", pContext, nWords );
  141. return CELL_ERROR_ERROR_FLAG;
  142. }
  143. CmdSubBuffer( uint32 * pBuffer, uint nAllocateWords )
  144. {
  145. this->current = this->begin = pBuffer;
  146. this->end = this->begin + nAllocateWords;
  147. this->callback = DoNothing;
  148. }
  149. ~CmdSubBuffer()
  150. {
  151. Assert( this->current == this->end );
  152. }
  153. };
  154. extern uint32 CalculateMemorySizeFromCmdLineParam( char const *pCmdParamName, uint32 nDefaultValue, uint32 nMinValue = 0 );
  155. inline bool CPs3gcmGlobalState::IsIoMemory( void * eaMemory )
  156. {
  157. return uintp( eaMemory ) >= uintp( m_pIoAddress ) && uintp( eaMemory ) <= uintp( m_pIoAddress ) + m_nIoSize;
  158. }
  159. #endif // _PS3GCMSTATE_H_INC_