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.

383 lines
18 KiB

  1. //============ Copyright (c) Valve Corporation, All rights reserved. ============
  2. //
  3. // glentrypoints.h
  4. //
  5. //===============================================================================
  6. #ifndef GLENTRYPOINTS_H
  7. #define GLENTRYPOINTS_H
  8. #pragma once
  9. #ifdef DX_TO_GL_ABSTRACTION
  10. #include "tier0/platform.h"
  11. #include "tier0/vprof_telemetry.h"
  12. #include "interface.h"
  13. #include "togl/rendermechanism.h"
  14. void *VoidFnPtrLookup_GlMgr( const char *libname, const char *fn, bool &okay, const bool bRequired, void *fallback=NULL );
  15. #if GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS
  16. class CGLExecuteHelperBase
  17. {
  18. public:
  19. inline void StartCall(const char *pName);
  20. inline void StopCall(const char *pName);
  21. #if GL_TRACK_API_TIME
  22. TmU64 m_nStartTime;
  23. #endif
  24. };
  25. template < class FunctionType, typename Result >
  26. class CGLExecuteHelper : public CGLExecuteHelperBase
  27. {
  28. public:
  29. inline CGLExecuteHelper(FunctionType pFn, const char *pName ) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(); StopCall(pName); }
  30. template<typename A> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a); StopCall(pName); }
  31. template<typename A, typename B> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b); StopCall(pName); }
  32. template<typename A, typename B, typename C> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c); StopCall(pName); }
  33. template<typename A, typename B, typename C, typename D> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d); StopCall(pName); }
  34. template<typename A, typename B, typename C, typename D, typename E> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e); StopCall(pName); }
  35. template<typename A, typename B, typename C, typename D, typename E, typename F> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f); StopCall(pName); }
  36. template<typename A, typename B, typename C, typename D, typename E, typename F, typename G> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g); StopCall(pName); }
  37. template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h); StopCall(pName); }
  38. template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h, i); StopCall(pName); }
  39. template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h, i, j); StopCall(pName); }
  40. inline operator Result() const { return m_Result; }
  41. inline operator char*() const { return (char*)m_Result; }
  42. FunctionType m_pFn;
  43. Result m_Result;
  44. };
  45. template < class FunctionType>
  46. class CGLExecuteHelper<FunctionType, void> : public CGLExecuteHelperBase
  47. {
  48. public:
  49. inline CGLExecuteHelper(FunctionType pFn, const char *pName ) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(); StopCall(pName); }
  50. template<typename A> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a); StopCall(pName); }
  51. template<typename A, typename B> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b); StopCall(pName); }
  52. template<typename A, typename B, typename C> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c); StopCall(pName); }
  53. template<typename A, typename B, typename C, typename D> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d); StopCall(pName); }
  54. template<typename A, typename B, typename C, typename D, typename E> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e); StopCall(pName); }
  55. template<typename A, typename B, typename C, typename D, typename E, typename F> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f); StopCall(pName); }
  56. template<typename A, typename B, typename C, typename D, typename E, typename F, typename G> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g); StopCall(pName); }
  57. template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h); StopCall(pName); }
  58. template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h, i); StopCall(pName); }
  59. template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h, i, j); StopCall(pName); }
  60. FunctionType m_pFn;
  61. };
  62. #endif
  63. template < class FunctionType, typename Result >
  64. class CDynamicFunctionOpenGLBase
  65. {
  66. public:
  67. // Construct with a NULL function pointer. You must manually call
  68. // Lookup() before you can call a dynamic function through this interface.
  69. CDynamicFunctionOpenGLBase() : m_pFn(NULL) {}
  70. // Construct and do a lookup right away. You will need to make sure that
  71. // the lookup actually succeeded, as the gl library might have failed to load
  72. // or (fn) might not exist in it.
  73. CDynamicFunctionOpenGLBase(const char *fn, FunctionType fallback=NULL) : m_pFn(NULL)
  74. {
  75. Lookup(fn, fallback);
  76. }
  77. // Construct and do a lookup right away. See comments in Lookup() about what (okay) does.
  78. CDynamicFunctionOpenGLBase(const char *fn, bool &okay, FunctionType fallback=NULL) : m_pFn(NULL)
  79. {
  80. Lookup(fn, okay, fallback);
  81. }
  82. // Load library if necessary, look up symbol. Returns true and sets
  83. // m_pFn on successful lookup, returns false otherwise. If the
  84. // function pointer is already looked up, this return true immediately.
  85. // Use Reset() first if you want to look up the symbol again.
  86. // This function will return false immediately unless (okay) is true.
  87. // This allows you to chain lookups like this:
  88. // bool okay = true;
  89. // x.Lookup(lib, "x", okay);
  90. // y.Lookup(lib, "y", okay);
  91. // z.Lookup(lib, "z", okay);
  92. // if (okay) { printf("All functions were loaded successfully!\n"); }
  93. // If you supply a fallback, it'll be used if the lookup fails (and if
  94. // non-NULL, means this will always return (okay)).
  95. bool Lookup(const char *libname, const char *fn, bool &okay, FunctionType fallback=NULL)
  96. {
  97. if (!okay)
  98. return false;
  99. else if (this->m_pFn == NULL)
  100. {
  101. this->m_pFn = (FunctionType) VoidFnPtrLookup_GlMgr(libname, fn, okay, false, (void *) fallback);
  102. this->SetFuncName( fn );
  103. }
  104. okay = m_pFn != NULL;
  105. return okay;
  106. }
  107. // Load library if necessary, look up symbol. Returns true and sets
  108. // m_pFn on successful lookup, returns false otherwise. If the
  109. // function pointer is already looked up, this return true immediately.
  110. // Use Reset() first if you want to look up the symbol again.
  111. // This function will return false immediately unless (okay) is true.
  112. // If you supply a fallback, it'll be used if the lookup fails (and if
  113. // non-NULL, means this will always return true).
  114. bool Lookup(const char *fn, FunctionType fallback=NULL)
  115. {
  116. bool okay = true;
  117. return Lookup(fn, okay, fallback);
  118. }
  119. // Invalidates the current lookup. Makes the function pointer NULL. You
  120. // will need to call Lookup() before you can call a dynamic function
  121. // through this interface again.
  122. void Reset() { m_pFn = NULL; }
  123. // Force this to be a specific function pointer.
  124. void Force(FunctionType ptr) { m_pFn = ptr; }
  125. // Retrieve the actual function pointer.
  126. FunctionType Pointer() const { return m_pFn; }
  127. #if GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS
  128. #if GL_TELEMETRY_ZONES || GL_DUMP_ALL_API_CALLS
  129. #define GL_FUNC_NAME m_szName
  130. #else
  131. #define GL_FUNC_NAME ""
  132. #endif
  133. inline CGLExecuteHelper<FunctionType, Result> operator() () const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME ); }
  134. template<typename T>
  135. inline CGLExecuteHelper<FunctionType, Result> operator() (T a) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a); }
  136. template<typename T, typename U>
  137. inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b); }
  138. template<typename T, typename U, typename V>
  139. inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c ) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c); }
  140. template<typename T, typename U, typename V, typename W>
  141. inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d); }
  142. template<typename T, typename U, typename V, typename W, typename X>
  143. inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e); }
  144. template<typename T, typename U, typename V, typename W, typename X, typename Y>
  145. inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f); }
  146. template<typename T, typename U, typename V, typename W, typename X, typename Y, typename Z>
  147. inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f, Z g) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g); }
  148. template<typename T, typename U, typename V, typename W, typename X, typename Y, typename Z, typename A>
  149. inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f, Z g, A h) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h); }
  150. template<typename T, typename U, typename V, typename W, typename X, typename Y, typename Z, typename A, typename B>
  151. inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f, Z g, A h, B i) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h, i); }
  152. template<typename T, typename U, typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C>
  153. inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f, Z g, A h, B i, C j) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h, i, j); }
  154. #else
  155. operator FunctionType() const { return m_pFn; }
  156. #endif
  157. // Can be used to verify that we have an actual function looked up and
  158. // ready to call: if (!MyDynFunc) { printf("Function not found!\n"); }
  159. operator bool () const { return m_pFn != NULL; }
  160. bool operator !() const { return m_pFn == NULL; }
  161. protected:
  162. FunctionType m_pFn;
  163. #if GL_TELEMETRY_ZONES || GL_DUMP_ALL_API_CALLS
  164. char m_szName[32];
  165. inline void SetFuncName(const char *pFn) { V_strncpy( m_szName, pFn, sizeof( m_szName ) ); }
  166. #else
  167. inline void SetFuncName(const char *pFn) { (void)pFn; }
  168. #endif
  169. };
  170. // This works a lot like CDynamicFunctionMustInit, but we use SDL_GL_GetProcAddress().
  171. template < const bool bRequired, class FunctionType, typename Result >
  172. class CDynamicFunctionOpenGL : public CDynamicFunctionOpenGLBase< FunctionType, Result >
  173. {
  174. private: // forbid default constructor.
  175. CDynamicFunctionOpenGL() {}
  176. public:
  177. CDynamicFunctionOpenGL(const char *libname, const char *fn, FunctionType fallback=NULL)
  178. {
  179. bool okay = true;
  180. Lookup(libname, fn, okay, fallback);
  181. this->SetFuncName( fn );
  182. }
  183. CDynamicFunctionOpenGL(const char *libname, const char *fn, bool &okay, FunctionType fallback=NULL)
  184. {
  185. Lookup(libname, fn, okay, fallback);
  186. this->SetFuncName( fn );
  187. }
  188. // Please note this is not virtual.
  189. // !!! FIXME: we might want to fall back and try "EXT" or "ARB" versions in some case.
  190. bool Lookup(const char *libname, const char *fn, bool &okay, FunctionType fallback=NULL)
  191. {
  192. if (this->m_pFn == NULL)
  193. {
  194. this->m_pFn = (FunctionType) VoidFnPtrLookup_GlMgr(libname, fn, okay, bRequired, (void *) fallback);
  195. this->SetFuncName( fn );
  196. }
  197. return okay;
  198. }
  199. };
  200. enum GLDriverStrings_t
  201. {
  202. cGLVendorString,
  203. cGLRendererString,
  204. cGLVersionString,
  205. cGLExtensionsString,
  206. cGLTotalDriverStrings
  207. };
  208. enum GLDriverProvider_t
  209. {
  210. cGLDriverProviderUnknown,
  211. cGLDriverProviderNVIDIA,
  212. cGLDriverProviderAMD,
  213. cGLDriverProviderIntel,
  214. cGLDriverProviderIntelOpenSource,
  215. cGLDriverProviderApple,
  216. cGLTotalDriverProviders
  217. };
  218. // This provides all the entry points for a given OpenGL context.
  219. // ENTRY POINTS ARE ONLY VALID FOR THE CONTEXT THAT WAS CURRENT WHEN
  220. // YOU LOOKED THEM UP. 99% of the time, this is not a problem, but
  221. // that 1% is really hard to track down. Always access the GL
  222. // through this class!
  223. class COpenGLEntryPoints
  224. {
  225. COpenGLEntryPoints( const COpenGLEntryPoints & );
  226. COpenGLEntryPoints &operator= ( const COpenGLEntryPoints & );
  227. public:
  228. // The GL context you are looking up entry points for must be current when you construct this object!
  229. COpenGLEntryPoints(const char *libname);
  230. ~COpenGLEntryPoints();
  231. void ClearEntryPoints();
  232. uint64 m_nTotalGLCycles, m_nTotalGLCalls;
  233. const char *m_strLibName; // this is the pointer you passed in the constructor, or a default if you passed NULL.
  234. int m_nOpenGLVersionMajor; // if GL_VERSION is 2.1.0, this will be set to 2.
  235. int m_nOpenGLVersionMinor; // if GL_VERSION is 2.1.0, this will be set to 1.
  236. int m_nOpenGLVersionPatch; // if GL_VERSION is 2.1.0, this will be set to 0.
  237. bool m_bHave_OpenGL;
  238. char *m_pGLDriverStrings[cGLTotalDriverStrings];
  239. GLDriverProvider_t m_nDriverProvider;
  240. #ifdef OSX
  241. #define GL_EXT(x,glmajor,glminor) bool m_bHave_##x;
  242. #define GL_FUNC(ext,req,ret,fn,arg,call) CDynamicFunctionOpenGL< req, ret (*) arg, ret > fn;
  243. #define GL_FUNC_VOID(ext,req,fn,arg,call) CDynamicFunctionOpenGL< req, void (*) arg, void > fn;
  244. #else
  245. #define GL_EXT(x,glmajor,glminor) bool m_bHave_##x;
  246. #define GL_FUNC(ext,req,ret,fn,arg,call) CDynamicFunctionOpenGL< req, ret (APIENTRY *) arg, ret > fn;
  247. #define GL_FUNC_VOID(ext,req,fn,arg,call) CDynamicFunctionOpenGL< req, void (APIENTRY *) arg, void > fn;
  248. #endif
  249. #include "togl/glfuncs.inl"
  250. #undef GL_FUNC_VOID
  251. #undef GL_FUNC
  252. #undef GL_EXT
  253. bool HasSwapTearExtension() const
  254. {
  255. #ifdef _WIN32
  256. return m_bHave_WGL_EXT_swap_control_tear;
  257. #else
  258. return m_bHave_GLX_EXT_swap_control_tear;
  259. #endif
  260. }
  261. };
  262. // This will be set to the current OpenGL context's entry points.
  263. extern COpenGLEntryPoints *gGL;
  264. typedef void * (*GL_GetProcAddressCallbackFunc_t)(const char *, const char *, bool &, const bool, void *);
  265. #ifdef TOGL_DLL_EXPORT
  266. DLL_EXPORT COpenGLEntryPoints *ToGLConnectLibraries( CreateInterfaceFn factory );
  267. DLL_EXPORT void ToGLDisconnectLibraries();
  268. DLL_EXPORT COpenGLEntryPoints *GetOpenGLEntryPoints(GL_GetProcAddressCallbackFunc_t callback);
  269. DLL_EXPORT void ClearOpenGLEntryPoints();
  270. #else
  271. DLL_IMPORT COpenGLEntryPoints *ToGLConnectLibraries( CreateInterfaceFn factory );
  272. DLL_IMPORT void ToGLDisconnectLibraries();
  273. DLL_IMPORT COpenGLEntryPoints *GetOpenGLEntryPoints(GL_GetProcAddressCallbackFunc_t callback);
  274. DLL_IMPORT void ClearOpenGLEntryPoints();
  275. #endif
  276. #if GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS
  277. inline void CGLExecuteHelperBase::StartCall(const char *pName)
  278. {
  279. (void)pName;
  280. #if GL_TELEMETRY_ZONES
  281. tmEnter( TELEMETRY_LEVEL3, TMZF_NONE, pName );
  282. #endif
  283. #if GL_TRACK_API_TIME
  284. m_nStartTime = tmFastTime();
  285. #endif
  286. #if GL_DUMP_ALL_API_CALLS
  287. static bool s_bDumpCalls;
  288. if ( s_bDumpCalls )
  289. {
  290. char buf[128];
  291. buf[0] = 'G';
  292. buf[1] = 'L';
  293. buf[2] = ':';
  294. size_t l = strlen( pName );
  295. memcpy( buf + 3, pName, l );
  296. buf[3 + l] = '\n';
  297. buf[4 + l] = '\0';
  298. Plat_DebugString( buf );
  299. }
  300. #endif
  301. }
  302. inline void CGLExecuteHelperBase::StopCall(const char *pName)
  303. {
  304. #if GL_TRACK_API_TIME
  305. uint64 nTotalCycles = tmFastTime() - m_nStartTime;
  306. #endif
  307. #if GL_TELEMETRY_ZONES
  308. tmLeave( TELEMETRY_LEVEL3 );
  309. #endif
  310. #if GL_TRACK_API_TIME
  311. //double flMilliseconds = g_Telemetry.flRDTSCToMilliSeconds * nTotalCycles;
  312. if (gGL)
  313. {
  314. gGL->m_nTotalGLCycles += nTotalCycles;
  315. gGL->m_nTotalGLCalls++;
  316. }
  317. #endif
  318. }
  319. #endif
  320. #endif // DX_TO_GL_ABSTRACTION
  321. #endif // GLENTRYPOINTS_H