Team Fortress 2 Source Code as on 22/4/2020
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.

262 lines
7.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. // TOGL CODE LICENSE
  3. //
  4. // Copyright 2011-2014 Valve Corporation
  5. // All Rights Reserved.
  6. //
  7. // Permission is hereby granted, free of charge, to any person obtaining a copy
  8. // of this software and associated documentation files (the "Software"), to deal
  9. // in the Software without restriction, including without limitation the rights
  10. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the Software is
  12. // furnished to do so, subject to the following conditions:
  13. //
  14. // The above copyright notice and this permission notice shall be included in
  15. // all copies or substantial portions of the Software.
  16. //
  17. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. // THE SOFTWARE.
  24. //
  25. // cglmprogram.h
  26. // GLMgr buffers (index / vertex)
  27. // ... maybe add PBO later as well
  28. //===============================================================================
  29. #ifndef CGLMBUFFER_H
  30. #define CGLMBUFFER_H
  31. #pragma once
  32. //===============================================================================
  33. extern bool g_bUsePseudoBufs;
  34. // forward declarations
  35. class GLMContext;
  36. enum EGLMBufferType
  37. {
  38. kGLMVertexBuffer,
  39. kGLMIndexBuffer,
  40. kGLMUniformBuffer, // for bindable uniform
  41. kGLMPixelBuffer, // for PBO
  42. kGLMNumBufferTypes
  43. };
  44. // pass this in "options" to constructor to make a dynamic buffer
  45. #define GLMBufferOptionDynamic 0x00000001
  46. struct GLMBuffLockParams
  47. {
  48. uint m_nOffset;
  49. uint m_nSize;
  50. bool m_bNoOverwrite;
  51. bool m_bDiscard;
  52. };
  53. #define GL_STATIC_BUFFER_SIZE ( 2048 * 1024 )
  54. #define GL_MAX_STATIC_BUFFERS 2
  55. extern void glBufferSubDataMaxSize( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data, uint nMaxSizePerCall = 128 * 1024 );
  56. //===========================================================================//
  57. // Creates an immutable storage for a buffer object
  58. // https://www.opengl.org/registry/specs/ARB/buffer_storage.txt
  59. class CPersistentBuffer
  60. {
  61. public:
  62. CPersistentBuffer();
  63. ~CPersistentBuffer();
  64. void Init( EGLMBufferType type,uint nSize );
  65. void Deinit();
  66. void InsertFence();
  67. void BlockUntilNotBusy();
  68. void Append( uint nSize );
  69. inline uint GetBytesRemaining() const { return m_nSize - m_nOffset; }
  70. inline uint GetOffset() const { return m_nOffset; }
  71. inline void *GetPtr() const { return m_pImmutablePersistentBuf; }
  72. inline GLuint GetHandle() const { return m_nHandle; }
  73. private:
  74. CPersistentBuffer( const CPersistentBuffer & );
  75. CPersistentBuffer & operator= (const CPersistentBuffer &);
  76. uint m_nSize;
  77. EGLMBufferType m_type;
  78. GLenum m_buffGLTarget; // GL_ARRAY_BUFFER_ARB / GL_ELEMENT_BUFFER_ARB
  79. GLuint m_nHandle; // handle of this program in the GL context
  80. // Holds a pointer to the persistently mapped buffer
  81. void* m_pImmutablePersistentBuf;
  82. uint m_nOffset;
  83. #ifdef HAVE_GL_ARB_SYNC
  84. GLsync m_nSyncObj;
  85. #endif
  86. };
  87. //===============================================================================
  88. #if GL_ENABLE_INDEX_VERIFICATION
  89. struct GLDynamicBuf_t
  90. {
  91. GLenum m_nGLType;
  92. uint m_nHandle;
  93. uint m_nActualBufSize;
  94. uint m_nSize;
  95. uint m_nLockOffset;
  96. uint m_nLockSize;
  97. };
  98. class CGLMBufferSpanManager
  99. {
  100. CGLMBufferSpanManager( const CGLMBufferSpanManager& );
  101. CGLMBufferSpanManager& operator= ( const CGLMBufferSpanManager& );
  102. public:
  103. CGLMBufferSpanManager();
  104. ~CGLMBufferSpanManager();
  105. void Init( GLMContext *pContext, EGLMBufferType nBufType, uint nInitialCapacity, uint nBufSize, bool bDynamic );
  106. void Deinit();
  107. inline GLMContext *GetContext() const { return m_pCtx; }
  108. inline GLenum GetGLBufType() const { return ( m_nBufType == kGLMVertexBuffer ) ? GL_ARRAY_BUFFER_ARB : GL_ELEMENT_ARRAY_BUFFER_ARB; }
  109. struct ActiveSpan_t
  110. {
  111. uint m_nStart;
  112. uint m_nEnd;
  113. GLDynamicBuf_t m_buf;
  114. bool m_bOriginalAlloc;
  115. inline ActiveSpan_t() { }
  116. 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 ); }
  117. };
  118. ActiveSpan_t *AddSpan( uint nOffset, uint nMaxSize, uint nActualSize, bool bDiscard, bool bNoOverwrite );
  119. void DiscardAllSpans();
  120. bool IsValid( uint nOffset, uint nSize ) const;
  121. private:
  122. bool AllocDynamicBuf( uint nSize, GLDynamicBuf_t &buf );
  123. void ReleaseDynamicBuf( GLDynamicBuf_t &buf );
  124. GLMContext *m_pCtx;
  125. EGLMBufferType m_nBufType;
  126. uint m_nBufSize;
  127. bool m_bDynamic;
  128. CUtlVector<ActiveSpan_t> m_ActiveSpans;
  129. CUtlVector<ActiveSpan_t> m_DeletedSpans;
  130. int m_nSpanEndMax;
  131. int m_nNumAllocatedBufs;
  132. int m_nTotalBytesAllocated;
  133. };
  134. #endif // GL_ENABLE_INDEX_VERIFICATION
  135. class CGLMBuffer
  136. {
  137. public:
  138. void Lock( GLMBuffLockParams *pParams, char **pAddressOut );
  139. void Unlock( int nActualSize = -1, const void *pActualData = NULL );
  140. GLuint GetHandle() const;
  141. friend class GLMContext; // only GLMContext can make CGLMBuffer objects
  142. friend class GLMTester;
  143. friend struct IDirect3D9;
  144. friend struct IDirect3DDevice9;
  145. CGLMBuffer( GLMContext *pCtx, EGLMBufferType type, uint size, uint options );
  146. ~CGLMBuffer();
  147. void SetModes( bool bAsyncMap, bool bExplicitFlush, bool bForce = false );
  148. void FlushRange( uint offset, uint size );
  149. #if GL_ENABLE_INDEX_VERIFICATION
  150. bool IsSpanValid( uint nOffset, uint nSize ) const;
  151. #endif
  152. GLMContext *m_pCtx; // link back to parent context
  153. EGLMBufferType m_type;
  154. uint m_nSize;
  155. uint m_nActualSize;
  156. bool m_bDynamic;
  157. GLenum m_buffGLTarget; // GL_ARRAY_BUFFER_ARB / GL_ELEMENT_BUFFER_ARB
  158. GLuint m_nHandle; // name of this program in the context
  159. uint m_nRevision; // bump anytime the size changes or buffer is orphaned
  160. bool m_bEnableAsyncMap; // mirror of the buffer state
  161. bool m_bEnableExplicitFlush; // mirror of the buffer state
  162. bool m_bMapped; // is it currently mapped
  163. uint m_dirtyMinOffset; // when equal, range is empty
  164. uint m_dirtyMaxOffset;
  165. float *m_pLastMappedAddress;
  166. int m_nPinnedMemoryOfs;
  167. uint m_nPersistentBufferStartOffset;
  168. bool m_bUsingPersistentBuffer;
  169. bool m_bPseudo; // true if the m_name is 0, and the backing is plain RAM
  170. // in pseudo mode, there is just one RAM buffer that acts as the backing.
  171. // expectation is that this mode would only be used for dynamic indices.
  172. // since indices have to be consumed (copied to command stream) prior to return from a drawing call,
  173. // there's no need to do any fencing or multibuffering. orphaning in particular becomes a no-op.
  174. char *m_pActualPseudoBuf; // storage for pseudo buffer
  175. char *m_pPseudoBuf; // storage for pseudo buffer
  176. char *m_pStaticBuffer;
  177. GLMBuffLockParams m_LockParams;
  178. static char ALIGN16 m_StaticBuffers[ GL_MAX_STATIC_BUFFERS ][ GL_STATIC_BUFFER_SIZE ] ALIGN16_POST;
  179. static bool m_bStaticBufferUsed[ GL_MAX_STATIC_BUFFERS ];
  180. #if GL_ENABLE_INDEX_VERIFICATION
  181. CGLMBufferSpanManager m_BufferSpanManager;
  182. #endif
  183. #if GL_ENABLE_UNLOCK_BUFFER_OVERWRITE_DETECTION
  184. uint m_nDirtyRangeStart;
  185. uint m_nDirtyRangeEnd;
  186. #endif
  187. };
  188. #endif // CGLMBUFFER_H