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.

404 lines
14 KiB

  1. //===== Copyright (c) 1996-2008, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #ifndef SHADERDEVICEDX8_H
  9. #define SHADERDEVICEDX8_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include "shaderdevicebase.h"
  14. #include "shaderapidx8_global.h"
  15. #include "tier1/utlvector.h"
  16. #include "materialsystem/imaterialsystem.h"
  17. //-----------------------------------------------------------------------------
  18. // Describes which D3DDEVTYPE to use
  19. //-----------------------------------------------------------------------------
  20. #ifndef USE_REFERENCE_RASTERIZER
  21. #define DX8_DEVTYPE D3DDEVTYPE_HAL
  22. #else
  23. #define DX8_DEVTYPE D3DDEVTYPE_REF
  24. #endif
  25. // PC: By default, PIX profiling is explicitly disallowed using the D3DPERF_SetOptions(1) API on PC
  26. // X360: PIX_INSTRUMENTATION will only generate PIX events in RELEASE builds on 360
  27. // Also be sure to enable PIX_ENABLE in imaterialsystem.h
  28. // Uncomment to use PIX instrumentation:
  29. //#define PIX_INSTRUMENTATION
  30. #define MAX_PIX_ERRORS 3
  31. #if defined( PIX_INSTRUMENTATION ) && defined ( DX_TO_GL_ABSTRACTION ) && defined( _WIN32 )
  32. typedef int (WINAPI *D3DPERF_BeginEvent_FuncPtr)( D3DCOLOR col, LPCWSTR wszName );
  33. typedef int (WINAPI *D3DPERF_EndEvent_FuncPtr)( void );
  34. typedef void (WINAPI *D3DPERF_SetMarker_FuncPtr)( D3DCOLOR col, LPCWSTR wszName );
  35. typedef void (WINAPI *D3DPERF_SetOptions_FuncPtr)( DWORD dwOptions );
  36. #endif
  37. //-----------------------------------------------------------------------------
  38. // The Base implementation of the shader device
  39. //-----------------------------------------------------------------------------
  40. class CShaderDeviceMgrDx8 : public CShaderDeviceMgrBase
  41. {
  42. typedef CShaderDeviceMgrBase BaseClass;
  43. public:
  44. // constructor, destructor
  45. CShaderDeviceMgrDx8();
  46. virtual ~CShaderDeviceMgrDx8();
  47. // Methods of IAppSystem
  48. virtual bool Connect( CreateInterfaceFn factory );
  49. virtual void Disconnect();
  50. virtual InitReturnVal_t Init();
  51. virtual void Shutdown();
  52. // Methods of IShaderDevice
  53. virtual int GetAdapterCount() const;
  54. virtual void GetAdapterInfo( int adapter, MaterialAdapterInfo_t& info ) const;
  55. virtual int GetModeCount( int nAdapter ) const;
  56. virtual void GetModeInfo( ShaderDisplayMode_t* pInfo, int nAdapter, int mode ) const;
  57. virtual void GetCurrentModeInfo( ShaderDisplayMode_t* pInfo, int nAdapter ) const;
  58. virtual bool SetAdapter( int nAdapter, int nFlags );
  59. virtual CreateInterfaceFn SetMode( void *hWnd, int nAdapter, const ShaderDeviceInfo_t& mode );
  60. // Determines hardware caps from D3D
  61. bool ComputeCapsFromD3D( HardwareCaps_t *pCaps, int nAdapter );
  62. // Forces caps to a specific dx level
  63. void ForceCapsToDXLevel( HardwareCaps_t *pCaps, int nDxLevel, const HardwareCaps_t &actualCaps );
  64. // Validates the mode...
  65. bool ValidateMode( int nAdapter, const ShaderDeviceInfo_t &info ) const;
  66. // Returns the amount of video memory in bytes for a particular adapter
  67. virtual int GetVidMemBytes( int nAdapter ) const;
  68. #if !defined( _X360 )
  69. FORCEINLINE IDirect3D9 *D3D() const
  70. {
  71. return m_pD3D;
  72. }
  73. #endif
  74. #if defined( PIX_INSTRUMENTATION ) && defined ( DX_TO_GL_ABSTRACTION ) && defined( _WIN32 )
  75. HMODULE m_hD3D9;
  76. D3DPERF_BeginEvent_FuncPtr m_pBeginEvent;
  77. D3DPERF_EndEvent_FuncPtr m_pEndEvent;
  78. D3DPERF_SetMarker_FuncPtr m_pSetMarker;
  79. D3DPERF_SetOptions_FuncPtr m_pSetOptions;
  80. #endif
  81. protected:
  82. // Determine capabilities
  83. bool DetermineHardwareCaps( );
  84. private:
  85. // Returns the screen resolution
  86. virtual void GetDesktopResolution( int *pWidth, int *pHeight, int nAdapter ) const;
  87. // Initialize adapter information
  88. void InitAdapterInfo();
  89. // Code to detect support for texture border mode (not a simple caps check)
  90. void CheckBorderColorSupport( HardwareCaps_t *pCaps, int nAdapter );
  91. // Vendor-dependent code to detect support for various flavors of shadow mapping
  92. void CheckVendorDependentShadowMappingSupport( HardwareCaps_t *pCaps, int nAdapter );
  93. // Vendor-dependent code to detect Alpha To Coverage Backdoors
  94. void CheckVendorDependentAlphaToCoverage( HardwareCaps_t *pCaps, int nAdapter );
  95. // Vendor-dependent code to detect support for optimal depth buffer rt resolve
  96. void CheckVendorDependentDepthResolveSupport( HardwareCaps_t *pCaps, int nAdapter );
  97. // Compute the effective DX support level based on all the other caps
  98. void ComputeDXSupportLevel( HardwareCaps_t &caps );
  99. // Used to enumerate adapters, attach to windows
  100. #if !defined( _X360 )
  101. IDirect3D9 *m_pD3D;
  102. #endif
  103. bool m_bAdapterInfoIntialized : 1;
  104. };
  105. extern CShaderDeviceMgrDx8* g_pShaderDeviceMgrDx8;
  106. //-----------------------------------------------------------------------------
  107. // IDirect3D accessor
  108. //-----------------------------------------------------------------------------
  109. #if defined( _X360 )
  110. extern IDirect3D9 *m_pD3D;
  111. inline IDirect3D9* D3D()
  112. {
  113. return m_pD3D;
  114. }
  115. #else
  116. inline IDirect3D9* D3D()
  117. {
  118. return g_pShaderDeviceMgrDx8->D3D();
  119. }
  120. #endif
  121. #define NUM_FRAME_SYNC_QUERIES 2
  122. #define NUM_FRAME_SYNC_FRAMES_LATENCY 0
  123. //-----------------------------------------------------------------------------
  124. // The Dx8implementation of the shader device
  125. //-----------------------------------------------------------------------------
  126. class CShaderDeviceDx8 : public CShaderDeviceBase
  127. {
  128. // Methods of IShaderDevice
  129. public:
  130. virtual bool IsUsingGraphics() const;
  131. virtual ImageFormat GetBackBufferFormat() const;
  132. virtual void GetBackBufferDimensions( int& width, int& height ) const;
  133. virtual const AspectRatioInfo_t &GetAspectRatioInfo( void ) const;
  134. virtual void Present();
  135. virtual IShaderBuffer* CompileShader( const char *pProgram, size_t nBufLen, const char *pShaderVersion );
  136. virtual VertexShaderHandle_t CreateVertexShader( IShaderBuffer *pBuffer );
  137. virtual void DestroyVertexShader( VertexShaderHandle_t hShader );
  138. virtual GeometryShaderHandle_t CreateGeometryShader( IShaderBuffer* pShaderBuffer );
  139. virtual void DestroyGeometryShader( GeometryShaderHandle_t hShader );
  140. virtual PixelShaderHandle_t CreatePixelShader( IShaderBuffer* pShaderBuffer );
  141. virtual void DestroyPixelShader( PixelShaderHandle_t hShader );
  142. virtual void ReleaseResources( bool bReleaseManagedResources = true );
  143. virtual void ReacquireResources();
  144. virtual IMesh* CreateStaticMesh( VertexFormat_t format, const char *pBudgetGroup, IMaterial * pMaterial = NULL, VertexStreamSpec_t *pStreamSpec = NULL );
  145. virtual void DestroyStaticMesh( IMesh* mesh );
  146. virtual IVertexBuffer *CreateVertexBuffer( ShaderBufferType_t type, VertexFormat_t fmt, int nVertexCount, const char *pBudgetGroup );
  147. virtual void DestroyVertexBuffer( IVertexBuffer *pVertexBuffer );
  148. virtual IIndexBuffer *CreateIndexBuffer( ShaderBufferType_t bufferType, MaterialIndexFormat_t fmt, int nIndexCount, const char *pBudgetGroup );
  149. virtual void DestroyIndexBuffer( IIndexBuffer *pIndexBuffer );
  150. virtual IVertexBuffer *GetDynamicVertexBuffer( int nStreamID, VertexFormat_t vertexFormat, bool bBuffered = true );
  151. virtual IIndexBuffer *GetDynamicIndexBuffer();
  152. virtual void SetHardwareGammaRamp( float fGamma, float fGammaTVRangeMin, float fGammaTVRangeMax, float fGammaTVExponent, bool bTVEnabled );
  153. virtual void SpewDriverInfo() const;
  154. virtual int GetCurrentAdapter() const;
  155. virtual void EnableNonInteractiveMode( MaterialNonInteractiveMode_t mode, ShaderNonInteractiveInfo_t *pInfo = NULL );
  156. virtual void RefreshFrontBufferNonInteractive();
  157. // Alternative method for ib/vs
  158. // NOTE: If this works, remove GetDynamicVertexBuffer/IndexBuffer
  159. // Methods of CShaderDeviceBase
  160. public:
  161. virtual bool InitDevice( void* hWnd, int nAdapter, const ShaderDeviceInfo_t &info );
  162. virtual void ShutdownDevice();
  163. virtual bool IsDeactivated() const;
  164. // Other public methods
  165. public:
  166. // constructor, destructor
  167. CShaderDeviceDx8();
  168. virtual ~CShaderDeviceDx8();
  169. // Call this when another app is initializing or finished initializing
  170. virtual void OtherAppInitializing( bool initializing );
  171. // This handles any events queued because they were called outside of the owning thread
  172. virtual void HandleThreadEvent( uint32 threadEvent );
  173. // FIXME: Make private
  174. // Which device are we using?
  175. UINT m_DisplayAdapter;
  176. D3DDEVTYPE m_DeviceType;
  177. protected:
  178. enum DeviceState_t
  179. {
  180. DEVICE_STATE_OK = 0,
  181. DEVICE_STATE_OTHER_APP_INIT,
  182. DEVICE_STATE_LOST_DEVICE,
  183. DEVICE_STATE_NEEDS_RESET,
  184. };
  185. struct NonInteractiveRefreshState_t
  186. {
  187. IDirect3DVertexShader9 *m_pVertexShader;
  188. IDirect3DPixelShader9 *m_pPixelShader;
  189. IDirect3DPixelShader9 *m_pPixelShaderStartup;
  190. IDirect3DPixelShader9 *m_pPixelShaderStartupPass2;
  191. IDirect3DVertexDeclaration9 *m_pVertexDecl;
  192. ShaderNonInteractiveInfo_t m_Info;
  193. MaterialNonInteractiveMode_t m_Mode;
  194. float m_flLastPacifierTime;
  195. int m_nPacifierFrame;
  196. float m_flStartTime;
  197. float m_flLastPresentTime;
  198. float m_flPeakDt;
  199. float m_flTotalDt;
  200. int m_nSamples;
  201. int m_nCountAbove66;
  202. };
  203. protected:
  204. // Creates the D3D Device
  205. bool CreateD3DDevice( void* pHWnd, int nAdapter, const ShaderDeviceInfo_t &info );
  206. // Actually creates the D3D Device once the present parameters are set up
  207. IDirect3DDevice9* InvokeCreateDevice( void* hWnd, int nAdapter, DWORD deviceCreationFlags );
  208. // Checks for CreateQuery support
  209. void DetectQuerySupport( IDirect3DDevice9* pD3DDevice );
  210. // Computes the presentation parameters
  211. void SetPresentParameters( void* hWnd, int nAdapter, const ShaderDeviceInfo_t &info, bool bSetSymbolsOnly = false );
  212. void CalcBackBufferDimensions( const ShaderDisplayMode_t &mode, const ShaderDeviceInfo_t &info, int *pBackBufferWidth, int *pBackBufferHeight );
  213. // Computes the supersample flags
  214. D3DMULTISAMPLE_TYPE ComputeMultisampleType( int nSampleCount );
  215. // Is the device active?
  216. bool IsActive() const;
  217. // Try to reset the device, returned true if it succeeded
  218. bool TryDeviceReset();
  219. // Queue up the fact that the device was lost
  220. void MarkDeviceLost();
  221. // Deals with lost devices
  222. void CheckDeviceLost( bool bOtherAppInitializing );
  223. // Changes the window size
  224. bool ResizeWindow( const ShaderDeviceInfo_t &info );
  225. // Deals with the frame synching object
  226. void AllocFrameSyncObjects( void );
  227. void FreeFrameSyncObjects( void );
  228. // Alloc and free objects that are necessary for frame syncing
  229. void AllocFrameSyncTextureObject();
  230. void FreeFrameSyncTextureObject();
  231. // Alloc and free objects necessary for noninteractive frame refresh on the x360
  232. bool AllocNonInteractiveRefreshObjects();
  233. void FreeNonInteractiveRefreshObjects();
  234. bool BuildStaticShader( bool bVertexShader, void **ppShader, const char *shaderName,
  235. const char *strShaderProgram, const DWORD *shaderData, unsigned int shaderSize );
  236. // FIXME: This is for backward compat; I still haven't solved a way of decoupling this
  237. virtual bool OnAdapterSet() = 0;
  238. virtual void ResetRenderState( bool bFullReset = true ) = 0;
  239. // For measuring if we meed TCR 022 on the XBox (refreshing often enough)
  240. void UpdatePresentStats();
  241. bool InNonInteractiveMode() const;
  242. void ReacquireResourcesInternal( bool bResetState = false, bool bForceReacquire = false, char const *pszForceReason = NULL );
  243. void OnDebugEvent( const char * pEvent = "" );
  244. #ifdef DX_TO_GL_ABSTRACTION
  245. public:
  246. virtual void DoStartupShaderPreloading( void );
  247. protected:
  248. #endif
  249. #ifndef _GAMECONSOLE
  250. IDirect3DDevice9 *m_pD3DDevice;
  251. #endif
  252. D3DPRESENT_PARAMETERS m_PresentParameters;
  253. ImageFormat m_AdapterFormat;
  254. // Mode info
  255. int m_DeviceSupportsCreateQuery;
  256. ShaderDeviceInfo_t m_PendingVideoModeChangeConfig;
  257. DeviceState_t m_DeviceState;
  258. bool m_bOtherAppInitializing : 1;
  259. bool m_bQueuedDeviceLost : 1;
  260. bool m_IsResizing : 1;
  261. bool m_bPendingVideoModeChange : 1;
  262. bool m_bUsingStencil : 1;
  263. bool m_bResourcesReleased : 1;
  264. // amount of stencil variation we have available
  265. int m_iStencilBufferBits;
  266. #ifdef _X360
  267. CON_COMMAND_MEMBER_F( CShaderDeviceDx8, "360vidinfo", SpewVideoInfo360, "Get information on the video mode on the 360", 0 );
  268. #endif
  269. // Frame sync objects
  270. IDirect3DQuery9 *m_pFrameSyncQueryObject[NUM_FRAME_SYNC_QUERIES];
  271. bool m_bQueryIssued[NUM_FRAME_SYNC_QUERIES];
  272. int m_currentSyncQuery;
  273. IDirect3DTexture9 *m_pFrameSyncTexture;
  274. #if defined( _X360 )
  275. HXUIDC m_hDC;
  276. #endif
  277. AspectRatioInfo_t m_AspectRatioInfo;
  278. // Used for x360 only
  279. NonInteractiveRefreshState_t m_NonInteractiveRefresh;
  280. CThreadFastMutex m_nonInteractiveModeMutex;
  281. friend class CShaderDeviceMgrDx8;
  282. int m_numReleaseResourcesRefCount; // This is holding the number of ReleaseResources calls queued up,
  283. // for every ReleaseResources call there should be a matching call to
  284. // ReacquireResources, only the last top-level ReacquireResources will
  285. // have effect. Nested ReleaseResources calls are bugs.
  286. };
  287. //-----------------------------------------------------------------------------
  288. // Globals
  289. //-----------------------------------------------------------------------------
  290. #if defined( _GAMECONSOLE )
  291. extern IDirect3DDevice9 *m_pD3DDevice;
  292. FORCEINLINE IDirect3DDevice9 *Dx9Device()
  293. {
  294. return m_pD3DDevice;
  295. }
  296. #else
  297. class D3DDeviceWrapper;
  298. D3DDeviceWrapper *Dx9Device();
  299. #endif
  300. extern CShaderDeviceDx8* g_pShaderDeviceDx8;
  301. //-----------------------------------------------------------------------------
  302. // Inline methods
  303. //-----------------------------------------------------------------------------
  304. #if defined( _GAMECONSOLE )
  305. FORCEINLINE bool CShaderDeviceDx8::IsActive() const
  306. {
  307. return ( m_pD3DDevice != NULL );
  308. }
  309. #endif
  310. // used to determine if we're deactivated
  311. FORCEINLINE bool CShaderDeviceDx8::IsDeactivated() const
  312. {
  313. return ( IsPC() && ( ( m_DeviceState != DEVICE_STATE_OK ) || m_bQueuedDeviceLost || m_numReleaseResourcesRefCount ) );
  314. }
  315. #endif // SHADERDEVICEDX8_H