//========== Copyright 2005, Valve Corporation, All rights reserved. ======== // // Purpose: // //============================================================================= #ifndef CMATERIALSYSTEM_H #define CMATERIALSYSTEM_H #include "tier1/delegates.h" #include "materialsystem_global.h" #include "materialsystem/imaterialsystem.h" #include "materialsystem/ishaderapi.h" #include "imaterialinternal.h" #include "imaterialsysteminternal.h" #include "shaderapi/ishaderutil.h" #include "materialsystem/deformations.h" #include "cmaterialdict.h" #include "cmatlightmaps.h" #include "cmatpaintmaps.h" #include "cmatrendercontext.h" #include "cmatqueuedrendercontext.h" #include "materialsystem_global.h" #include "custom_material.h" #include "composite_texture.h" #ifndef MATSYS_INTERNAL #error "This file is private to the implementation of IMaterialSystem/IMaterialSystemInternal" #endif #if defined( _WIN32 ) #pragma once #endif #ifdef _PS3 #include "tls_ps3.h" inline IMatRenderContextInternal *& Ps3TlsMaterialSystemRenderContextFn() { void **ppv = &( GetTLSGlobals()->pMaterialSystemRenderContext ); return *( IMatRenderContextInternal ** ) ppv; } #define Ps3TlsMaterialSystemRenderContext Ps3TlsMaterialSystemRenderContextFn() #endif //----------------------------------------------------------------------------- class CJob; struct DeferredUpdateLightmapInfo_t; // typedefs to allow use of delegation macros typedef int LightmapOffset_t[2]; //----------------------------------------------------------------------------- extern CThreadFastMutex g_MatSysMutex; enum AsyncTextureLoadError_t { ASYNCTEXTURE_LOADERROR_NONE = 0, ASYNCTEXTURE_LOADERROR_FILEOPEN = -1, ASYNCTEXTRUE_LOADERROR_READING = -2, }; struct AsyncTextureLoad_t { AsyncTextureContext_t *m_pContext; void *m_pData; int m_nNumReadBytes; AsyncTextureLoadError_t m_LoadError; }; //----------------------------------------------------------------------------- // The material system implementation //----------------------------------------------------------------------------- class CMaterialSystem : public CTier2AppSystem< IMaterialSystemInternal >, public IShaderUtil { typedef CTier2AppSystem< IMaterialSystemInternal > BaseClass; public: CMaterialSystem(); ~CMaterialSystem(); //--------------------------------------------------------- // Initialization and shutdown //--------------------------------------------------------- // // IAppSystem // virtual bool Connect( CreateInterfaceFn factory ); virtual void Disconnect(); virtual void * QueryInterface( const char *pInterfaceName ); virtual InitReturnVal_t Init(); virtual void Shutdown(); virtual const AppSystemInfo_t * GetDependencies( ) { return NULL; } virtual AppSystemTier_t GetTier() { return APP_SYSTEM_TIER2; } virtual void Reconnect( CreateInterfaceFn factory, const char *pInterfaceName ) { BaseClass::Reconnect( factory, pInterfaceName ); } CreateInterfaceFn Init( const char* pShaderDLL, IMaterialProxyFactory* pMaterialProxyFactory, CreateInterfaceFn fileSystemFactory, CreateInterfaceFn cvarFactory ); // Call this to set an explicit shader version to use // Must be called before Init(). void SetShaderAPI( const char *pShaderAPIDLL ); // Must be called before Init(), if you're going to call it at all... void SetAdapter( int nAdapter, int nFlags ); void ModInit(); void ModShutdown(); private: // Used to dynamically load and unload the shader api CreateInterfaceFn CreateShaderAPI( const char* pShaderDLL ); void DestroyShaderAPI(); // Method to get at interfaces supported by the SHADDERAPI void * QueryShaderAPI( const char *pInterfaceName ); // Initializes the color correction terms void InitColorCorrection(); // force the thread mode to single threaded, synchronizes with render thread if running void ForceSingleThreaded(); void ThreadRelease( void ); // Tell QMS to release GL void ThreadAcquire( void ); // Tell QMS to acquire GL public: virtual void SetThreadMode( MaterialThreadMode_t nextThreadMode, int nServiceThread ); virtual MaterialThreadMode_t GetThreadMode(); // current thread mode virtual bool IsRenderThreadSafe( ); virtual bool AllowThreading( bool bAllow, int nServiceThread ); virtual void ExecuteQueued(); virtual void OnDebugEvent( const char * pEvent = "" ); //--------------------------------------------------------- // Component accessors //--------------------------------------------------------- const CMatLightmaps * GetLightmaps() const { return &m_Lightmaps; } CMatLightmaps * GetLightmaps() { return &m_Lightmaps; } const CMatPaintmaps * GetPaintmaps( void ) const { return &m_Paintmaps; } CMatPaintmaps * GetPaintmaps( void ) { return &m_Paintmaps; } IMatRenderContext * GetRenderContext(); IMatRenderContext * CreateRenderContext( MaterialContextType_t type ); IMatRenderContext * SetRenderContext( IMatRenderContext * ); #ifdef _PS3 const IMatRenderContextInternal * GetRenderContextInternal() const { IMatRenderContextInternal *pRenderContext = Ps3TlsMaterialSystemRenderContext; return ( pRenderContext ) ? pRenderContext : &m_HardwareRenderContext; } IMatRenderContextInternal * GetRenderContextInternal() { IMatRenderContextInternal *pRenderContext = Ps3TlsMaterialSystemRenderContext; return ( pRenderContext ) ? pRenderContext : &m_HardwareRenderContext; } #elif defined(_X360) const IMatRenderContextInternal * GetRenderContextInternal() const { IMatRenderContextInternal *pRenderContext = m_pRenderContexts[(int)ThreadInMainThread()]; return ( pRenderContext ) ? pRenderContext : &m_HardwareRenderContext; } IMatRenderContextInternal * GetRenderContextInternal() { IMatRenderContextInternal *pRenderContext = m_pRenderContexts[(int)ThreadInMainThread()]; return ( pRenderContext ) ? pRenderContext : &m_HardwareRenderContext; } #else const IMatRenderContextInternal * GetRenderContextInternal() const { IMatRenderContextInternal *pRenderContext = m_pRenderContext; return ( pRenderContext ) ? pRenderContext : &m_HardwareRenderContext; } IMatRenderContextInternal * GetRenderContextInternal() { IMatRenderContextInternal *pRenderContext = m_pRenderContext; return ( pRenderContext ) ? pRenderContext : &m_HardwareRenderContext; } #endif const CMaterialDict * GetMaterialDict() const { return &m_MaterialDict; } CMaterialDict * GetMaterialDict() { return &m_MaterialDict; } virtual void ReloadFilesInList( IFileList *pFilesToReload ); public: //--------------------------------------------------------- // Config management //--------------------------------------------------------- // IMaterialSystem virtual IMaterialSystemHardwareConfig * GetHardwareConfig( const char *pVersion, int *returnCode ); // Get the current config for this video card (as last set by control panel or the default if not) virtual bool UpdateConfig( bool forceUpdate ); virtual bool OverrideConfig( const MaterialSystem_Config_t &config, bool bForceUpdate ); const MaterialSystem_Config_t & GetCurrentConfigForVideoCard() const; // Gets *recommended* configuration information associated with the display card and dxsupport. virtual bool GetRecommendedVideoConfig( KeyValues *pKeyValues ); virtual bool GetRecommendedConfigurationInfo( int nDXLevel, KeyValues * pKeyValues ); // IShaderUtil MaterialSystem_Config_t & GetConfig(); private: //--------------------------------- // This is called when the config changes void GenerateConfigFromConfigKeyValues( MaterialSystem_Config_t *pConfig, bool bOverwriteCommandLineValues ); // Read/write config into convars void ReadConfigFromConVars( MaterialSystem_Config_t *pConfig ); void WriteConfigIntoConVars( const MaterialSystem_Config_t &config ); public: // ----------------------------------------------------------- // Device methods // ----------------------------------------------------------- int GetDisplayAdapterCount() const; int GetCurrentAdapter() const; void GetDisplayAdapterInfo( int adapter, MaterialAdapterInfo_t& info ) const; int GetModeCount( int adapter ) const; void GetModeInfo( int adapter, int mode, MaterialVideoMode_t& info ) const; void AddModeChangeCallBack( ModeChangeCallbackFunc_t func ); void RemoveModeChangeCallBack( ModeChangeCallbackFunc_t func ); // Returns the mode info for the current display device void GetDisplayMode( MaterialVideoMode_t& info ) const; bool SetMode( void* hwnd, const MaterialSystem_Config_t &config ); // Reports support for a given MSAA mode bool SupportsMSAAMode( int nMSAAMode ); // Reports support for a given CSAA mode bool SupportsCSAAMode( int nNumSamples, int nQualityLevel ); bool SupportsHDRMode( HDRType_t nHDRModede ); bool UsesSRGBCorrectBlending() const; // Shadow depth bias factors void SetShadowDepthBiasFactors( float fShadowSlopeScaleDepthBias, float fShadowDepthBias ); void FlipCulling( bool bFlipCulling ); const MaterialSystemHardwareIdentifier_t &GetVideoCardIdentifier() const; // Use this to spew information about the 3D layer void SpewDriverInfo() const; DELEGATE_TO_OBJECT_2VC( GetBackBufferDimensions, int &, int &, g_pShaderDevice ); DELEGATE_TO_OBJECT_0C( ImageFormat, GetBackBufferFormat, g_pShaderDevice ); DELEGATE_TO_OBJECT_0C( const AspectRatioInfo_t &, GetAspectRatioInfo, g_pShaderAPI ); DELEGATE_TO_OBJECT_1V( PushDeformation, DeformationBase_t const *, g_pShaderAPI ); DELEGATE_TO_OBJECT_0V( PopDeformation, g_pShaderAPI ); DELEGATE_TO_OBJECT_0C(int, GetNumActiveDeformations, g_pShaderAPI ); // ----------------------------------------------------------- // Window methods // ----------------------------------------------------------- // Creates/ destroys a child window bool AddView( void* hwnd ); void RemoveView( void* hwnd ); // Sets the view void SetView( void* hwnd ); // ----------------------------------------------------------- // Control flow // ----------------------------------------------------------- void BeginFrame( float frameTime ); void EndFrame(); virtual bool IsInFrame( ) const; void Flush( bool flushHardware = false ); void SwapBuffers(); uint32 GetCurrentFrameCount(); // Flushes managed textures from the texture cacher void EvictManagedResources(); void ReleaseResources(); void ReacquireResources(); // Recomputes a state snapshot void RecomputeAllStateSnapshots(); void NoteAnisotropicLevel( int currentLevel ); // ----------------------------------------------------------- // Device loss/restore // ----------------------------------------------------------- // Installs a function to be called when we need to release vertex buffers void AddReleaseFunc( MaterialBufferReleaseFunc_t func ); void RemoveReleaseFunc( MaterialBufferReleaseFunc_t func ); // Installs a function to be called when we need to restore vertex buffers void AddRestoreFunc( MaterialBufferRestoreFunc_t func ); void RemoveRestoreFunc( MaterialBufferRestoreFunc_t func ); // Called by the shader API when it's just about to lose video memory void ReleaseShaderObjects( int nChangeFlags ); void RestoreShaderObjects( CreateInterfaceFn shaderFactory, int nChangeFlags = 0 ); // Installs a function to be called when we need to delete objects at the end of the render frame virtual void AddEndFrameCleanupFunc( EndFrameCleanupFunc_t func ); virtual void RemoveEndFrameCleanupFunc( EndFrameCleanupFunc_t func ); // Gets called when the level is shuts down, will call the registered callback virtual void OnLevelShutdown(); // Installs a function to be called when the level is shuts down virtual bool AddOnLevelShutdownFunc( OnLevelShutdownFunc_t func, void * pUserData ); virtual bool RemoveOnLevelShutdownFunc( OnLevelShutdownFunc_t func, void * pUserData ); // Installs a function to be called when we need to perform operation before next rendering context is started virtual void AddEndFramePriorToNextContextFunc( EndFramePriorToNextContextFunc_t func ); virtual void RemoveEndFramePriorToNextContextFunc( EndFramePriorToNextContextFunc_t func ); virtual void OnLevelLoadingComplete(); // Release temporary HW memory... void ResetTempHWMemory( bool bExitingLevel = false ); // For dealing with device lost in cases where SwapBuffers isn't called all the time (Hammer) void HandleDeviceLost(); // ----------------------------------------------------------- // Shaders // ----------------------------------------------------------- int ShaderCount() const; int GetShaders( int nFirstShader, int nCount, IShader **ppShaderList ) const; int ShaderFlagCount() const; const char * ShaderFlagName( int nIndex ) const; void GetShaderFallback( const char *pShaderName, char *pFallbackShader, int nFallbackLength ); // ----------------------------------------------------------- // Material proxies // ----------------------------------------------------------- IMaterialProxyFactory* GetMaterialProxyFactory(); void SetMaterialProxyFactory( IMaterialProxyFactory* pFactory ); IClientMaterialSystem* GetClientMaterialSystemInterface(); // ----------------------------------------------------------- // Refresh the spinner on load screens // ----------------------------------------------------------- void RefreshFrontBufferNonInteractive(); virtual uint32 GetFrameTimestamps( ApplicationPerformanceCountersInfo_t &apci, ApplicationInstantCountersInfo_t & aici ); bool CanDownloadTextures() const; // ----------------------------------------------------------- // Editor mode // ----------------------------------------------------------- bool InEditorMode() const; // Used to enable editor materials. Must be called before Init. void EnableEditorMaterials(); void EnableGBuffers( void ); // Can we use editor materials? bool CanUseEditorMaterials( void ) const; int GetConfigurationFlags( void ) const; // ----------------------------------------------------------- // Stub mode mode // ----------------------------------------------------------- void SetInStubMode( bool bInStubMode ); bool IsInStubMode(); //--------------------------------------------------------- // Image formats //--------------------------------------------------------- ImageFormatInfo_t const& ImageFormatInfo( ImageFormat fmt) const; int GetMemRequired( int width, int height, int depth, ImageFormat format, bool mipmap ); bool ConvertImageFormat( unsigned char *src, enum ImageFormat srcImageFormat, unsigned char *dst, enum ImageFormat dstImageFormat, int width, int height, int srcStride = 0, int dstStride = 0 ); //--------------------------------------------------------- // Debug support //--------------------------------------------------------- void CreateDebugMaterials(); void CleanUpDebugMaterials(); void CleanUpErrorMaterial(); void DebugPrintUsedMaterials( const char *pSearchSubString, bool bVerbose ); void DebugPrintUsedTextures(); void ToggleSuppressMaterial( const char* pMaterialName ); void ToggleDebugMaterial( const char* pMaterialName ); //--------------------------------------------------------- // Misc features //--------------------------------------------------------- //returns whether fast clipping is being used or not - needed to be exposed for better per-object clip behavior bool UsingFastClipping(); int StencilBufferBits(); //--------------------------------------------------------- // Standard material and textures //--------------------------------------------------------- void AllocateStandardTextures(); void ReleaseStandardTextures(); IMaterialInternal * GetDrawFlatMaterial() { return m_pDrawFlatMaterial; } IMaterialInternal * GetBufferClearObeyStencil( int i ) { return m_pBufferClearObeyStencil[i]; } IMaterialInternal * GetReloadZcullMaterial() { return m_pReloadZcullMaterial; } IMaterialInternal * GetRenderTargetBlitMaterial() { return m_pRenderTargetBlitMaterial; } ShaderAPITextureHandle_t GetFullbrightLightmapTextureHandle() const { return m_FullbrightLightmapTextureHandle; } ShaderAPITextureHandle_t GetFullbrightBumpedLightmapTextureHandle() const { return m_FullbrightBumpedLightmapTextureHandle; } ShaderAPITextureHandle_t GetBlackTextureHandle() const { return m_BlackTextureHandle; } ShaderAPITextureHandle_t GetBlackAlphaZeroTextureHandle() const { return m_BlackAlphaZeroTextureHandle; } ShaderAPITextureHandle_t GetFlatNormalTextureHandle() const { return m_FlatNormalTextureHandle; } ShaderAPITextureHandle_t GetFlatSSBumpTextureHandle() const { return m_FlatSSBumpTextureHandle; } ShaderAPITextureHandle_t GetGreyTextureHandle() const { return m_GreyTextureHandle; } ShaderAPITextureHandle_t GetGreyAlphaZeroTextureHandle() const { return m_GreyAlphaZeroTextureHandle; } ShaderAPITextureHandle_t GetWhiteTextureHandle() const { return m_WhiteTextureHandle; } ShaderAPITextureHandle_t GetLinearToGammaTableTextureHandle() const { return m_LinearToGammaTableTextureHandle; } ShaderAPITextureHandle_t GetLinearToGammaIdentityTableTextureHandle() const { return m_LinearToGammaIdentityTableTextureHandle; } ShaderAPITextureHandle_t GetMaxDepthTextureHandle() const { return m_MaxDepthTextureHandle; } //--------------------------------------------------------- // Material and texture management //--------------------------------------------------------- void UncacheAllMaterials(); void UncacheUnusedMaterials( bool bRecomputeStateSnapshots ); void CacheUsedMaterials(); void ReloadTextures(); void ReloadMaterials( const char *pSubString = NULL ); // Create new materials IMaterial * CreateMaterial( const char *pMaterialName, KeyValues *pVMTKeyValues ); IMaterial * FindMaterial( const char *materialName, const char *pTextureGroupName, bool complain = true, const char *pComplainPrefix = NULL ); virtual IMaterial * FindProceduralMaterial( const char *pMaterialName, const char *pTextureGroupName, KeyValues *pVMTKeyValues = NULL ); const char * GetForcedTextureLoadPathID() { return m_pForcedTextureLoadPathID; } bool LoadKeyValuesFromVMTFile( KeyValues &vmtKeyValues, const char *pMaterialName, bool bUsesUNCFilename ); //--------------------------------- DELEGATE_TO_OBJECT_0C( MaterialHandle_t, FirstMaterial, &m_MaterialDict ); DELEGATE_TO_OBJECT_1C( MaterialHandle_t, NextMaterial, MaterialHandle_t, &m_MaterialDict ); DELEGATE_TO_OBJECT_0C( MaterialHandle_t, InvalidMaterial, &m_MaterialDict ); DELEGATE_TO_OBJECT_1C( IMaterial *, GetMaterial, MaterialHandle_t, &m_MaterialDict ); DELEGATE_TO_OBJECT_1C( IMaterialInternal *, GetMaterialInternal, MaterialHandle_t, &m_MaterialDict ); DELEGATE_TO_OBJECT_0C( int, GetNumMaterials, &m_MaterialDict ); DELEGATE_TO_OBJECT_1V( AddMaterialToMaterialList, IMaterialInternal *, &m_MaterialDict ); DELEGATE_TO_OBJECT_1V( RemoveMaterial, IMaterialInternal *, &m_MaterialDict ); DELEGATE_TO_OBJECT_1V( RemoveMaterialSubRect, IMaterialInternal *, &m_MaterialDict ); //--------------------------------- ITexture * FindTexture( const char* pTextureName, const char *pTextureGroupName, bool complain = true, int nAdditionalCreationFlags = 0 ); bool IsTextureLoaded( const char* pTextureName ) const; bool GetTextureInformation( char const *szTextureName, MaterialTextureInfo_t &info ) const; void AddTextureAlias( const char *pAlias, const char *pRealName ); void RemoveTextureAlias( const char *pAlias ); void SetExcludedTextures( const char *pScriptName, bool bUsingWeaponModelCache ); void UpdateExcludedTextures( void ); void ClearForceExcludes( void ); // Creates a procedural texture ITexture * CreateProceduralTexture( const char *pTextureName, const char *pTextureGroupName, int w, int h, ImageFormat fmt, int nFlags ); virtual ICustomMaterialManager *GetCustomMaterialManager(); virtual ICompositeTextureGenerator *GetCompositeTextureGenerator(); #if defined( _X360 ) // Create a texture for displaying gamerpics. // This function allocates the texture in the correct gamerpic format, but it does not fill in the gamerpic data. virtual ITexture * CreateGamerpicTexture( const char *pTextureName, const char *pTextureGroupName, int nFlags ); // Update the given texture with the player gamerpic for the local player at the given index. // Note: this texture must be the correct size and format. Use CreateGamerpicTexture. virtual bool UpdateLocalGamerpicTexture( ITexture *pTexture, DWORD userIndex ); // Update the given texture with a remote player's gamerpic. // Note: this texture must be the correct size and format. Use CreateGamerpicTexture. virtual bool UpdateRemoteGamerpicTexture( ITexture *pTexture, XUID xuid ); #endif // _X360 // // Render targets // void BeginRenderTargetAllocation(); void EndRenderTargetAllocation(); // Simulate an Alt-Tab in here, which causes a release/restore of all resources void FinishRenderTargetAllocation( void ); void ReEnableRenderTargetAllocation_IRealizeIfICallThisAllTexturesWillBeUnloadedAndLoadTimeWillSufferHorribly( void ); // Creates a texture for use as a render target ITexture * CreateRenderTargetTexture( int w, int h, RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). ImageFormat format, MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED ); ITexture * CreateNamedRenderTargetTextureEx( const char *pRTName, // Pass in NULL here for an unnamed render target. int w, int h, RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). ImageFormat format, MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, unsigned int renderTargetFlags = 0 ); ITexture * CreateNamedRenderTargetTexture( const char *pRTName, int w, int h, RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). ImageFormat format, MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, bool bClampTexCoords = true, bool bAutoMipMap = false ); ITexture * CreateNamedRenderTargetTextureEx2( const char *pRTName, // Pass in NULL here for an unnamed render target. int w, int h, RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). ImageFormat format, MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, unsigned int renderTargetFlags = 0 ); ITexture * CreateNamedMultiRenderTargetTexture( const char *pRTName, // Pass in NULL here for an unnamed render target. int w, int h, RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). ImageFormat format, MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, unsigned int renderTargetFlags = 0 ); // ----------------------------------------------------------- bool OnDrawMesh( IMesh *pMesh, int firstIndex, int numIndices ); bool OnDrawMesh( IMesh *pMesh, CPrimList *pLists, int nLists ); bool OnDrawMeshModulated( IMesh *pMesh, const Vector4D &diffuseModulation, int firstIndex, int numIndices ); DELEGATE_TO_OBJECT_3( bool, OnSetFlexMesh, IMesh *, IMesh *, int, GetRenderContextInternal() ); DELEGATE_TO_OBJECT_3( bool, OnSetColorMesh, IMesh *, IMesh *, int, GetRenderContextInternal() ); DELEGATE_TO_OBJECT_2( bool, OnSetPrimitiveType, IMesh *, MaterialPrimitiveType_t, GetRenderContextInternal() ); DELEGATE_TO_OBJECT_0V( SyncMatrices, GetRenderContextInternal() ); DELEGATE_TO_OBJECT_1V( SyncMatrix, MaterialMatrixMode_t, GetRenderContextInternal() ); void OnThreadEvent( uint32 threadEvent ); DELEGATE_TO_OBJECT_1( ShaderAPITextureHandle_t, GetLightmapTexture, ShaderAPITextureHandle_t, GetRenderContextInternal() ); DELEGATE_TO_OBJECT_1( ShaderAPITextureHandle_t, GetPaintmapTexture, ShaderAPITextureHandle_t, GetRenderContextInternal() ); // ----------------------------------------------------------- // Lightmaps delegates // ----------------------------------------------------------- DELEGATE_TO_OBJECT_0V( BeginLightmapAllocation, &m_Lightmaps ); void EndLightmapAllocation() { GetLightmaps()->EndLightmapAllocation(); AllocateStandardTextures(); } void CleanupLightmaps() { GetLightmaps()->CleanupLightmaps(); } DELEGATE_TO_OBJECT_4( int, AllocateLightmap, int, int, LightmapOffset_t, IMaterial *, &m_Lightmaps ); DELEGATE_TO_OBJECT_1( int, AllocateWhiteLightmap, IMaterial *, &m_Lightmaps ); DELEGATE_TO_OBJECT_3( int, AllocateDynamicLightmap, LightmapOffset_t, int *, int, &m_Lightmaps ); void UpdateLightmap( int, LightmapOffset_t, LightmapOffset_t, float *, float *, float *, float * ); DELEGATE_TO_OBJECT_0( int, GetNumSortIDs, &m_Lightmaps ); DELEGATE_TO_OBJECT_1V( GetSortInfo, MaterialSystem_SortInfo_t *, &m_Lightmaps ); DELEGATE_TO_OBJECT_3VC( GetLightmapPageSize, int, int *, int *, &m_Lightmaps ); DELEGATE_TO_OBJECT_0V( ResetMaterialLightmapPageInfo, &m_Lightmaps ); DELEGATE_TO_OBJECT_0C( int, GetNumLightmapPages, &m_Lightmaps ); DELEGATE_TO_OBJECT_1C( int, GetLightmapWidth, int, &m_Lightmaps ); DELEGATE_TO_OBJECT_1C( int, GetLightmapHeight, int, &m_Lightmaps ); DELEGATE_TO_OBJECT_0V( BeginUpdateLightmaps, &m_Lightmaps ); DELEGATE_TO_OBJECT_0V( EndUpdateLightmaps, &m_Lightmaps ); // ----------------------------------------------------------- // Paint map delegates // ----------------------------------------------------------- DELEGATE_TO_OBJECT_1( void, RegisterPaintmapDataManager, IPaintmapDataManager *, &m_Paintmaps ); DELEGATE_TO_OBJECT_0V( BeginUpdatePaintmaps, &m_Paintmaps ); DELEGATE_TO_OBJECT_0V( EndUpdatePaintmaps, &m_Paintmaps ); void UpdatePaintmap( int paintmap, BYTE* pPaintData, int numRects, Rect_t* pRects ); // ----------------------------------------------------------- // Stereo // ----------------------------------------------------------- bool IsStereoSupported(); bool IsStereoActiveThisFrame() const; void NVStereoUpdate(); bool m_bStereoBoolsInitialized; bool m_bIsStereoSupported; bool m_bIsStereoActiveThisFrame; // ----------------------------------------------------------- // Render context delegates // ----------------------------------------------------------- // IMaterialSystem DELEGATE_TO_OBJECT_3V( ClearBuffers, bool, bool, bool, GetRenderContextInternal() ); // IMaterialSystemInternal DELEGATE_TO_OBJECT_0( IMaterial *, GetCurrentMaterial, GetRenderContextInternal() ); DELEGATE_TO_OBJECT_0( int, GetLightmapPage, GetRenderContextInternal() ); DELEGATE_TO_OBJECT_0( ITexture *, GetLocalCubemap, GetRenderContextInternal() ); DELEGATE_TO_OBJECT_1V( ForceDepthFuncEquals, bool, GetRenderContextInternal() ); DELEGATE_TO_OBJECT_0( MaterialHeightClipMode_t, GetHeightClipMode, GetRenderContextInternal() ); DELEGATE_TO_OBJECT_0C( bool, InFlashlightMode, GetRenderContextInternal() ); DELEGATE_TO_OBJECT_0C( bool, IsRenderingPaint, GetRenderContextInternal() ); DELEGATE_TO_OBJECT_0C( bool, IsCascadedShadowMapping, GetRenderContextInternal() ); // IShaderUtil DELEGATE_TO_OBJECT_3V( BindStandardTexture, Sampler_t, TextureBindFlags_t, StandardTextureId_t, &m_HardwareRenderContext ); DELEGATE_TO_OBJECT_1( ShaderAPITextureHandle_t, GetStandardTexture, StandardTextureId_t, &m_HardwareRenderContext ); DELEGATE_TO_OBJECT_2V( BindStandardVertexTexture, VertexTextureSampler_t, StandardTextureId_t, &m_HardwareRenderContext ); DELEGATE_TO_OBJECT_2V( GetLightmapDimensions, int *, int *, &m_HardwareRenderContext ); DELEGATE_TO_OBJECT_3V( GetStandardTextureDimensions, int *, int *, StandardTextureId_t, &m_HardwareRenderContext ); DELEGATE_TO_OBJECT_0( float, GetSubDHeight, &m_HardwareRenderContext ); DELEGATE_TO_OBJECT_0( MorphFormat_t, GetBoundMorphFormat, &m_HardwareRenderContext ); DELEGATE_TO_OBJECT_1( ITexture *, GetRenderTargetEx, int, &m_HardwareRenderContext ); DELEGATE_TO_OBJECT_7V( DrawClearBufferQuad, unsigned char, unsigned char, unsigned char, unsigned char, bool, bool, bool, &m_HardwareRenderContext ); #if defined( _PS3 ) DELEGATE_TO_OBJECT_0V( DrawReloadZcullQuad, &m_HardwareRenderContext ); #endif // _PS3 DELEGATE_TO_OBJECT_0C( int, MaxHWMorphBatchCount, g_pMorphMgr ); DELEGATE_TO_OBJECT_1V( GetCurrentColorCorrection, ShaderColorCorrectionInfo_t*, g_pColorCorrectionSystem ); virtual ShaderAPITextureHandle_t GetShaderAPITextureBindHandle( ITexture *pTexture, int nFrameVar, int nTextureChannel = 0 ); #if defined( _X360 ) void ListUsedMaterials(); HXUIFONT OpenTrueTypeFont( const char *pFontname, int tall, int style ); void CloseTrueTypeFont( HXUIFONT hFont ); bool GetTrueTypeFontMetrics( HXUIFONT hFont, wchar_t wchFirst, wchar_t wchLast, XUIFontMetrics *pFontMetrics, XUICharMetrics *pCharMetrics ); // Render a sequence of characters and extract the data into a buffer // For each character, provide the width+height of the font texture subrect, // an offset to apply when rendering the glyph, and an offset into a buffer to receive the RGBA data bool GetTrueTypeGlyphs( HXUIFONT hFont, int numChars, wchar_t *pWch, int *pOffsetX, int *pOffsetY, int *pWidth, int *pHeight, unsigned char *pRGBA, int *pOffset ); void ReadBackBuffer( Rect_t *pSrcRect, Rect_t *pDstRect, unsigned char *pData, ImageFormat dstFormat, int nDstStride ); void PersistDisplay(); void *GetD3DDevice(); bool OwnGPUResources( bool bEnable ); #elif defined( _PS3 ) void ListUsedMaterials(); virtual HPS3FONT OpenTrueTypeFont( const char *pFontname, int tall, int style ); virtual void CloseTrueTypeFont( HPS3FONT hFont ); virtual bool GetTrueTypeFontMetrics( HPS3FONT hFont, int nFallbackTall, wchar_t wchFirst, wchar_t wchLast, CPS3FontMetrics *pFontMetrics, CPS3CharMetrics *pCharMetrics ); // Render a sequence of characters and extract the data into a buffer // For each character, provide the width+height of the font texture subrect, // an offset to apply when rendering the glyph, and an offset into a buffer to receive the RGBA data virtual bool GetTrueTypeGlyphs( HPS3FONT hFont, int nFallbackTall, int numChars, wchar_t *pWch, int *pOffsetX, int *pOffsetY, int *pWidth, int *pHeight, unsigned char *pRGBA, int *pRGBAOffset ); virtual void TransmitScreenshotToVX(); virtual void CompactRsxLocalMemory( char const *szReason ); virtual void SetFlipPresentFrequency( int nNumVBlanks ); static void RunQMS(void* cmat, void* ptr) { ((CMaterialSystem*)cmat)->ThreadExecuteQueuedContext((CMatQueuedRenderContext *)ptr); } #endif virtual void SpinPresent( uint nFrames ); MaterialLock_t Lock(); void Unlock( MaterialLock_t ); CMatCallQueue * GetRenderCallQueue(); uint GetRenderThreadId() const { return m_nRenderThreadID; } void UnbindMaterial( IMaterial *pMaterial ); virtual void CompactMemory(); // Get stats on GPU memory usage virtual void GetGPUMemoryStats( GPUMemoryStats &stats ); bool IsLevelLoadingComplete() const; void OnAsyncTextureDataComplete( AsyncTextureContext_t *pContext, void *pData, int nNumReadBytes, AsyncTextureLoadError_t loadError ); // ----------------------------------------------------------- private: CON_COMMAND_MEMBER_F( CMaterialSystem, "mat_showmaterials", DebugPrintUsedMaterials, "Show materials.", 0 ); CON_COMMAND_MEMBER_F( CMaterialSystem, "mat_showmaterialsverbose", DebugPrintUsedMaterialsVerbose, "Show materials (verbose version).", 0 ); CON_COMMAND_MEMBER_F( CMaterialSystem, "mat_showtextures", DebugPrintUsedTextures, "Show used textures.", 0 ); CON_COMMAND_MEMBER_F( CMaterialSystem, "mat_reloadallmaterials", ReloadAllMaterials, "Reloads all materials", FCVAR_CHEAT ); CON_COMMAND_MEMBER_F( CMaterialSystem, "mat_reloadmaterial", ReloadMaterials, "Reloads a single material", FCVAR_CHEAT ); CON_COMMAND_MEMBER_F( CMaterialSystem, "mat_reloadtextures", ReloadTextures, "Reloads all textures", FCVAR_CHEAT ); CON_COMMAND_MEMBER_F( CMaterialSystem, "mat_showaspectratioinfo", DebugPrintAspectRatioInfo, "Spew info about the hardware aspect ratio", FCVAR_DEVELOPMENTONLY ); #if defined( _X360 ) || defined(_PS3) CON_COMMAND_MEMBER_F( CMaterialSystem, "mat_material_list", ListUsedMaterials, "Show used textures.", 0 ); #endif friend void* InstantiateMaterialSystemV76Interface(); friend CMaterialSystem *CMatLightmaps::GetMaterialSystem() const; friend CMaterialSystem *CMatPaintmaps::GetMaterialSystem() const; void ThreadExecuteQueuedContext( CMatQueuedRenderContext *pContext ); IThreadPool * CreateMatQueueThreadPool(); void DestroyMatQueueThreadPool(); #if defined( DX_TO_GL_ABSTRACTION ) && !defined( _GAMECONSOLE ) void DoStartupShaderPreloading( void ); #endif void ServiceAsyncTextureLoads(); void ServiceEndFramePriorToNextContext(); // ----------------------------------------------------------- CMaterialDict m_MaterialDict; CMatLightmaps m_Lightmaps; CMatPaintmaps m_Paintmaps; #if defined(_X360) static IMatRenderContextInternal *CMaterialSystem::m_pRenderContexts[2]; #elif !defined(_PS3) static CTHREADLOCALPTR(IMatRenderContextInternal) m_pRenderContext; #endif CMatRenderContext m_HardwareRenderContext; CMatQueuedRenderContext m_QueuedRenderContexts[2]; int m_iCurQueuedContext; MaterialThreadMode_t m_ThreadMode; MaterialThreadMode_t m_IdealThreadMode; int m_nServiceThread; //--------------------------------- char * m_pShaderDLL; CSysModule * m_ShaderHInst; // Used to dynamically load the shader DLL CreateInterfaceFn m_ShaderAPIFactory; int m_nAdapter; int m_nAdapterFlags; int m_nConfigurationFlags; // MATCONFIG_FLAGS_xxxx ShaderDisplayMode_t m_nAdapterInfo; //--------------------------------- IMaterialProxyFactory * m_pMaterialProxyFactory; IClientMaterialSystem * m_pClientMaterialSystemInterface; //--------------------------------- // Callback methods for releasing + restoring video memory CUtlVector< MaterialBufferReleaseFunc_t > m_ReleaseFunc; CUtlVector< MaterialBufferRestoreFunc_t > m_RestoreFunc; CUtlVector< EndFrameCleanupFunc_t > m_EndFrameCleanupFunc; class COnLevelShutdownFunc { public: COnLevelShutdownFunc( OnLevelShutdownFunc_t func, void * pUserData ) : m_Func(func), m_pUserData(pUserData) { // Do nothing... Is there a CUtlPair class or something like that? } bool operator==(const COnLevelShutdownFunc & other) const { return ( (m_Func == other.m_Func) && (m_pUserData == other.m_pUserData) ); } OnLevelShutdownFunc_t m_Func; void * m_pUserData; }; CUtlVector< COnLevelShutdownFunc > m_OnLevelShutdownFuncs; CUtlVector< EndFramePriorToNextContextFunc_t > m_EndFramePriorToNextContextFunc; //--------------------------------- bool m_bRequestedEditorMaterials; bool m_bRequestedGBuffers; //--------------------------------- // Store texids for various things ShaderAPITextureHandle_t m_FullbrightLightmapTextureHandle; ShaderAPITextureHandle_t m_FullbrightBumpedLightmapTextureHandle; ShaderAPITextureHandle_t m_BlackTextureHandle; ShaderAPITextureHandle_t m_BlackAlphaZeroTextureHandle; ShaderAPITextureHandle_t m_FlatNormalTextureHandle; ShaderAPITextureHandle_t m_FlatSSBumpTextureHandle; ShaderAPITextureHandle_t m_GreyTextureHandle; ShaderAPITextureHandle_t m_GreyAlphaZeroTextureHandle; ShaderAPITextureHandle_t m_WhiteTextureHandle; ShaderAPITextureHandle_t m_LinearToGammaTableTextureHandle; //linear to gamma srgb conversion lookup for the current hardware ShaderAPITextureHandle_t m_LinearToGammaIdentityTableTextureHandle; //An identity lookup for when srgb writes are off ShaderAPITextureHandle_t m_MaxDepthTextureHandle; //a 1x1 texture with maximum depth values. // Have we allocated the standard lightmaps? bool m_StandardTexturesAllocated; // Do we need to restore mananged resources next time RestoreShaderObjects is called bool m_bRestoreManangedResources; // Deferred material reload ( so we don't call it when ALT-TABd bool m_bDeferredMaterialReload; char *m_pSubString; // allocated substring for deferred material reload //--------------------------------- // Shared materials used for debugging.... //--------------------------------- enum BufferClearType_t //bClearColor + ( bClearAlpha << 1 ) + ( bClearDepth << 2 ) { BUFFER_CLEAR_NONE, BUFFER_CLEAR_COLOR, BUFFER_CLEAR_ALPHA, BUFFER_CLEAR_COLOR_AND_ALPHA, BUFFER_CLEAR_DEPTH, BUFFER_CLEAR_COLOR_AND_DEPTH, BUFFER_CLEAR_ALPHA_AND_DEPTH, BUFFER_CLEAR_COLOR_AND_ALPHA_AND_DEPTH, BUFFER_CLEAR_TYPE_COUNT }; IMaterialInternal * m_pBufferClearObeyStencil[BUFFER_CLEAR_TYPE_COUNT]; IMaterialInternal * m_pReloadZcullMaterial; IMaterialInternal * m_pDrawFlatMaterial; IMaterialInternal * m_pRenderTargetBlitMaterial; IMaterialInternal * m_pBIKPreloadMaterial; // PORTAL2 - a dummy material which is used to ensure that the (~2 KB) bink shaders are always loaded //--------------------------------- const char * m_pForcedTextureLoadPathID; uint m_nRenderThreadID; // nesting counter for render target allocation int m_nAllocatingRenderTargets; bool m_bDisableRenderTargetAllocationForever; bool m_bInStubMode; bool m_bGeneratedConfig; bool m_bInFrame; bool m_bForcedSingleThreaded; bool m_bAllowQueuedRendering; bool m_bThreadHasOwnership; bool m_bLevelLoadingComplete; CTSQueue< AsyncTextureLoad_t > m_QueuedAsyncTextureLoads; AsyncTextureLoad_t m_AsyncTextureLoad; AsyncTextureLoad_t * m_pActiveAsyncTextureLoad; //--------------------------------- CCustomMaterialManager m_CustomMaterialManager; CCompositeTextureGenerator m_CompositeTextureGenerator; #ifdef DX_TO_GL_ABSTRACTION uint m_ThreadOwnershipID; #endif #ifndef _PS3 CJob * m_pActiveAsyncJob; #else bool m_bQMSJobSubmitted; #endif CUtlVector m_threadEvents; IThreadPool * m_pMatQueueThreadPool; #if defined(_PS3) // some PS3-specific font info (hey, it was either do this or have a pointer to a pimpl struct) CUtlVector< HPS3FONT > m_vExtantFonts; // used to catch leaks -- can't store a vector of the CellFonts directly bc the handle is a pointer and can't store pointers into a vector void InitializePS3Fonts(); enum { kPS3_DEFAULT_MAX_USER_FONTS = 256 }; public: virtual bool PS3InitFontLibrary( unsigned fontFileCacheSizeInBytes, unsigned maxNumFonts ); virtual void PS3DumpFontLibrary(); virtual void *PS3GetFontLibPtr(); protected: #else inline void InitializePS3Fonts(){}; #endif }; //----------------------------------------------------------------------------- inline CMaterialSystem *CMatLightmaps::GetMaterialSystem() const { return GET_OUTER( CMaterialSystem, m_Lightmaps ); } inline CMaterialSystem *CMatPaintmaps::GetMaterialSystem() const { return GET_OUTER( CMaterialSystem, m_Paintmaps ); } //----------------------------------------------------------------------------- #endif // CMATERIALSYSTEM_H