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.

100 lines
3.2 KiB

  1. //========== Copyright � Valve Corporation, All rights reserved. ========
  2. //
  3. // This job chain wrapper is an infinite job chain with dynamic job submission
  4. // It is single-threaded and not very fast in the current implementation,
  5. // so it'll need to be optimized if we ever become SPU bound and use it often.
  6. // To make it multithreaded, the easiest way is to lock every operation
  7. // with a compare-exchange flag and a spin-wait, and use getllar to update "this" and the flag atomically
  8. //
  9. #if !defined( VJOBSCHAINU4_HDR ) && defined( _PS3 )
  10. #define VJOBSCHAINU4_HDR
  11. #include <cell/spurs.h>
  12. #include "ps3/job_notify.h"
  13. #include "ps3/spu_job_shared.h"
  14. struct VJobsRoot;
  15. struct ALIGN128 VjobChain4BufferHeader_t
  16. {
  17. public:
  18. CellSpursJob64 m_jobNotify;
  19. job_notify::NotifyArea_t m_notifyArea;
  20. }
  21. ALIGN128_POST;
  22. struct VjobChain4Buffer_t: public VjobChain4BufferHeader_t
  23. {
  24. public:
  25. enum ConstEnum_t
  26. {
  27. VERBATIM_COMMAND_COUNT = 2 // we employ syncronization scheme: SYNC, JOB(notify), ...
  28. };
  29. uint64 m_spursCommands[32]; // there will be at least verbatim commands, a user command, and a NEXT
  30. void Init( VJobsRoot * pRoot, cell::Spurs::JobChain * pSpursJobChain, uint nMaxCommandsPerBuffer );
  31. };
  32. // VjobChain4 has only 1 jobchain but double-buffers it to facilitate continuous wait-free execution
  33. class ALIGN16 VjobChain4
  34. {
  35. protected:
  36. enum ConstEnum_t {
  37. BUFFER_COUNT = 4
  38. };
  39. VjobChain4 * m_eaThis;
  40. cell::Spurs::JobChain *m_pSpursJobChain;
  41. VjobChain4Buffer_t * m_pBuffers[BUFFER_COUNT];
  42. VjobChain4Buffer_t * m_pFrontBuffer;
  43. uint m_nFrontBuffer; // the buffer currently in use
  44. uint m_nMaxCommandsPerBuffer; // max count of commands fitting into one buffer
  45. uint m_nFrontBufferCommandCount; // count of commands in the current front buffer
  46. uint m_nSpinWaitNotify; // did we spin waiting for job_notify ? if we did, we probably need to increase the command buffer size
  47. const char * m_pName;
  48. public:
  49. #ifndef SPU
  50. int Init( VJobsRoot * pRoot, uint nMaxContention, uint nMinCommandsPerBuffer, uint8_t nVjobChainPriority[8], uint nSizeOfJobDescriptor, uint nMaxGrabbedJob, const char* pName, uint nDmaTags );
  51. void Shutdown(){End();Join();}
  52. void End();
  53. void Join();
  54. void Run(){ m_pSpursJobChain->run();}
  55. #endif
  56. uint64* Push( );
  57. const char * GetName()const {return m_pName;}
  58. protected:
  59. void WaitForEntryNotify( VjobChain4Buffer_t * eaBuffer );
  60. uint64* StartCommandBuffer( uint nNext1Buffer );
  61. uint64* SwapCommandBuffer( );
  62. }
  63. ALIGN128_POST;
  64. inline uint64* VjobChain4::Push( )
  65. {
  66. uint64 * pInsertionPoint;
  67. Assert( m_nFrontBufferCommandCount < m_nMaxCommandsPerBuffer );
  68. if( m_nFrontBufferCommandCount == m_nMaxCommandsPerBuffer - 1 )
  69. {
  70. // time to switch the buffer
  71. pInsertionPoint = SwapCommandBuffer( );
  72. }
  73. else
  74. {
  75. Assert( VjobDmaGetUint64( (uint)&m_pFrontBuffer->m_spursCommands[ m_nFrontBufferCommandCount + 1 ], DMATAG_SYNC, 0, 0 ) == CELL_SPURS_JOB_COMMAND_JTS );
  76. LWSYNC_PPU_ONLY(); // Important: this sync ensures that both the command header AND JTS are written before SPU sees them
  77. pInsertionPoint = &m_pFrontBuffer->m_spursCommands[ m_nFrontBufferCommandCount ];
  78. m_nFrontBufferCommandCount ++;
  79. }
  80. return pInsertionPoint;
  81. }
  82. extern vec_uint4 g_cellSpursJts16;
  83. extern void FillSpursJts( uint64 * eaCommands, uint nBufferCount );
  84. #endif