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.

382 lines
12 KiB

  1. //========= Copyright 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. //-----------------------------------------------------------------------------
  17. // Describes which D3DDEVTYPE to use
  18. //-----------------------------------------------------------------------------
  19. #ifndef USE_REFERENCE_RASTERIZER
  20. #define DX8_DEVTYPE D3DDEVTYPE_HAL
  21. #else
  22. #define DX8_DEVTYPE D3DDEVTYPE_REF
  23. #endif
  24. // PC: By default, PIX profiling is explicitly disallowed using the D3DPERF_SetOptions(1) API on PC
  25. // X360: PIX_INSTRUMENTATION will only generate PIX events in RELEASE builds on 360
  26. // Uncomment to use PIX instrumentation:
  27. #if PIX_ENABLE
  28. #define PIX_INSTRUMENTATION
  29. #endif
  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. // Initialize adapter information
  86. void InitAdapterInfo();
  87. // Code to detect support for texture border mode (not a simple caps check)
  88. void CheckBorderColorSupport( HardwareCaps_t *pCaps, int nAdapter );
  89. // Vendor-dependent code to detect support for various flavors of shadow mapping
  90. void CheckVendorDependentShadowMappingSupport( HardwareCaps_t *pCaps, int nAdapter );
  91. // Vendor-dependent code to detect Alpha To Coverage Backdoors
  92. void CheckVendorDependentAlphaToCoverage( HardwareCaps_t *pCaps, int nAdapter );
  93. // Compute the effective DX support level based on all the other caps
  94. void ComputeDXSupportLevel( HardwareCaps_t &caps );
  95. // Used to enumerate adapters, attach to windows
  96. #if !defined( _X360 )
  97. IDirect3D9 *m_pD3D;
  98. #endif
  99. bool m_bObeyDxCommandlineOverride : 1;
  100. bool m_bAdapterInfoIntialized : 1;
  101. };
  102. extern CShaderDeviceMgrDx8* g_pShaderDeviceMgrDx8;
  103. //-----------------------------------------------------------------------------
  104. // IDirect3D accessor
  105. //-----------------------------------------------------------------------------
  106. #if defined( _X360 )
  107. extern IDirect3D9 *m_pD3D;
  108. inline IDirect3D9* D3D()
  109. {
  110. return m_pD3D;
  111. }
  112. #else
  113. inline IDirect3D9* D3D()
  114. {
  115. return g_pShaderDeviceMgrDx8->D3D();
  116. }
  117. #endif
  118. #define NUM_FRAME_SYNC_QUERIES 2
  119. #define NUM_FRAME_SYNC_FRAMES_LATENCY 0
  120. //-----------------------------------------------------------------------------
  121. // The Dx8implementation of the shader device
  122. //-----------------------------------------------------------------------------
  123. class CShaderDeviceDx8 : public CShaderDeviceBase
  124. {
  125. // Methods of IShaderDevice
  126. public:
  127. virtual bool IsUsingGraphics() const;
  128. virtual ImageFormat GetBackBufferFormat() const;
  129. virtual void GetBackBufferDimensions( int& width, int& height ) const;
  130. virtual void Present();
  131. virtual IShaderBuffer* CompileShader( const char *pProgram, size_t nBufLen, const char *pShaderVersion );
  132. virtual VertexShaderHandle_t CreateVertexShader( IShaderBuffer *pBuffer );
  133. virtual void DestroyVertexShader( VertexShaderHandle_t hShader );
  134. virtual GeometryShaderHandle_t CreateGeometryShader( IShaderBuffer* pShaderBuffer );
  135. virtual void DestroyGeometryShader( GeometryShaderHandle_t hShader );
  136. virtual PixelShaderHandle_t CreatePixelShader( IShaderBuffer* pShaderBuffer );
  137. virtual void DestroyPixelShader( PixelShaderHandle_t hShader );
  138. virtual void ReleaseResources();
  139. virtual void ReacquireResources();
  140. virtual IMesh* CreateStaticMesh( VertexFormat_t format, const char *pBudgetGroup, IMaterial * pMaterial = NULL );
  141. virtual void DestroyStaticMesh( IMesh* mesh );
  142. virtual IVertexBuffer *CreateVertexBuffer( ShaderBufferType_t type, VertexFormat_t fmt, int nVertexCount, const char *pBudgetGroup );
  143. virtual void DestroyVertexBuffer( IVertexBuffer *pVertexBuffer );
  144. virtual IIndexBuffer *CreateIndexBuffer( ShaderBufferType_t bufferType, MaterialIndexFormat_t fmt, int nIndexCount, const char *pBudgetGroup );
  145. virtual void DestroyIndexBuffer( IIndexBuffer *pIndexBuffer );
  146. virtual IVertexBuffer *GetDynamicVertexBuffer( int nStreamID, VertexFormat_t vertexFormat, bool bBuffered = true );
  147. virtual IIndexBuffer *GetDynamicIndexBuffer( MaterialIndexFormat_t fmt, bool bBuffered = true );
  148. virtual void SetHardwareGammaRamp( float fGamma, float fGammaTVRangeMin, float fGammaTVRangeMax, float fGammaTVExponent, bool bTVEnabled );
  149. virtual void SpewDriverInfo() const;
  150. virtual int GetCurrentAdapter() const;
  151. virtual void EnableNonInteractiveMode( MaterialNonInteractiveMode_t mode, ShaderNonInteractiveInfo_t *pInfo = NULL );
  152. virtual void RefreshFrontBufferNonInteractive();
  153. virtual char *GetDisplayDeviceName() OVERRIDE;
  154. // Alternative method for ib/vs
  155. // NOTE: If this works, remove GetDynamicVertexBuffer/IndexBuffer
  156. // Methods of CShaderDeviceBase
  157. public:
  158. virtual bool InitDevice( void* hWnd, int nAdapter, const ShaderDeviceInfo_t &info );
  159. virtual void ShutdownDevice();
  160. virtual bool IsDeactivated() const;
  161. // Other public methods
  162. public:
  163. // constructor, destructor
  164. CShaderDeviceDx8();
  165. virtual ~CShaderDeviceDx8();
  166. // Call this when another app is initializing or finished initializing
  167. virtual void OtherAppInitializing( bool initializing );
  168. // This handles any events queued because they were called outside of the owning thread
  169. virtual void HandleThreadEvent( uint32 threadEvent );
  170. // FIXME: Make private
  171. // Which device are we using?
  172. UINT m_DisplayAdapter;
  173. D3DDEVTYPE m_DeviceType;
  174. protected:
  175. enum DeviceState_t
  176. {
  177. DEVICE_STATE_OK = 0,
  178. DEVICE_STATE_OTHER_APP_INIT,
  179. DEVICE_STATE_LOST_DEVICE,
  180. DEVICE_STATE_NEEDS_RESET,
  181. };
  182. struct NonInteractiveRefreshState_t
  183. {
  184. IDirect3DVertexShader9 *m_pVertexShader;
  185. IDirect3DPixelShader9 *m_pPixelShader;
  186. IDirect3DPixelShader9 *m_pPixelShaderStartup;
  187. IDirect3DPixelShader9 *m_pPixelShaderStartupPass2;
  188. IDirect3DVertexDeclaration9 *m_pVertexDecl;
  189. ShaderNonInteractiveInfo_t m_Info;
  190. MaterialNonInteractiveMode_t m_Mode;
  191. float m_flLastPacifierTime;
  192. int m_nPacifierFrame;
  193. float m_flStartTime;
  194. float m_flLastPresentTime;
  195. float m_flPeakDt;
  196. float m_flTotalDt;
  197. int m_nSamples;
  198. int m_nCountAbove66;
  199. };
  200. protected:
  201. // Creates the D3D Device
  202. bool CreateD3DDevice( void* pHWnd, int nAdapter, const ShaderDeviceInfo_t &info );
  203. // Actually creates the D3D Device once the present parameters are set up
  204. IDirect3DDevice9* InvokeCreateDevice( void* hWnd, int nAdapter, DWORD deviceCreationFlags );
  205. // Checks for CreateQuery support
  206. void DetectQuerySupport( IDirect3DDevice9* pD3DDevice );
  207. // Computes the presentation parameters
  208. void SetPresentParameters( void* hWnd, int nAdapter, const ShaderDeviceInfo_t &info );
  209. // Computes the supersample flags
  210. D3DMULTISAMPLE_TYPE ComputeMultisampleType( int nSampleCount );
  211. // Is the device active?
  212. bool IsActive() const;
  213. // Try to reset the device, returned true if it succeeded
  214. bool TryDeviceReset();
  215. // Queue up the fact that the device was lost
  216. void MarkDeviceLost();
  217. // Deals with lost devices
  218. void CheckDeviceLost( bool bOtherAppInitializing );
  219. // Changes the window size
  220. bool ResizeWindow( const ShaderDeviceInfo_t &info );
  221. // Deals with the frame synching object
  222. void AllocFrameSyncObjects( void );
  223. void FreeFrameSyncObjects( void );
  224. // Alloc and free objects that are necessary for frame syncing
  225. void AllocFrameSyncTextureObject();
  226. void FreeFrameSyncTextureObject();
  227. // Alloc and free objects necessary for noninteractive frame refresh on the x360
  228. bool AllocNonInteractiveRefreshObjects();
  229. void FreeNonInteractiveRefreshObjects();
  230. // FIXME: This is for backward compat; I still haven't solved a way of decoupling this
  231. virtual bool OnAdapterSet() = 0;
  232. virtual void ResetRenderState( bool bFullReset = true ) = 0;
  233. // For measuring if we meed TCR 022 on the XBox (refreshing often enough)
  234. void UpdatePresentStats();
  235. bool InNonInteractiveMode() const;
  236. void ReacquireResourcesInternal( bool bResetState = false, bool bForceReacquire = false, char const *pszForceReason = NULL );
  237. #ifdef DX_TO_GL_ABSTRACTION
  238. public:
  239. virtual void DoStartupShaderPreloading( void );
  240. protected:
  241. #endif
  242. D3DPRESENT_PARAMETERS m_PresentParameters;
  243. ImageFormat m_AdapterFormat;
  244. // Mode info
  245. int m_DeviceSupportsCreateQuery;
  246. ShaderDeviceInfo_t m_PendingVideoModeChangeConfig;
  247. DeviceState_t m_DeviceState;
  248. bool m_bOtherAppInitializing : 1;
  249. bool m_bQueuedDeviceLost : 1;
  250. bool m_IsResizing : 1;
  251. bool m_bPendingVideoModeChange : 1;
  252. bool m_bUsingStencil : 1;
  253. bool m_bResourcesReleased : 1;
  254. // amount of stencil variation we have available
  255. int m_iStencilBufferBits;
  256. #ifdef _X360
  257. CON_COMMAND_MEMBER_F( CShaderDeviceDx8, "360vidinfo", SpewVideoInfo360, "Get information on the video mode on the 360", 0 );
  258. #endif
  259. // Frame sync objects
  260. IDirect3DQuery9 *m_pFrameSyncQueryObject[NUM_FRAME_SYNC_QUERIES];
  261. bool m_bQueryIssued[NUM_FRAME_SYNC_QUERIES];
  262. int m_currentSyncQuery;
  263. IDirect3DTexture9 *m_pFrameSyncTexture;
  264. #if defined( _X360 )
  265. HXUIDC m_hDC;
  266. #endif
  267. CUtlString m_sDisplayDeviceName;
  268. // Used for x360 only
  269. NonInteractiveRefreshState_t m_NonInteractiveRefresh;
  270. CThreadFastMutex m_nonInteractiveModeMutex;
  271. friend class CShaderDeviceMgrDx8;
  272. int m_numReleaseResourcesRefCount; // This is holding the number of ReleaseResources calls queued up,
  273. // for every ReleaseResources call there should be a matching call to
  274. // ReacquireResources, only the last top-level ReacquireResources will
  275. // have effect. Nested ReleaseResources calls are bugs.
  276. };
  277. //-----------------------------------------------------------------------------
  278. // Globals
  279. //-----------------------------------------------------------------------------
  280. extern IDirect3DDevice9 *g_pD3DDevice;
  281. FORCEINLINE IDirect3DDevice9 *Dx9Device()
  282. {
  283. return g_pD3DDevice;
  284. }
  285. extern CShaderDeviceDx8* g_pShaderDeviceDx8;
  286. //-----------------------------------------------------------------------------
  287. // Inline methods
  288. //-----------------------------------------------------------------------------
  289. FORCEINLINE bool CShaderDeviceDx8::IsActive() const
  290. {
  291. return ( g_pD3DDevice != NULL );
  292. }
  293. // used to determine if we're deactivated
  294. FORCEINLINE bool CShaderDeviceDx8::IsDeactivated() const
  295. {
  296. return ( IsPC() && ( ( m_DeviceState != DEVICE_STATE_OK ) || m_bQueuedDeviceLost || m_numReleaseResourcesRefCount ) );
  297. }
  298. #endif // SHADERDEVICEDX8_H