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.

514 lines
20 KiB

  1. //============ Copyright (c) Valve Corporation, All rights reserved. ============
  2. //
  3. // cglmtex.h
  4. // GLMgr textures
  5. //
  6. //===============================================================================
  7. #ifndef CGLMTEX_H
  8. #define CGLMTEX_H
  9. #pragma once
  10. #ifdef OSX
  11. #include "glmgrbasics.h"
  12. #endif
  13. #include "tier1/utlhash.h"
  14. #include "tier1/utlmap.h"
  15. //===============================================================================
  16. // forward declarations
  17. class GLMContext;
  18. class GLMTester;
  19. class CGLMTexLayoutTable;
  20. class CGLMTex;
  21. class CGLMFBO;
  22. struct IDirect3DSurface9;
  23. #if GLMDEBUG
  24. extern CGLMTex *g_pFirstCGMLTex;
  25. #endif
  26. // For GL_EXT_texture_sRGB_decode
  27. #ifndef GL_TEXTURE_SRGB_DECODE_EXT
  28. #define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48
  29. #endif
  30. #ifndef GL_DECODE_EXT
  31. #define GL_DECODE_EXT 0x8A49
  32. #endif
  33. #ifndef GL_SKIP_DECODE_EXT
  34. #define GL_SKIP_DECODE_EXT 0x8A4A
  35. #endif
  36. //===============================================================================
  37. struct GLMTexFormatDesc
  38. {
  39. const char *m_formatSummary; // for debug visibility
  40. D3DFORMAT m_d3dFormat; // what D3D knows it as; see public/bitmap/imageformat.h
  41. GLenum m_glIntFormat; // GL internal format
  42. GLenum m_glIntFormatSRGB; // internal format if SRGB flavor
  43. GLenum m_glDataFormat; // GL data format
  44. GLenum m_glDataType; // GL data type
  45. int m_chunkSize; // 1 or 4 - 4 is used for compressed textures
  46. int m_bytesPerSquareChunk; // how many bytes for the smallest quantum (m_chunkSize x m_chunkSize)
  47. // this description lets us calculate size cleanly without conditional logic for compression
  48. };
  49. const GLMTexFormatDesc *GetFormatDesc( D3DFORMAT format );
  50. //===============================================================================
  51. // utility function for generating slabs of texels. mostly for test.
  52. typedef struct
  53. {
  54. // in
  55. D3DFORMAT m_format;
  56. void *m_dest; // dest address
  57. int m_chunkCount; // square chunk count (single texels or compressed blocks)
  58. int m_byteCountLimit; // caller expectation of max number of bytes to write out
  59. float r,g,b,a; // color desired
  60. // out
  61. int m_bytesWritten;
  62. } GLMGenTexelParams;
  63. // return true if successful
  64. bool GLMGenTexels( GLMGenTexelParams *params );
  65. //===============================================================================
  66. struct GLMTexLayoutSlice
  67. {
  68. int m_xSize,m_ySize,m_zSize; //texel dimensions of this slice
  69. int m_storageOffset; //where in the storage slab does this slice live
  70. int m_storageSize; //how much storage does this slice occupy
  71. };
  72. enum EGLMTexFlags
  73. {
  74. kGLMTexMipped = 0x01,
  75. kGLMTexMippedAuto = 0x02,
  76. kGLMTexRenderable = 0x04,
  77. kGLMTexIsStencil = 0x08,
  78. kGLMTexIsDepth = 0x10,
  79. kGLMTexSRGB = 0x20,
  80. kGLMTexMultisampled = 0x40, // has an RBO backing it. Cannot combine with Mipped, MippedAuto. One slice maximum, only targeting GL_TEXTURE_2D.
  81. // actually not 100% positive on the mipmapping, the RBO itself can't be mipped, but the resulting texture could
  82. // have mipmaps generated.
  83. };
  84. //===============================================================================
  85. struct GLMTexLayoutKey
  86. {
  87. // input values: held const, these are the hash key for the form map
  88. GLenum m_texGLTarget; // flavor of texture: GL_TEXTURE_2D, GL_TEXTURE_3D, GLTEXTURE_CUBE_MAP
  89. D3DFORMAT m_texFormat; // D3D texel format
  90. unsigned long m_texFlags; // mipped, autogen mips, render target, ... ?
  91. unsigned long m_texSamples; // zero for a plain tex, 2/4/6/8 for "MSAA tex" (RBO backed)
  92. int m_xSize,m_ySize,m_zSize; // size of base mip
  93. };
  94. bool LessFunc_GLMTexLayoutKey( const GLMTexLayoutKey &a, const GLMTexLayoutKey &b );
  95. #define GLM_TEX_MAX_MIPS 14
  96. #define GLM_TEX_MAX_FACES 6
  97. #define GLM_TEX_MAX_SLICES (GLM_TEX_MAX_MIPS * GLM_TEX_MAX_FACES)
  98. #pragma warning( push )
  99. #pragma warning( disable : 4200 )
  100. struct GLMTexLayout
  101. {
  102. char *m_layoutSummary; // for debug visibility
  103. // const inputs used for hashing
  104. GLMTexLayoutKey m_key;
  105. // refcount
  106. int m_refCount;
  107. // derived values:
  108. GLMTexFormatDesc *m_format; // format specific info
  109. int m_mipCount; // derived by starying at base size and working down towards 1x1
  110. int m_faceCount; // 1 for 2d/3d, 6 for cubemap
  111. int m_sliceCount; // product of faces and mips
  112. int m_storageTotalSize; // size of storage slab required
  113. // slice array
  114. GLMTexLayoutSlice m_slices[0]; // dynamically allocated 2-d array [faces][mips]
  115. };
  116. #pragma warning( pop )
  117. class CGLMTexLayoutTable
  118. {
  119. public:
  120. CGLMTexLayoutTable();
  121. GLMTexLayout *NewLayoutRef( GLMTexLayoutKey *pDesiredKey ); // pass in a pointer to layout key - receive ptr to completed layout
  122. void DelLayoutRef( GLMTexLayout *layout ); // pass in pointer to completed layout. refcount is dropped.
  123. void DumpStats( void );
  124. protected:
  125. CUtlMap< GLMTexLayoutKey, GLMTexLayout* > m_layoutMap;
  126. };
  127. //===============================================================================
  128. // a sampler specifies desired state for drawing on a given sampler index
  129. // this is the combination of a texture choice and a set of sampler parameters
  130. // see http://msdn.microsoft.com/en-us/library/bb172602(VS.85).aspx
  131. struct GLMTexLockParams
  132. {
  133. // input params which identify the slice of interest
  134. CGLMTex *m_tex;
  135. int m_face;
  136. int m_mip;
  137. // identifies the region of the slice
  138. GLMRegion m_region;
  139. // tells GLM to force re-read of the texels back from GL
  140. // i.e. "I know I stepped on those texels with a draw or blit - the GLM copy is stale"
  141. bool m_readback;
  142. };
  143. struct GLMTexLockDesc
  144. {
  145. GLMTexLockParams m_req; // form of the lock request
  146. bool m_active; // set true at lock time. cleared at unlock time.
  147. int m_sliceIndex; // which slice in the layout
  148. int m_sliceBaseOffset; // where is that in the texture data
  149. int m_sliceRegionOffset; // offset to the start (lowest address corner) of the region requested
  150. };
  151. //===============================================================================
  152. #define GLM_SAMPLER_COUNT 16
  153. #define GLM_MAX_PIXEL_TEX_SAMPLERS 16
  154. #define GLM_MAX_VERTEX_TEX_SAMPLERS 0
  155. typedef CBitVec<GLM_SAMPLER_COUNT> CTexBindMask;
  156. enum EGLMTexSliceFlag
  157. {
  158. kSliceValid = 0x01, // slice has been teximage'd in whole at least once - set to 0 initially
  159. kSliceStorageValid = 0x02, // if backing store is available, this slice's data is a valid copy - set to 0 initially
  160. kSliceLocked = 0x04, // are one or more locks outstanding on this slice
  161. kSliceFullyDirty = 0x08, // does the slice need to be fully downloaded at unlock time (disregard dirty rects)
  162. };
  163. //===============================================================================
  164. #define GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS (2)
  165. #define GLM_PACKED_SAMPLER_PARAMS_MIN_FILTER_BITS (2)
  166. #define GLM_PACKED_SAMPLER_PARAMS_MAG_FILTER_BITS (2)
  167. #define GLM_PACKED_SAMPLER_PARAMS_MIP_FILTER_BITS (2)
  168. #define GLM_PACKED_SAMPLER_PARAMS_MIN_LOD_BITS (4)
  169. #define GLM_PACKED_SAMPLER_PARAMS_MAX_ANISO_BITS (5)
  170. #define GLM_PACKED_SAMPLER_PARAMS_COMPARE_MODE_BITS (1)
  171. #define GLM_PACKED_SAMPLER_PARAMS_SRGB_BITS (1)
  172. struct GLMTexPackedSamplingParams
  173. {
  174. uint32 m_addressU : GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS;
  175. uint32 m_addressV : GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS;
  176. uint32 m_addressW : GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS;
  177. uint32 m_minFilter : GLM_PACKED_SAMPLER_PARAMS_MIN_FILTER_BITS;
  178. uint32 m_magFilter : GLM_PACKED_SAMPLER_PARAMS_MAG_FILTER_BITS;
  179. uint32 m_mipFilter : GLM_PACKED_SAMPLER_PARAMS_MIP_FILTER_BITS;
  180. uint32 m_minLOD : GLM_PACKED_SAMPLER_PARAMS_MIN_LOD_BITS;
  181. uint32 m_maxAniso : GLM_PACKED_SAMPLER_PARAMS_MAX_ANISO_BITS;
  182. uint32 m_compareMode : GLM_PACKED_SAMPLER_PARAMS_COMPARE_MODE_BITS;
  183. uint32 m_srgb : GLM_PACKED_SAMPLER_PARAMS_SRGB_BITS;
  184. uint32 m_isValid : 1;
  185. };
  186. struct GLMTexSamplingParams
  187. {
  188. union
  189. {
  190. GLMTexPackedSamplingParams m_packed;
  191. uint32 m_bits;
  192. };
  193. uint32 m_borderColor;
  194. FORCEINLINE bool operator== (const GLMTexSamplingParams& rhs ) const
  195. {
  196. return ( m_bits == rhs.m_bits ) && ( m_borderColor == rhs.m_borderColor );
  197. }
  198. FORCEINLINE void SetToDefaults()
  199. {
  200. m_bits = 0;
  201. m_borderColor = 0;
  202. m_packed.m_addressU = D3DTADDRESS_WRAP;
  203. m_packed.m_addressV = D3DTADDRESS_WRAP;
  204. m_packed.m_addressW = D3DTADDRESS_WRAP;
  205. m_packed.m_minFilter = D3DTEXF_POINT;
  206. m_packed.m_magFilter = D3DTEXF_POINT;
  207. m_packed.m_mipFilter = D3DTEXF_NONE;
  208. m_packed.m_maxAniso = 1;
  209. m_packed.m_compareMode = 0;
  210. m_packed.m_isValid = true;
  211. }
  212. #ifndef OSX
  213. FORCEINLINE void SetToSamplerObject( GLuint nSamplerObject ) const
  214. {
  215. static const GLenum dxtogl_addressMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, (GLenum)-1 };
  216. static const GLenum dxtogl_magFilter[4] = { GL_NEAREST, GL_NEAREST, GL_LINEAR, GL_LINEAR };
  217. static const GLenum dxtogl_minFilter[4][4] = // indexed by _D3DTEXTUREFILTERTYPE on both axes: [row is min filter][col is mip filter].
  218. {
  219. /* min = D3DTEXF_NONE */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 }, // D3DTEXF_NONE we just treat like POINT
  220. /* min = D3DTEXF_POINT */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 },
  221. /* min = D3DTEXF_LINEAR */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 },
  222. /* min = D3DTEXF_ANISOTROPIC */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 }, // no diff from prior row, set maxAniso to effect the sampling
  223. };
  224. gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_WRAP_S, dxtogl_addressMode[m_packed.m_addressU] );
  225. gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_WRAP_T, dxtogl_addressMode[m_packed.m_addressV] );
  226. gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_WRAP_R, dxtogl_addressMode[m_packed.m_addressW] );
  227. gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_MIN_FILTER, dxtogl_minFilter[m_packed.m_minFilter][m_packed.m_mipFilter] );
  228. gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_MAG_FILTER, dxtogl_magFilter[m_packed.m_magFilter] );
  229. gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_packed.m_maxAniso );
  230. float flBorderColor[4] = { 0, 0, 0, 0 };
  231. if ( m_borderColor )
  232. {
  233. flBorderColor[0] = ((m_borderColor >> 16) & 0xFF) * (1.0f/255.0f); //R
  234. flBorderColor[1] = ((m_borderColor >> 8) & 0xFF) * (1.0f/255.0f); //G
  235. flBorderColor[2] = ((m_borderColor ) & 0xFF) * (1.0f/255.0f); //B
  236. flBorderColor[3] = ((m_borderColor >> 24) & 0xFF) * (1.0f/255.0f); //A
  237. }
  238. gGL->glSamplerParameterfv( nSamplerObject, GL_TEXTURE_BORDER_COLOR, flBorderColor ); // <-- this crashes ATI's driver, remark it out
  239. gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_MIN_LOD, m_packed.m_minLOD );
  240. gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_COMPARE_MODE_ARB, m_packed.m_compareMode ? GL_COMPARE_R_TO_TEXTURE_ARB : GL_NONE );
  241. if ( m_packed.m_compareMode )
  242. {
  243. gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL );
  244. }
  245. if ( gGL->m_bHave_GL_EXT_texture_sRGB_decode )
  246. {
  247. gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_SRGB_DECODE_EXT, m_packed.m_srgb ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT );
  248. }
  249. }
  250. #endif
  251. inline void DeltaSetToTarget( GLenum target, const GLMTexSamplingParams &curState )
  252. {
  253. static const GLenum dxtogl_addressMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, (GLenum)-1 };
  254. static const GLenum dxtogl_magFilter[4] = { GL_NEAREST, GL_NEAREST, GL_LINEAR, GL_LINEAR };
  255. static const GLenum dxtogl_minFilter[4][4] = // indexed by _D3DTEXTUREFILTERTYPE on both axes: [row is min filter][col is mip filter].
  256. {
  257. /* min = D3DTEXF_NONE */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 }, // D3DTEXF_NONE we just treat like POINT
  258. /* min = D3DTEXF_POINT */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 },
  259. /* min = D3DTEXF_LINEAR */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 },
  260. /* min = D3DTEXF_ANISOTROPIC */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 }, // no diff from prior row, set maxAniso to effect the sampling
  261. };
  262. if ( m_packed.m_addressU != curState.m_packed.m_addressU )
  263. {
  264. gGL->glTexParameteri( target, GL_TEXTURE_WRAP_S, dxtogl_addressMode[m_packed.m_addressU] );
  265. }
  266. if ( m_packed.m_addressV != curState.m_packed.m_addressV )
  267. {
  268. gGL->glTexParameteri( target, GL_TEXTURE_WRAP_T, dxtogl_addressMode[m_packed.m_addressV] );
  269. }
  270. if ( m_packed.m_addressW != curState.m_packed.m_addressW )
  271. {
  272. gGL->glTexParameteri( target, GL_TEXTURE_WRAP_R, dxtogl_addressMode[m_packed.m_addressW] );
  273. }
  274. if ( ( m_packed.m_minFilter != curState.m_packed.m_minFilter ) ||
  275. ( m_packed.m_magFilter != curState.m_packed.m_magFilter ) ||
  276. ( m_packed.m_mipFilter != curState.m_packed.m_mipFilter ) ||
  277. ( m_packed.m_maxAniso != curState.m_packed.m_maxAniso ) )
  278. {
  279. gGL->glTexParameteri( target, GL_TEXTURE_MIN_FILTER, dxtogl_minFilter[m_packed.m_minFilter][m_packed.m_mipFilter] );
  280. gGL->glTexParameteri( target, GL_TEXTURE_MAG_FILTER, dxtogl_magFilter[m_packed.m_magFilter] );
  281. gGL->glTexParameteri( target, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_packed.m_maxAniso );
  282. }
  283. if ( m_borderColor != curState.m_borderColor )
  284. {
  285. float flBorderColor[4] = { 0, 0, 0, 0 };
  286. if ( m_borderColor )
  287. {
  288. flBorderColor[0] = ((m_borderColor >> 16) & 0xFF) * (1.0f/255.0f); //R
  289. flBorderColor[1] = ((m_borderColor >> 8) & 0xFF) * (1.0f/255.0f); //G
  290. flBorderColor[2] = ((m_borderColor ) & 0xFF) * (1.0f/255.0f); //B
  291. flBorderColor[3] = ((m_borderColor >> 24) & 0xFF) * (1.0f/255.0f); //A
  292. }
  293. gGL->glTexParameterfv( target, GL_TEXTURE_BORDER_COLOR, flBorderColor ); // <-- this crashes ATI's driver, remark it out
  294. }
  295. if ( m_packed.m_minLOD != curState.m_packed.m_minLOD )
  296. {
  297. gGL->glTexParameteri( target, GL_TEXTURE_MIN_LOD, m_packed.m_minLOD );
  298. }
  299. if ( m_packed.m_compareMode != curState.m_packed.m_compareMode )
  300. {
  301. gGL->glTexParameteri( target, GL_TEXTURE_COMPARE_MODE_ARB, m_packed.m_compareMode ? GL_COMPARE_R_TO_TEXTURE_ARB : GL_NONE );
  302. if ( m_packed.m_compareMode )
  303. {
  304. gGL->glTexParameteri( target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL );
  305. }
  306. }
  307. if ( ( gGL->m_bHave_GL_EXT_texture_sRGB_decode ) && ( m_packed.m_srgb != curState.m_packed.m_srgb ) )
  308. {
  309. gGL->glTexParameteri( target, GL_TEXTURE_SRGB_DECODE_EXT, m_packed.m_srgb ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT );
  310. }
  311. }
  312. inline void SetToTarget( GLenum target )
  313. {
  314. static const GLenum dxtogl_addressMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, (GLenum)-1 };
  315. static const GLenum dxtogl_magFilter[4] = { GL_NEAREST, GL_NEAREST, GL_LINEAR, GL_LINEAR };
  316. static const GLenum dxtogl_minFilter[4][4] = // indexed by _D3DTEXTUREFILTERTYPE on both axes: [row is min filter][col is mip filter].
  317. {
  318. /* min = D3DTEXF_NONE */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 }, // D3DTEXF_NONE we just treat like POINT
  319. /* min = D3DTEXF_POINT */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 },
  320. /* min = D3DTEXF_LINEAR */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 },
  321. /* min = D3DTEXF_ANISOTROPIC */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 }, // no diff from prior row, set maxAniso to effect the sampling
  322. };
  323. gGL->glTexParameteri( target, GL_TEXTURE_WRAP_S, dxtogl_addressMode[m_packed.m_addressU] );
  324. gGL->glTexParameteri( target, GL_TEXTURE_WRAP_T, dxtogl_addressMode[m_packed.m_addressV] );
  325. gGL->glTexParameteri( target, GL_TEXTURE_WRAP_R, dxtogl_addressMode[m_packed.m_addressW] );
  326. gGL->glTexParameteri( target, GL_TEXTURE_MIN_FILTER, dxtogl_minFilter[m_packed.m_minFilter][m_packed.m_mipFilter] );
  327. gGL->glTexParameteri( target, GL_TEXTURE_MAG_FILTER, dxtogl_magFilter[m_packed.m_magFilter] );
  328. gGL->glTexParameteri( target, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_packed.m_maxAniso );
  329. float flBorderColor[4] = { 0, 0, 0, 0 };
  330. if ( m_borderColor )
  331. {
  332. flBorderColor[0] = ((m_borderColor >> 16) & 0xFF) * (1.0f/255.0f); //R
  333. flBorderColor[1] = ((m_borderColor >> 8) & 0xFF) * (1.0f/255.0f); //G
  334. flBorderColor[2] = ((m_borderColor ) & 0xFF) * (1.0f/255.0f); //B
  335. flBorderColor[3] = ((m_borderColor >> 24) & 0xFF) * (1.0f/255.0f); //A
  336. }
  337. gGL->glTexParameterfv( target, GL_TEXTURE_BORDER_COLOR, flBorderColor ); // <-- this crashes ATI's driver, remark it out
  338. gGL->glTexParameteri( target, GL_TEXTURE_MIN_LOD, m_packed.m_minLOD );
  339. gGL->glTexParameteri( target, GL_TEXTURE_COMPARE_MODE_ARB, m_packed.m_compareMode ? GL_COMPARE_R_TO_TEXTURE_ARB : GL_NONE );
  340. if ( m_packed.m_compareMode )
  341. {
  342. gGL->glTexParameteri( target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL );
  343. }
  344. if ( gGL->m_bHave_GL_EXT_texture_sRGB_decode )
  345. {
  346. gGL->glTexParameteri( target, GL_TEXTURE_SRGB_DECODE_EXT, m_packed.m_srgb ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT );
  347. }
  348. }
  349. };
  350. //===============================================================================
  351. class CGLMTex
  352. {
  353. public:
  354. void Lock( GLMTexLockParams *params, char** addressOut, int* yStrideOut, int *zStrideOut );
  355. void Unlock( GLMTexLockParams *params );
  356. GLuint GetTexName() { return m_texName; }
  357. protected:
  358. friend class GLMContext; // only GLMContext can make CGLMTex objects
  359. friend class GLMTester;
  360. friend class CGLMFBO;
  361. friend struct IDirect3DDevice9;
  362. friend struct IDirect3DBaseTexture9;
  363. friend struct IDirect3DTexture9;
  364. friend struct IDirect3DSurface9;
  365. friend struct IDirect3DCubeTexture9;
  366. friend struct IDirect3DVolumeTexture9;
  367. CGLMTex( GLMContext *ctx, GLMTexLayout *layout, uint levels, const char *debugLabel = NULL );
  368. ~CGLMTex( );
  369. int CalcSliceIndex( int face, int mip );
  370. void CalcTexelDataOffsetAndStrides( int sliceIndex, int x, int y, int z, int *offsetOut, int *yStrideOut, int *zStrideOut );
  371. void ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice=true );
  372. void WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice=true, bool noDataWrite=false );
  373. // last param lets us send NULL data ptr (only legal with uncompressed formats, beware)
  374. // this helps out ResetSRGB.
  375. #if defined( OSX )
  376. void HandleSRGBMismatch( bool srgb, int &srgbFlipCount );
  377. void ResetSRGB( bool srgb, bool noDataWrite );
  378. // re-specify texture format to match desired sRGB form
  379. // noWrite means send NULL for texel source addresses instead of actual data - ideal for RT's
  380. #endif
  381. bool IsRBODirty() const;
  382. void ForceRBONonDirty();
  383. void ForceRBODirty();
  384. // re-specify texture format to match desired sRGB form
  385. // noWrite means send NULL for texel source addresses instead of actual data - ideal for RT's
  386. GLuint m_texName; // name of this texture in the context
  387. GLenum m_texGLTarget;
  388. uint m_nSamplerType; // SAMPLER_2D, etc.
  389. GLMTexSamplingParams m_SamplingParams;
  390. GLMTexLayout *m_layout; // layout of texture (shared across all tex with same layout)
  391. uint m_nLastResolvedBatchCounter;
  392. int m_minActiveMip;//index of lowest mip that has been written. used to drive setting of GL_TEXTURE_MAX_LEVEL.
  393. int m_maxActiveMip;//index of highest mip that has been written. used to drive setting of GL_TEXTURE_MAX_LEVEL.
  394. GLMContext *m_ctx; // link back to parent context
  395. CGLMFBO *m_pBlitSrcFBO;
  396. CGLMFBO *m_pBlitDstFBO;
  397. GLuint m_rboName; // name of MSAA RBO backing the tex if MSAA enabled (or zero)
  398. int m_rtAttachCount; // how many RT's have this texture attached somewhere
  399. char *m_backing; // backing storage if available
  400. int m_lockCount; // lock reqs are stored in the GLMContext for tracking
  401. CUtlVector<unsigned char> m_sliceFlags;
  402. char *m_debugLabel; // strdup() of debugLabel passed in, or NULL
  403. bool m_texClientStorage; // was CS selected for texture
  404. bool m_texPreloaded; // has it been kicked into VRAM with GLMContext::PreloadTex yet
  405. int m_srgbFlipCount;
  406. #if GLMDEBUG
  407. CGLMTex *m_pPrevTex;
  408. CGLMTex *m_pNextTex;
  409. #endif
  410. };
  411. #endif