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.

240 lines
6.3 KiB

  1. //============ Copyright (c) Valve Corporation, All rights reserved. ============
  2. //
  3. // cglmprogram.h
  4. // GLMgr buffers (index / vertex)
  5. // ... maybe add PBO later as well
  6. //===============================================================================
  7. #ifndef CGLMBUFFER_H
  8. #define CGLMBUFFER_H
  9. #pragma once
  10. //===============================================================================
  11. extern bool g_bUsePseudoBufs;
  12. // forward declarations
  13. class GLMContext;
  14. enum EGLMBufferType
  15. {
  16. kGLMVertexBuffer,
  17. kGLMIndexBuffer,
  18. kGLMUniformBuffer, // for bindable uniform
  19. kGLMPixelBuffer, // for PBO
  20. kGLMNumBufferTypes
  21. };
  22. // pass this in "options" to constructor to make a dynamic buffer
  23. #define GLMBufferOptionDynamic 0x00000001
  24. struct GLMBuffLockParams
  25. {
  26. uint m_nOffset;
  27. uint m_nSize;
  28. bool m_bNoOverwrite;
  29. bool m_bDiscard;
  30. };
  31. #define GL_STATIC_BUFFER_SIZE ( 2048 * 1024 )
  32. #define GL_MAX_STATIC_BUFFERS 2
  33. extern void glBufferSubDataMaxSize( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data, uint nMaxSizePerCall = 128 * 1024 );
  34. //===========================================================================//
  35. // Creates an immutable storage for a buffer object
  36. // https://www.opengl.org/registry/specs/ARB/buffer_storage.txt
  37. class CPersistentBuffer
  38. {
  39. public:
  40. CPersistentBuffer();
  41. ~CPersistentBuffer();
  42. void Init( EGLMBufferType type,uint nSize );
  43. void Deinit();
  44. void InsertFence();
  45. void BlockUntilNotBusy();
  46. void Append( uint nSize );
  47. inline uint GetBytesRemaining() const { return m_nSize - m_nOffset; }
  48. inline uint GetOffset() const { return m_nOffset; }
  49. inline void *GetPtr() const { return m_pImmutablePersistentBuf; }
  50. inline GLuint GetHandle() const { return m_nHandle; }
  51. private:
  52. CPersistentBuffer( const CPersistentBuffer & );
  53. CPersistentBuffer & operator= (const CPersistentBuffer &);
  54. uint m_nSize;
  55. EGLMBufferType m_type;
  56. GLenum m_buffGLTarget; // GL_ARRAY_BUFFER_ARB / GL_ELEMENT_BUFFER_ARB
  57. GLuint m_nHandle; // handle of this program in the GL context
  58. // Holds a pointer to the persistently mapped buffer
  59. void* m_pImmutablePersistentBuf;
  60. uint m_nOffset;
  61. #ifdef HAVE_GL_ARB_SYNC
  62. GLsync m_nSyncObj;
  63. #endif
  64. };
  65. //===============================================================================
  66. #if GL_ENABLE_INDEX_VERIFICATION
  67. struct GLDynamicBuf_t
  68. {
  69. GLenum m_nGLType;
  70. uint m_nHandle;
  71. uint m_nActualBufSize;
  72. uint m_nSize;
  73. uint m_nLockOffset;
  74. uint m_nLockSize;
  75. };
  76. class CGLMBufferSpanManager
  77. {
  78. CGLMBufferSpanManager( const CGLMBufferSpanManager& );
  79. CGLMBufferSpanManager& operator= ( const CGLMBufferSpanManager& );
  80. public:
  81. CGLMBufferSpanManager();
  82. ~CGLMBufferSpanManager();
  83. void Init( GLMContext *pContext, EGLMBufferType nBufType, uint nInitialCapacity, uint nBufSize, bool bDynamic );
  84. void Deinit();
  85. inline GLMContext *GetContext() const { return m_pCtx; }
  86. inline GLenum GetGLBufType() const { return ( m_nBufType == kGLMVertexBuffer ) ? GL_ARRAY_BUFFER_ARB : GL_ELEMENT_ARRAY_BUFFER_ARB; }
  87. struct ActiveSpan_t
  88. {
  89. uint m_nStart;
  90. uint m_nEnd;
  91. GLDynamicBuf_t m_buf;
  92. bool m_bOriginalAlloc;
  93. inline ActiveSpan_t() { }
  94. inline ActiveSpan_t( uint nStart, uint nEnd, GLDynamicBuf_t &buf, bool bOriginalAlloc ) : m_nStart( nStart ), m_nEnd( nEnd ), m_buf( buf ), m_bOriginalAlloc( bOriginalAlloc ) { Assert( nStart <= nEnd ); }
  95. };
  96. ActiveSpan_t *AddSpan( uint nOffset, uint nMaxSize, uint nActualSize, bool bDiscard, bool bNoOverwrite );
  97. void DiscardAllSpans();
  98. bool IsValid( uint nOffset, uint nSize ) const;
  99. private:
  100. bool AllocDynamicBuf( uint nSize, GLDynamicBuf_t &buf );
  101. void ReleaseDynamicBuf( GLDynamicBuf_t &buf );
  102. GLMContext *m_pCtx;
  103. EGLMBufferType m_nBufType;
  104. uint m_nBufSize;
  105. bool m_bDynamic;
  106. CUtlVector<ActiveSpan_t> m_ActiveSpans;
  107. CUtlVector<ActiveSpan_t> m_DeletedSpans;
  108. int m_nSpanEndMax;
  109. int m_nNumAllocatedBufs;
  110. int m_nTotalBytesAllocated;
  111. };
  112. #endif // GL_ENABLE_INDEX_VERIFICATION
  113. class CGLMBuffer
  114. {
  115. public:
  116. void Lock( GLMBuffLockParams *pParams, char **pAddressOut );
  117. void Unlock( int nActualSize = -1, const void *pActualData = NULL );
  118. GLuint GetHandle() const;
  119. friend class GLMContext; // only GLMContext can make CGLMBuffer objects
  120. friend class GLMTester;
  121. friend struct IDirect3D9;
  122. friend struct IDirect3DDevice9;
  123. CGLMBuffer( GLMContext *pCtx, EGLMBufferType type, uint size, uint options );
  124. ~CGLMBuffer();
  125. void SetModes( bool bAsyncMap, bool bExplicitFlush, bool bForce = false );
  126. void FlushRange( uint offset, uint size );
  127. #if GL_ENABLE_INDEX_VERIFICATION
  128. bool IsSpanValid( uint nOffset, uint nSize ) const;
  129. #endif
  130. GLMContext *m_pCtx; // link back to parent context
  131. EGLMBufferType m_type;
  132. uint m_nSize;
  133. uint m_nActualSize;
  134. bool m_bDynamic;
  135. GLenum m_buffGLTarget; // GL_ARRAY_BUFFER_ARB / GL_ELEMENT_BUFFER_ARB
  136. GLuint m_nHandle; // name of this program in the context
  137. uint m_nRevision; // bump anytime the size changes or buffer is orphaned
  138. bool m_bEnableAsyncMap; // mirror of the buffer state
  139. bool m_bEnableExplicitFlush; // mirror of the buffer state
  140. bool m_bMapped; // is it currently mapped
  141. uint m_dirtyMinOffset; // when equal, range is empty
  142. uint m_dirtyMaxOffset;
  143. float *m_pLastMappedAddress;
  144. int m_nPinnedMemoryOfs;
  145. uint m_nPersistentBufferStartOffset;
  146. bool m_bUsingPersistentBuffer;
  147. bool m_bPseudo; // true if the m_name is 0, and the backing is plain RAM
  148. // in pseudo mode, there is just one RAM buffer that acts as the backing.
  149. // expectation is that this mode would only be used for dynamic indices.
  150. // since indices have to be consumed (copied to command stream) prior to return from a drawing call,
  151. // there's no need to do any fencing or multibuffering. orphaning in particular becomes a no-op.
  152. char *m_pActualPseudoBuf; // storage for pseudo buffer
  153. char *m_pPseudoBuf; // storage for pseudo buffer
  154. char *m_pStaticBuffer;
  155. GLMBuffLockParams m_LockParams;
  156. static char ALIGN16 m_StaticBuffers[ GL_MAX_STATIC_BUFFERS ][ GL_STATIC_BUFFER_SIZE ] ALIGN16_POST;
  157. static bool m_bStaticBufferUsed[ GL_MAX_STATIC_BUFFERS ];
  158. #if GL_ENABLE_INDEX_VERIFICATION
  159. CGLMBufferSpanManager m_BufferSpanManager;
  160. #endif
  161. #if GL_ENABLE_UNLOCK_BUFFER_OVERWRITE_DETECTION
  162. uint m_nDirtyRangeStart;
  163. uint m_nDirtyRangeEnd;
  164. #endif
  165. };
  166. #endif // CGLMBUFFER_H