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.

257 lines
8.8 KiB

  1. //========== Copyright � Valve Corporation, All rights reserved. ========
  2. // This is the central hub for controlling SPU activities relating to
  3. // RSX/graphics processing/rendering
  4. //
  5. #ifndef SPU_GCM_HDR
  6. #define SPU_GCM_HDR
  7. #include "ps3/spugcm_shared.h"
  8. //#include "ps3/rsx_spu_double_ring.h"
  9. #include "vjobs_interface.h"
  10. #include "ps3/vjobchain.h"
  11. #include "ps3/vjobpool.h"
  12. #include "ps3/ps3gcmmemory.h"
  13. #include "spudrawqueue.h"
  14. #include "gcmfunc.h"
  15. #include <edge/post/edgePost_ppu.h>
  16. #include <edge/post/edgepost_mlaa_handler_ppu.h>
  17. extern CSpuGcmSharedState g_spuGcmShared;
  18. extern void StallAndWarning( const char * pWarning );
  19. class ZPass
  20. {
  21. public:
  22. void Init();
  23. bool CanBegin();
  24. void Begin( uint32 * pCursor );
  25. void End() { m_pCursor = NULL; }
  26. void Shutdown();
  27. void Validate()const{Assert( !m_nDummy && ( m_nPut - m_nGet ) <= m_nJobs );}
  28. uint GetSubchainCapacity()const { Validate(); return m_nJobs - ( m_nPut - m_nGet ) ; }
  29. uint64 * GetCurrentCommandPtr() { return &m_pJobs[ m_nPut & ( m_nJobs - 1 ) ]; }
  30. void PushCommand( uint64 nCommand );
  31. operator bool () const { return m_pCursor != NULL; }
  32. public:
  33. uint m_nDrawPassSubchain;
  34. uint m_nJobPoolMarker;
  35. uint m_nJobs;
  36. uint m_nDummy;
  37. uint m_nPut;
  38. uint m_isInEndZPass;
  39. ZPassSavedState_t * m_pSavedState;
  40. uint32 * m_pCursor;
  41. uint64 * m_pSubchain;
  42. uint64 * m_pJobs; // this ring buffer contains recorded rendering jobs to be replayed
  43. uint m_nFpcpStateEndOfJournalIdxAtZPassBegin; // ... at the beginning of Zpass
  44. // Notice: this m_pGet member is patched by SPU after a corresponding job subchain is finished
  45. volatile uint32 m_nGet;
  46. protected:
  47. };
  48. class ALIGN128 CEdgePostWorkload
  49. {
  50. public:
  51. CEdgePostWorkload(){m_isInitialized = false;}
  52. void OnVjobsInit( VJobsRoot* pRoot );
  53. void OnVjobsShutdown( VJobsRoot* pRoot );
  54. void Kick( void * dst, uint nSetLabel );
  55. bool ShouldUseLabelForSynchronization()const{return true;}
  56. bool IsResultInMainMemory()const { return true; }
  57. enum EnumConst_t{STAGE_COUNT=1};
  58. EdgePostProcessStage m_stages[STAGE_COUNT];
  59. EdgePostMlaaContext m_mlaaContext;
  60. EdgePostWorkload m_workload;
  61. void * m_pMlaaScratch;
  62. bool m_isInitialized;
  63. } ALIGN128_POST;
  64. extern CEdgePostWorkload g_edgePostWorkload;
  65. class CSpuGcm: public VJobInstance
  66. {
  67. public:
  68. void CreateRsxBuffers();
  69. void CreateIoBuffers();
  70. void UseIoBufferSlack( uint nIoBufferSlack );
  71. void OnGcmInit();
  72. void Shutdown();
  73. void BeginScene();
  74. void EndScene();
  75. void CmdBufferFlush( )
  76. {
  77. GcmStateFlush();
  78. //PutPcbringCtx();
  79. }
  80. void CmdBufferFinish();
  81. int OnGcmCommandBufferReserveCallback( struct CellGcmContextData *context, uint32_t nCount );
  82. int OnGcmCommandBufferReserveCallbackOld( struct CellGcmContextData *context, uint32_t nCount );
  83. void GcmStateFlush( );
  84. SpuDrawHeader_t * BeginDrawBatch();
  85. void SubmitDrawBatch( IDirect3DVertexDeclaration9 *pVertDecl, OptimizedModel::OptimizedIndexBufferMarkupPs3_t *pIbMarkup );
  86. bool TruePause();
  87. void RenderEmptyFrame();
  88. void SyncMlaa( void * pLocalSurface );
  89. void SyncMlaa( ) { SyncMlaa( m_pMlaaBuffer ); }
  90. bool BeginZPass( );
  91. void SetPredication( uint nPredicationMask ); // D3DPRED_* mask
  92. void EndZPass( bool bPopMarker );
  93. void AbortZPass(){ EndZPass( false ); }
  94. void OnSetPixelShaderConstant();
  95. SpuDrawQueue * GetDrawQueue(){ return &m_spuDrawQueues[m_nSpuDrawQueueSelector];}
  96. SpuDrawQueue * GetDrawQueueNormal(){ return &m_spuDrawQueues[0]; }
  97. void DrawQueueNormal( bool bExecuteDeferredQueueSegment = true );
  98. struct DrawQueueDeferred_Result{ bool isFirstInFrame; };
  99. DrawQueueDeferred_Result DrawQueueDeferred(); // may flush previous frame deferred queue
  100. uint IsDeferredDrawQueue() { return m_nSpuDrawQueueSelector; }
  101. bool ExecuteDeferredDrawQueue( uint nPrevious );
  102. void FlipDeferredDrawQueue();
  103. bool ExecuteDeferredDrawQueueSegment( uint32 * pCmdBegin, uint32 * pCmdEnd, bool bExecuteDraws );
  104. void ValidateDeferredQueue();
  105. //void DisableMlaaForTwoFrames();
  106. void DisableMlaaPermanently();
  107. void DisableMlaa();
  108. protected:
  109. static void OnSpuDrawQueueStallDeferredDelegator( SpuDrawQueue *pDrawQueue, uint32 * pGet, uint nWords );
  110. void OnSpuDrawQueueStallDeferred( SpuDrawQueue *pDrawQueue, uint32 * pGet, uint nWords );
  111. static void OnSpuDrawQueueFlushDeferred( SpuDrawQueue *pDrawQueue );
  112. static void OnSpuDrawQueueStall( SpuDrawQueue *pDrawQueue, uint32 * pGet, uint nWords );
  113. static void OnSpuDrawQueueFlush( SpuDrawQueue *pDrawQueue );
  114. static void OnSpuDrawQueueFlushDoNothing( SpuDrawQueue *pDrawQueue ){}
  115. static void OnSpuDrawQueueFlushInZPass( SpuDrawQueue *pDrawQueue );
  116. void OnSpuDrawQueueFlushInZPass( );
  117. void OnVjobsInit(); // gets called after m_pRoot was created and assigned
  118. void TestPriorities();
  119. void OnVjobsShutdown(); // gets called before m_pRoot is about to be destructed and NULL'ed
  120. uint32 * GetPcbringPtr( uint nOffsetBytes ) { return AddBytes( m_pPcbringBuffer, nOffsetBytes & ( g_spuGcmShared.m_nPcbringSize - 1 ) ); }
  121. uint32 * GetPcbringBufferEnd() {return AddBytes( m_pPcbringBuffer, g_spuGcmShared.m_nPcbringSize ); }
  122. signed int GetPcbringAvailableBytes()const;
  123. //void SetCtxBuffer( uint nSegment );
  124. #if 0
  125. volatile uint64* PutPcbringCtx( uint32 * pSkipTo, uint32 * pNewEnd );
  126. volatile uint64* PutPcbringCtx();
  127. #endif
  128. inline uint GetMaxPcbringSegmentBytes()const { return m_nMaxPcbringSegmentBytes; }
  129. void BeginGcmStateTransaction();
  130. void PushSpuGcmJob( CellSpursJob128 * pJob );
  131. void PushStateFlushJob( SpuDrawQueue * pDrawQueue, uint nResultantSpuDrawQueueSignal, uint32 *pCursorBegin, uint32 * pCursorEnd );
  132. void PushSpuGcmJobCommand( uint64 nCommand );
  133. void PushSpuGcmCallSubchain( uint64 * eaJobChain ){ m_jobSink.Push( CELL_SPURS_JOB_COMMAND_CALL( eaJobChain ) );}
  134. void ZPassCheckpoint( uint nReserveSlots );
  135. CellSpursJob128 * PushDrawBatchJob( uint nResultantSpuDrawQueueSignal, SpuDrawHeader_t * pDrawHeader, IDirect3DVertexDeclaration9 *pVertDecl, OptimizedModel::OptimizedIndexBufferMarkupPs3_t *pIbMarkup );
  136. public:
  137. void CloseDeferredChunk();
  138. uint32* OpenDeferredChunk( uint nHeader = SPUDRAWQUEUE_DEFERRED_GCMFLUSH_METHOD, uint nAllocExtra = 0 );
  139. void SetCurrentBatchCursor( uint32 * pCursor )
  140. {
  141. m_pCurrentBatchCursor[m_nSpuDrawQueueSelector] = pCursor;
  142. }
  143. uint32 * GetCurrentBatchCursor()
  144. {
  145. return m_pCurrentBatchCursor[m_nSpuDrawQueueSelector];
  146. }
  147. protected:
  148. SpuDrawQueue m_spuDrawQueues[2];
  149. // this frame [0] and previous frames [1] "end" markers for replay
  150. // gets updated on every chunk close
  151. uint32* m_pDeferredQueueCursors[3];
  152. // this is the last point where DrawQueueDeferred() was called
  153. uint32 * m_pDeferredQueueSegment;
  154. // pointer to deferred chunk last open; NULL if the last deferred chunk was closed, but none new was open yet
  155. // this may stay non-NULL( thus indicating non-closed chunk) during executing deferred commands, too,
  156. // in case of out-of-memory condition. Then, StallDeferred callback will execute deferred commands without closing current chunk.
  157. // Relation: MANY chunks per ONE batch
  158. uint32* m_pDeferredChunkHead;
  159. uint32 m_nDeferredChunkHead;
  160. uint32 *m_pDeferredChunkSubmittedTill[4]; // only [1] is used; [0] and [2] are write- and debug-only
  161. uint16 m_nSpuDrawQueueSelector;
  162. uint16 m_nFramesToDisableDeferredQueue; // disable for this number of frames if we don't have enough memory
  163. public:
  164. // fragment program constant patcher double ring, JTS->RET , RSX->SPU
  165. CPs3gcmLocalMemoryBlock m_fpcpRingBuffer, m_edgeGeomRingBuffer;
  166. VjobChain3 m_jobSink;
  167. VjobPool<CellSpursJob128> m_jobPool128;
  168. volatile uint32 * m_pFinishLabel;
  169. uint32 *m_pPcbringBuffer;
  170. ZPass m_zPass; // NULL when we aren't in Zpass
  171. DeferredState_t * m_pDeferredStates[2];
  172. uint m_nPcbringBegin; // this byte offset corresponds to GCM_CTX->begin
  173. uint32 m_nPcbringWaitSpins;
  174. uint32 m_nMaxPcbringSegmentBytes;
  175. uint32 m_nGcmFlushJobScratchSize;
  176. uintp m_eaLastJobThatUpdatesSharedState;
  177. uint m_nFpcpStateEndOfJournalIdxAtSpuGcmJob;
  178. enum TransactionBatchEnum_t
  179. {
  180. BATCH_GCMSTATE, // the default transaction type
  181. BATCH_DRAW
  182. };
  183. TransactionBatchEnum_t m_nCurrentBatch;
  184. // the batch is a batch of commands to send to an SPU job: job_gcmflush (BATCH_GCMSTATE) or job_drawindexedprimitive (BATCH_DRAW)
  185. uint32 * m_pCurrentBatchCursor[2];
  186. void * m_pMlaaBuffer, *m_pMlaaBufferOut;
  187. volatile vec_uint4 * m_pMlaaBufferCookie;
  188. uint32 *m_pEdgePostRsxLock;
  189. uint m_nFrame;
  190. #ifdef _DEBUG
  191. uint m_nJobsPushed, m_nChunksClosedInSegment;
  192. #endif
  193. uint64 m_nDeferredQueueWords;
  194. bool m_bUseDeferredDrawQueue;
  195. };
  196. extern CSpuGcm g_spuGcm;
  197. extern const vec_uint4 g_vuSpuGcmCookie;
  198. struct ALIGN128 PriorityTest_t
  199. {
  200. CellSpursJob128 m_job;
  201. job_notify::NotifyArea_t m_notify;
  202. bool Test( class VjobChain4 *pJobChain );
  203. } ALIGN128_POST;
  204. #endif