gfxDevice.cpp

Engine/source/gfx/gfxDevice.cpp

More...

Classes:

Public Variables

Public Functions

DefineEngineFunction(clearGFXResourceFlags , void , () , "Clears the flagged state on all allocated <a href="/coding/file/gfxdevice_8h/#gfxdevice_8h_1afd23debb5edac4f53e564f02e6964c62">GFX</a> resources. " "See flagCurrentGFXResources <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> usage <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">details.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" "@see flagCurrentGFXResources, listGFXResources , describeGFXResources" )
DefineEngineFunction(describeGFXResources , void , (const char *resourceTypes, const char *filePath, bool unflaggedOnly) , (false) , "@brief Dumps <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> description of <a href="/coding/file/gfxdevice_8h/#gfxdevice_8h_1afd23debb5edac4f53e564f02e6964c62">GFX</a> resources <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> or the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n</a>" "@param resourceTypes A space seperated list of resource types or an empty string <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> all <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">resources.\n</a>" "@param filePath A <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> dump the list <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> or an empty string <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> write <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n</a>" "@param unflaggedOnly If true only unflagged resources are dumped. See <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">flagCurrentGFXResources.\n</a>" "@note The resource types can be one or more of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">following:\n\n</a>" " - <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">texture\n</a>" " - texture <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">target\n</a>" " - window <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">target\n</a>" " - vertex <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">buffers\n</a>" " - primitive <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">buffers\n</a>" " - <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">fences\n</a>" " - <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">cubemaps\n</a>" " - <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">shaders\n</a>" " - <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stateblocks\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )
DefineEngineFunction(describeGFXStateBlocks , void , (const char *filePath) , "Dumps <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> description of all state <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">blocks.\n</a>" "@param filePath A <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> dump the state blocks <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> or an empty string <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> write <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )
DefineEngineFunction(flagCurrentGFXResources , void , () , "@brief Flags all currently allocated <a href="/coding/file/gfxdevice_8h/#gfxdevice_8h_1afd23debb5edac4f53e564f02e6964c62">GFX</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">resources.\n</a>" "Used <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> resource allocation and leak tracking by flagging " "current resources then dumping <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> list of unflagged resources " "at some later point in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">execution.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" "@see listGFXResources, clearGFXResourceFlags , describeGFXResources" )
DefineEngineFunction(getBestHDRFormat , GFXFormat , () , "Returns the best texture format <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> storage of HDR data <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the active <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">device.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )
DefineEngineFunction(getDisplayDeviceInformation , const char * , () , "Get the string describing the active <a href="/coding/file/gfxdevice_8h/#gfxdevice_8h_1afd23debb5edac4f53e564f02e6964c62">GFX</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">device.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )
DefineEngineFunction(getDisplayDeviceList , String , () , "Returns <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> tab-seperated string of the detected devices across all <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">adapters.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )
DefineEngineFunction(getDisplayDeviceType , GFXAdapterType , () , "Get the string describing the active <a href="/coding/file/gfxdevice_8h/#gfxdevice_8h_1afd23debb5edac4f53e564f02e6964c62">GFX</a> device <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">type.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )
DefineEngineFunction(getPixelShaderVersion , F32 , () , "Returns the pixel shader version <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the active <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">device.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )
DefineEngineFunction(listGFXResources , void , (bool unflaggedOnly) , (false) , "Returns <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> list of the unflagged <a href="/coding/file/gfxdevice_8h/#gfxdevice_8h_1afd23debb5edac4f53e564f02e6964c62">GFX</a> resources. See flagCurrentGFXResources <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> usage <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">details.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" "@see flagCurrentGFXResources, clearGFXResourceFlags , describeGFXResources" )
DefineEngineFunction(ResetGFX , void , () , "forces the gbuffer <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be reinitialized in cases of improper/lack of buffer clears." )
DefineEngineFunction(setPixelShaderVersion , void , (F32 version) , "@brief Sets the pixel shader version <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the active <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">device.\n</a>" "This can be used <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> force <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> lower pixel shader version than is supported by " "the device <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> testing or performance <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">optimization.\n</a>" "@param version The floating point shader version <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">number.\n</a>" "@note This will only affect shaders/materials created after the call " "and should be used before the game <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">begins.\n</a>" "@see $<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pref::Video::forcedPixVersion\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )

Detailed Description

Public Variables

bool gDisassembleAllShaders 

Public Functions

DefineEngineFunction(clearGFXResourceFlags , void , () , "Clears the flagged state on all allocated <a href="/coding/file/gfxdevice_8h/#gfxdevice_8h_1afd23debb5edac4f53e564f02e6964c62">GFX</a> resources. " "See flagCurrentGFXResources <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> usage <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">details.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" "@see flagCurrentGFXResources, listGFXResources , describeGFXResources" )

DefineEngineFunction(describeGFXResources , void , (const char *resourceTypes, const char *filePath, bool unflaggedOnly) , (false) , "@brief Dumps <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> description of <a href="/coding/file/gfxdevice_8h/#gfxdevice_8h_1afd23debb5edac4f53e564f02e6964c62">GFX</a> resources <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> or the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n</a>" "@param resourceTypes A space seperated list of resource types or an empty string <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> all <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">resources.\n</a>" "@param filePath A <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> dump the list <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> or an empty string <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> write <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n</a>" "@param unflaggedOnly If true only unflagged resources are dumped. See <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">flagCurrentGFXResources.\n</a>" "@note The resource types can be one or more of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">following:\n\n</a>" " - <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">texture\n</a>" " - texture <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">target\n</a>" " - window <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">target\n</a>" " - vertex <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">buffers\n</a>" " - primitive <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">buffers\n</a>" " - <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">fences\n</a>" " - <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">cubemaps\n</a>" " - <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">shaders\n</a>" " - <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">stateblocks\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )

DefineEngineFunction(describeGFXStateBlocks , void , (const char *filePath) , "Dumps <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> description of all state <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">blocks.\n</a>" "@param filePath A <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> dump the state blocks <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> or an empty string <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> write <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )

DefineEngineFunction(flagCurrentGFXResources , void , () , "@brief Flags all currently allocated <a href="/coding/file/gfxdevice_8h/#gfxdevice_8h_1afd23debb5edac4f53e564f02e6964c62">GFX</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">resources.\n</a>" "Used <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> resource allocation and leak tracking by flagging " "current resources then dumping <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> list of unflagged resources " "at some later point in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">execution.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" "@see listGFXResources, clearGFXResourceFlags , describeGFXResources" )

DefineEngineFunction(getBestHDRFormat , GFXFormat , () , "Returns the best texture format <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> storage of HDR data <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the active <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">device.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )

DefineEngineFunction(getDisplayDeviceInformation , const char * , () , "Get the string describing the active <a href="/coding/file/gfxdevice_8h/#gfxdevice_8h_1afd23debb5edac4f53e564f02e6964c62">GFX</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">device.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )

DefineEngineFunction(getDisplayDeviceList , String , () , "Returns <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> tab-seperated string of the detected devices across all <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">adapters.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )

DefineEngineFunction(getDisplayDeviceType , GFXAdapterType , () , "Get the string describing the active <a href="/coding/file/gfxdevice_8h/#gfxdevice_8h_1afd23debb5edac4f53e564f02e6964c62">GFX</a> device <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">type.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )

DefineEngineFunction(getPixelShaderVersion , F32 , () , "Returns the pixel shader version <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the active <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">device.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )

DefineEngineFunction(listGFXResources , void , (bool unflaggedOnly) , (false) , "Returns <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> list of the unflagged <a href="/coding/file/gfxdevice_8h/#gfxdevice_8h_1afd23debb5edac4f53e564f02e6964c62">GFX</a> resources. See flagCurrentGFXResources <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> usage <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">details.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" "@see flagCurrentGFXResources, clearGFXResourceFlags , describeGFXResources" )

DefineEngineFunction(ResetGFX , void , () , "forces the gbuffer <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be reinitialized in cases of improper/lack of buffer clears." )

DefineEngineFunction(setPixelShaderVersion , void , (F32 version) , "@brief Sets the pixel shader version <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the active <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">device.\n</a>" "This can be used <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> force <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> lower pixel shader version than is supported by " "the device <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> testing or performance <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">optimization.\n</a>" "@param version The floating point shader version <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">number.\n</a>" "@note This will only affect shaders/materials created after the call " "and should be used before the game <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">begins.\n</a>" "@see $<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pref::Video::forcedPixVersion\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )

   1
   2//-----------------------------------------------------------------------------
   3// Copyright (c) 2012 GarageGames, LLC
   4//
   5// Permission is hereby granted, free of charge, to any person obtaining a copy
   6// of this software and associated documentation files (the "Software"), to
   7// deal in the Software without restriction, including without limitation the
   8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   9// sell copies of the Software, and to permit persons to whom the Software is
  10// furnished to do so, subject to the following conditions:
  11//
  12// The above copyright notice and this permission notice shall be included in
  13// all copies or substantial portions of the Software.
  14//
  15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21// IN THE SOFTWARE.
  22//-----------------------------------------------------------------------------
  23
  24#include "platform/platform.h"
  25#include "gfx/gfxDevice.h"
  26
  27#include "gfx/gfxInit.h"
  28#include "gfx/gfxCubemap.h"
  29#include "gfx/primBuilder.h"
  30#include "gfx/gfxDrawUtil.h"
  31#include "gfx/gfxFence.h"
  32#include "gfx/gfxFontRenderBatcher.h"
  33#include "gfx/gfxPrimitiveBuffer.h"
  34#include "gfx/gfxShader.h"
  35#include "gfx/gfxStateBlock.h"
  36#include "gfx/screenshot.h"
  37#include "gfx/gfxStringEnumTranslate.h"
  38#include "gfx/gfxTextureManager.h"
  39
  40#include "core/frameAllocator.h"
  41#include "core/stream/fileStream.h"
  42#include "core/strings/unicode.h"
  43#include "core/util/journal/process.h"
  44#include "core/util/safeDelete.h"
  45#include "math/util/frustum.h"
  46#include "console/consoleTypes.h"
  47#include "console/engineAPI.h"
  48
  49GFXDevice * GFXDevice::smGFXDevice = NULL;
  50bool GFXDevice::smWireframe = false;
  51bool GFXDevice::smDisableVSync = true;
  52F32 GFXDevice::smForcedPixVersion = -1.0f;
  53bool GFXDevice::smDisableOcclusionQuery = false;
  54bool gDisassembleAllShaders = false;
  55
  56
  57void GFXDevice::initConsole()
  58{
  59   GFXStringEnumTranslate::init();
  60
  61   Con::addVariable( "$gfx::wireframe", TypeBool, &smWireframe,
  62      "Used to toggle wireframe rendering at runtime.\n"
  63      "@ingroup GFX\n" );
  64
  65   Con::addVariable( "$gfx::disassembleAllShaders", TypeBool, &gDisassembleAllShaders,
  66      "On supported devices this will dump shader disassembly to the "
  67      "procedural shader folder.\n"
  68      "@ingroup GFX\n" );
  69
  70   Con::addVariable( "$gfx::disableOcclusionQuery", TypeBool, &smDisableOcclusionQuery,
  71      "Debug helper that disables all hardware occlusion queries causing "
  72      "them to return only the visibile state.\n"
  73      "@ingroup GFX\n" );
  74
  75   Con::addVariable( "$pref::Video::disableVerticalSync", TypeBool, &smDisableVSync,
  76      "Disables vertical sync on the active device.\n"
  77      "@note The video mode must be reset for the change to take affect.\n"
  78      "@ingroup GFX\n" );
  79
  80   Con::addVariable( "$pref::Video::forcedPixVersion", TypeF32, &smForcedPixVersion,
  81      "Will force the shader model if the value is positive and less than the "
  82      "shader model supported by the active device.  Use 0 for fixed function.\n"
  83      "@note The graphics device must be reset for the change to take affect.\n"
  84      "@ingroup GFX\n" );
  85}
  86
  87GFXDevice::DeviceEventSignal& GFXDevice::getDeviceEventSignal()
  88{
  89   static DeviceEventSignal theSignal;
  90   return theSignal;
  91}
  92
  93GFXDevice::GFXDevice() 
  94{    
  95   VECTOR_SET_ASSOCIATION( mVideoModes );
  96   VECTOR_SET_ASSOCIATION( mRTStack );
  97
  98   mWorldStackSize = 0;
  99
 100   mViewMatrix.identity();
 101   mProjectionMatrix.identity();
 102   
 103   for( S32 i = 0; i < GFX_WORLD_STACK_MAX; i++ )
 104      mWorldMatrix[i].identity();
 105   
 106   AssertFatal(smGFXDevice == NULL, "Already a GFXDevice created! Bad!");
 107   smGFXDevice = this;
 108      
 109   // Vertex buffer cache
 110   mCurrVertexDecl = NULL;
 111   mVertexDeclDirty = false;
 112   for ( U32 i=0; i < VERTEX_STREAM_COUNT; i++ )
 113   {
 114      mVertexBufferDirty[i] = false;
 115      mVertexBufferFrequency[i] = 0;
 116      mVertexBufferFrequencyDirty[i] = false;
 117   }
 118
 119   // Primitive buffer cache
 120   mPrimitiveBufferDirty = false;
 121   mTexturesDirty = false;
 122   
 123   // Use of GFX_TEXTURE_STAGE_COUNT in initialization is okay [7/2/2007 Pat]
 124   for(U32 i = 0; i < GFX_TEXTURE_STAGE_COUNT; i++)
 125   {
 126      mTextureDirty[i] = false;
 127      mCurrentTexture[i] = NULL;
 128      mNewTexture[i] = NULL;
 129      mCurrentCubemap[i] = NULL;
 130      mNewCubemap[i] = NULL;
 131      mCurrentCubemapArray[i] = NULL;
 132      mNewTextureArray[i] = NULL;
 133      mCurrentTextureArray[i] = NULL;
 134      mNewCubemapArray[i] = NULL;
 135      mTexType[i] = GFXTDT_Normal;
 136   }
 137
 138   // State block 
 139   mStateBlockDirty = false;
 140   mCurrentStateBlock = NULL;
 141   mNewStateBlock = NULL;
 142
 143   mCurrentShaderConstBuffer = NULL;
 144
 145   // misc
 146   mAllowRender = true;
 147   mCurrentRenderStyle = RS_Standard;
 148   mCurrentStereoTarget = -1;
 149   mStereoHeadTransform = MatrixF(1);
 150   mCanCurrentlyRender = false;
 151   mInitialized = false;
 152   
 153   mRTDirty = false;
 154   mViewport = RectI::Zero;
 155   mViewportDirty = false;
 156
 157   mDeviceSwizzle32 = NULL;
 158   mDeviceSwizzle24 = NULL;
 159
 160   mResourceListHead = NULL;
 161
 162   mCardProfiler = NULL;   
 163
 164   // Initialize our drawing utility.
 165   mDrawer = NULL;
 166   mFrameTime = PlatformTimer::create();
 167   // Add a few system wide shader macros.
 168   GFXShader::addGlobalMacro( "TORQUE", "1" );
 169   GFXShader::addGlobalMacro( "TORQUE_VERSION", String::ToString(getVersionNumber()) );
 170   #if defined TORQUE_OS_WIN
 171      GFXShader::addGlobalMacro( "TORQUE_OS_WIN" );
 172   #elif defined TORQUE_OS_MAC
 173      GFXShader::addGlobalMacro( "TORQUE_OS_MAC" );
 174   #elif defined TORQUE_OS_LINUX
 175      GFXShader::addGlobalMacro( "TORQUE_OS_LINUX" );      
 176   #endif
 177
 178   mStereoTargets[0] = NULL;
 179   mStereoTargets[1] = NULL;
 180}
 181
 182GFXDrawUtil* GFXDevice::getDrawUtil()
 183{
 184   if (!mDrawer)
 185   {
 186      mDrawer = new GFXDrawUtil(this);
 187   }
 188   return mDrawer;
 189}
 190
 191void GFXDevice::deviceInited()
 192{
 193   getDeviceEventSignal().trigger(deInit);
 194   mDeviceStatistics.setPrefix("$GFXDeviceStatistics::");
 195
 196   // Initialize the static helper textures.
 197   GBitmap temp( 2, 2, false, GFXFormatR8G8B8A8 );
 198   temp.fill( ColorI::ONE );
 199   GFXTexHandle::ONE.set( &temp, &GFXStaticTextureSRGBProfile, false, "GFXTexHandle::ONE" ); 
 200   temp.fill( ColorI::ZERO );
 201   GFXTexHandle::ZERO.set( &temp, &GFXStaticTextureSRGBProfile, false, "GFXTexHandle::ZERO" ); 
 202   temp.fill( ColorI( 128, 128, 255 ) );
 203   GFXTexHandle::ZUP.set( &temp, &GFXNormalMapProfile, false, "GFXTexHandle::ZUP" );
 204}
 205
 206bool GFXDevice::destroy()
 207{
 208   // Cleanup the static helper textures.
 209   GFXTexHandle::ONE.free();
 210   GFXTexHandle::ZERO.free();
 211   GFXTexHandle::ZUP.free();
 212
 213   // Make this release its buffer.
 214   PrimBuild::shutdown();
 215
 216   // Let people know we are shutting down
 217   getDeviceEventSignal().trigger(deDestroy);
 218
 219   if(smGFXDevice)
 220      smGFXDevice->preDestroy();
 221   SAFE_DELETE(smGFXDevice);
 222
 223   return true;
 224}
 225
 226void GFXDevice::preDestroy()
 227{
 228   // Delete draw util
 229   SAFE_DELETE( mDrawer );
 230}
 231
 232GFXDevice::~GFXDevice()
 233{ 
 234   smGFXDevice = NULL;
 235
 236   // Clean up our current buffers.
 237   mCurrentPrimitiveBuffer = NULL;
 238   for ( U32 i=0; i < VERTEX_STREAM_COUNT; i++ )
 239      mCurrentVertexBuffer[i] = NULL;
 240
 241   // Clear out our current texture references
 242   for (U32 i = 0; i < GFX_TEXTURE_STAGE_COUNT; i++)
 243   {
 244      mCurrentTexture[i] = NULL;
 245      mNewTexture[i] = NULL;
 246      mCurrentCubemap[i] = NULL;
 247      mNewCubemap[i] = NULL;
 248      mCurrentCubemapArray[i] = NULL;
 249      mNewCubemapArray[i] = NULL;
 250      mCurrentTextureArray[i] = NULL;
 251      mNewTextureArray[i] = NULL;
 252   }
 253
 254   mCurrentRT = NULL;
 255
 256   // Release all the unreferenced textures in the cache.
 257   mTextureManager->cleanupCache();
 258
 259   // Check for resource leaks
 260#ifdef TORQUE_DEBUG
 261   AssertFatal( GFXTextureObject::dumpActiveTOs() == 0, "There is a texture object leak, check the log for more details." );
 262   GFXPrimitiveBuffer::dumpActivePBs();
 263#endif
 264
 265   SAFE_DELETE( mTextureManager );
 266   SAFE_DELETE( mFrameTime );
 267
 268   // Clear out our state block references
 269   mCurrentStateBlocks.clear();
 270   mNewStateBlock = NULL;
 271   mCurrentStateBlock = NULL;
 272
 273   mCurrentShaderConstBuffer = NULL;
 274   /// End Block above BTR
 275
 276   // -- Clear out resource list
 277   // Note: our derived class destructor will have already released resources.
 278   // Clearing this list saves us from having our resources (which are not deleted
 279   // just released) turn around and try to remove themselves from this list.
 280   while (mResourceListHead)
 281   {
 282      GFXResource * head = mResourceListHead;
 283      mResourceListHead = head->mNextResource;
 284      
 285      head->mPrevResource = NULL;
 286      head->mNextResource = NULL;
 287      head->mOwningDevice = NULL;
 288   }
 289}
 290
 291GFXStateBlockRef GFXDevice::createStateBlock(const GFXStateBlockDesc& desc)
 292{
 293   PROFILE_SCOPE( GFXDevice_CreateStateBlock );
 294
 295   U32 hashValue = desc.getHashValue();
 296   if (mCurrentStateBlocks[hashValue])
 297      return mCurrentStateBlocks[hashValue];
 298
 299   GFXStateBlockRef result = createStateBlockInternal(desc);
 300   result->registerResourceWithDevice(this);   
 301   mCurrentStateBlocks[hashValue] = result;
 302   return result;
 303}
 304
 305void GFXDevice::setStateBlock(GFXStateBlock* block)
 306{
 307   AssertFatal(block, "NULL state block!");
 308   AssertFatal(block->getOwningDevice() == this, "This state doesn't apply to this device!");
 309
 310   if (block != mCurrentStateBlock)
 311   {
 312      mStateDirty = true;
 313      mStateBlockDirty = true;
 314      mNewStateBlock = block;
 315   } else {
 316      mStateBlockDirty = false;
 317      mNewStateBlock = mCurrentStateBlock;
 318   }
 319}
 320
 321void GFXDevice::setStateBlockByDesc( const GFXStateBlockDesc &desc )
 322{
 323   PROFILE_SCOPE( GFXDevice_SetStateBlockByDesc );
 324   GFXStateBlock *block = createStateBlock( desc );
 325   setStateBlock( block );
 326}
 327
 328void GFXDevice::setShaderConstBuffer(GFXShaderConstBuffer* buffer)
 329{
 330   mCurrentShaderConstBuffer = buffer;
 331}
 332
 333void GFXDevice::updateStates(bool forceSetAll /*=false*/)
 334{
 335   PROFILE_SCOPE(GFXDevice_updateStates);
 336
 337   if(forceSetAll)
 338   {
 339      bool rememberToEndScene = false;
 340      if(!canCurrentlyRender())
 341      {
 342         if (!beginScene())
 343         {
 344            AssertFatal(false, "GFXDevice::updateStates:  Unable to beginScene!");
 345         }
 346         rememberToEndScene = true;
 347      }
 348
 349      setVertexDecl( mCurrVertexDecl );
 350
 351      for ( U32 i=0; i < VERTEX_STREAM_COUNT; i++ )
 352      {
 353         setVertexStream( i, mCurrentVertexBuffer[i] );
 354         setVertexStreamFrequency( i, mVertexBufferFrequency[i] );
 355      }
 356
 357      if( mCurrentPrimitiveBuffer.isValid() ) // This could be NULL when the device is initalizing
 358         mCurrentPrimitiveBuffer->prepare();
 359
 360      /// Stateblocks
 361      if ( mNewStateBlock )
 362         setStateBlockInternal(mNewStateBlock, true);
 363      mCurrentStateBlock = mNewStateBlock;
 364
 365      for(U32 i = 0; i < getNumSamplers(); i++)
 366      {
 367         switch (mTexType[i])
 368         {
 369            case GFXTDT_Normal :
 370               {
 371                  mCurrentTexture[i] = mNewTexture[i];
 372                  setTextureInternal(i, mCurrentTexture[i]);
 373               }  
 374               break;
 375            case GFXTDT_Cube :
 376               {
 377                  mCurrentCubemap[i] = mNewCubemap[i];
 378                  if (mCurrentCubemap[i])
 379                     mCurrentCubemap[i]->setToTexUnit(i);
 380                  else
 381                     setTextureInternal(i, NULL);
 382               }
 383               break;
 384            case GFXTDT_CubeArray:
 385               {
 386                  mCurrentCubemapArray[i] = mNewCubemapArray[i];
 387                  if (mCurrentCubemapArray[i])
 388                     mCurrentCubemapArray[i]->setToTexUnit(i);
 389                  else
 390                     setTextureInternal(i, NULL);
 391               }
 392               break;
 393            case GFXTDT_TextureArray:
 394               {
 395                  mCurrentTextureArray[i] = mNewTextureArray[i];
 396                  if (mCurrentTextureArray[i])
 397                     mCurrentTextureArray[i]->setToTexUnit(i);
 398                  else
 399                     setTextureInternal(i, NULL);
 400               }
 401               break;
 402            default:
 403               AssertFatal(false, "Unknown texture type!");
 404               break;
 405         }
 406      }
 407
 408       _updateRenderTargets();
 409
 410      if(rememberToEndScene)
 411         endScene();
 412
 413      return;
 414   }
 415
 416   if (!mStateDirty)
 417      return;
 418
 419   // Normal update logic begins here.
 420   mStateDirty = false;
 421
 422   // Update the vertex declaration.
 423   if ( mVertexDeclDirty )
 424   {
 425      setVertexDecl( mCurrVertexDecl );
 426      mVertexDeclDirty = false;
 427   }
 428
 429   // Update the vertex buffers.
 430   for ( U32 i=0; i < VERTEX_STREAM_COUNT; i++ )
 431   {
 432      if ( mVertexBufferDirty[i] )
 433      {
 434         setVertexStream( i, mCurrentVertexBuffer[i] );
 435         mVertexBufferDirty[i] = false;
 436      }
 437
 438      if ( mVertexBufferFrequencyDirty[i] )
 439      {
 440         setVertexStreamFrequency( i, mVertexBufferFrequency[i] );
 441         mVertexBufferFrequencyDirty[i] = false;
 442      }
 443   }
 444
 445   // Update primitive buffer
 446   //
 447   // NOTE: It is very important to set the primitive buffer AFTER the vertex buffer
 448   // because in order to draw indexed primitives in DX8, the call to SetIndicies
 449   // needs to include the base vertex offset, and the DX8 GFXDevice relies on
 450   // having mCurrentVB properly assigned before the call to setIndices -patw
 451   if( mPrimitiveBufferDirty )
 452   {
 453      if( mCurrentPrimitiveBuffer.isValid() ) // This could be NULL when the device is initalizing
 454         mCurrentPrimitiveBuffer->prepare();
 455      mPrimitiveBufferDirty = false;
 456   }
 457
 458   // NOTE: With state blocks, it's now important to update state before setting textures
 459   // some devices (e.g. OpenGL) set states on the texture and we need that information before
 460   // the texture is activated.
 461   if (mStateBlockDirty)
 462   {
 463      setStateBlockInternal(mNewStateBlock, false);
 464      mCurrentStateBlock = mNewStateBlock;
 465      mStateBlockDirty = false;
 466   }
 467
 468   _updateRenderTargets();
 469
 470   if( mTexturesDirty )
 471   {
 472      mTexturesDirty = false;
 473      for(U32 i = 0; i < getNumSamplers(); i++)
 474      {
 475         if(!mTextureDirty[i])
 476            continue;
 477         mTextureDirty[i] = false;
 478
 479         switch (mTexType[i])
 480         {
 481         case GFXTDT_Normal :
 482            {
 483               mCurrentTexture[i] = mNewTexture[i];
 484               setTextureInternal(i, mCurrentTexture[i]);
 485            }  
 486            break;
 487         case GFXTDT_Cube :
 488            {
 489               mCurrentCubemap[i] = mNewCubemap[i];
 490               if (mCurrentCubemap[i])
 491                  mCurrentCubemap[i]->setToTexUnit(i);
 492               else
 493                  setTextureInternal(i, NULL);
 494            }
 495            break;
 496         case GFXTDT_CubeArray:
 497         {
 498            mCurrentCubemapArray[i] = mNewCubemapArray[i];
 499            if (mCurrentCubemapArray[i])
 500               mCurrentCubemapArray[i]->setToTexUnit(i);
 501            else
 502               setTextureInternal(i, NULL);
 503         }
 504            break;
 505         case GFXTDT_TextureArray:
 506         {
 507            mCurrentTextureArray[i] = mNewTextureArray[i];
 508            if (mCurrentTextureArray[i])
 509               mCurrentTextureArray[i]->setToTexUnit(i);
 510            else
 511               setTextureInternal(i, NULL);
 512         }
 513         break;
 514         default:
 515            AssertFatal(false, "Unknown texture type!");
 516            break;
 517         }
 518      }
 519   }
 520
 521   _updateRenderTargets();
 522
 523#ifdef TORQUE_DEBUG_RENDER
 524   doParanoidStateCheck();
 525#endif
 526}
 527
 528void GFXDevice::clearTextureStateImmediate(U32 stage)
 529{
 530   mCurrentTexture[stage] = NULL;
 531   mCurrentCubemap[stage] = NULL;
 532   setTextureInternal(stage, NULL);
 533}
 534
 535void GFXDevice::setPrimitiveBuffer( GFXPrimitiveBuffer *buffer )
 536{
 537   if( buffer == mCurrentPrimitiveBuffer )
 538      return;
 539   
 540   mCurrentPrimitiveBuffer = buffer;
 541   mPrimitiveBufferDirty = true;
 542   mStateDirty = true;
 543}
 544
 545void GFXDevice::drawPrimitive( U32 primitiveIndex )
 546{
 547   AssertFatal( mCurrentPrimitiveBuffer.isValid(), "Trying to call drawPrimitive with no current primitive buffer, call setPrimitiveBuffer()" );
 548   AssertFatal( primitiveIndex < mCurrentPrimitiveBuffer->mPrimitiveCount, "Out of range primitive index.");
 549   drawPrimitive( mCurrentPrimitiveBuffer->mPrimitiveArray[primitiveIndex] );
 550}
 551
 552void GFXDevice::drawPrimitive( const GFXPrimitive &prim )
 553{
 554   // Do NOT add index buffer offset to this call, it will be added by drawIndexedPrimitive
 555   drawIndexedPrimitive(   prim.type, 
 556                           prim.startVertex,
 557                           prim.minIndex, 
 558                           prim.numVertices, 
 559                           prim.startIndex, 
 560                           prim.numPrimitives );
 561}
 562
 563void GFXDevice::drawPrimitives()
 564{
 565   AssertFatal( mCurrentPrimitiveBuffer.isValid(), "Trying to call drawPrimitive with no current primitive buffer, call setPrimitiveBuffer()" );
 566
 567   GFXPrimitive *info = NULL;
 568   
 569   for( U32 i = 0; i < mCurrentPrimitiveBuffer->mPrimitiveCount; i++ ) {
 570      info = &mCurrentPrimitiveBuffer->mPrimitiveArray[i];
 571
 572      // Do NOT add index buffer offset to this call, it will be added by drawIndexedPrimitive
 573      drawIndexedPrimitive(   info->type, 
 574                              info->startVertex,
 575                              info->minIndex, 
 576                              info->numVertices, 
 577                              info->startIndex, 
 578                              info->numPrimitives );
 579   }
 580}
 581
 582DefineEngineFunction( getDisplayDeviceList, String, (),,
 583   "Returns a tab-seperated string of the detected devices across all adapters.\n"
 584   "@ingroup GFX\n" )
 585{
 586   Vector<GFXAdapter*> adapters;
 587   GFXInit::getAdapters(&adapters);
 588
 589   StringBuilder str;
 590   for (S32 i=0; i<adapters.size(); i++)
 591   {
 592      if (i)
 593         str.append( '\t' );
 594      str.append(adapters[i]->mName);
 595   }
 596
 597   return str.end();
 598}
 599
 600void GFXDevice::setFrustum(   F32 left, 
 601                              F32 right, 
 602                              F32 bottom, 
 603                              F32 top, 
 604                              F32 nearPlane, 
 605                              F32 farPlane,
 606                              bool bRotate )
 607{
 608   // store values
 609   mFrustum.set(false, left, right, top, bottom, nearPlane, farPlane);
 610   
 611   // compute matrix
 612   MatrixF projection;
 613   mFrustum.getProjectionMatrix(&projection, bRotate);
 614   setProjectionMatrix( projection );
 615}
 616
 617void GFXDevice::setFrustum( const Frustum& frust, bool bRotate )
 618{
 619   // store values
 620   mFrustum = frust;
 621   
 622   // compute matrix
 623   MatrixF projection;
 624   mFrustum.getProjectionMatrix(&projection, bRotate);
 625   setProjectionMatrix( projection );
 626}
 627
 628
 629void GFXDevice::getFrustum( F32 *left, F32 *right, F32 *bottom, F32 *top, F32 *nearPlane, F32 *farPlane, bool *isOrtho ) const
 630{   
 631   if ( left )       *left       = mFrustum.getNearLeft();
 632   if ( right )      *right      = mFrustum.getNearRight();
 633   if ( bottom )     *bottom     = mFrustum.getNearBottom();
 634   if ( top )        *top        = mFrustum.getNearTop();
 635   if ( nearPlane )  *nearPlane  = mFrustum.getNearDist();
 636   if ( farPlane )   *farPlane   = mFrustum.getFarDist();
 637   if ( isOrtho )    *isOrtho    = mFrustum.isOrtho();
 638}
 639
 640void GFXDevice::setOrtho(  F32 left, 
 641                           F32 right, 
 642                           F32 bottom, 
 643                           F32 top, 
 644                           F32 nearPlane, 
 645                           F32 farPlane,
 646                           bool doRotate )
 647{
 648   // store values
 649   mFrustum.set(true, left, right, top, bottom, nearPlane, farPlane);
 650
 651   // compute matrix
 652   MatrixF projection;
 653   mFrustum.getProjectionMatrix(&projection, doRotate);  
 654
 655   setProjectionMatrix( projection );
 656}
 657
 658Point2F GFXDevice::getWorldToScreenScale() const
 659{
 660   Point2F scale;
 661
 662   const RectI &viewport = getViewport();
 663
 664   if ( mFrustum.isOrtho() )
 665      scale.set(  viewport.extent.x / mFrustum.getWidth(),
 666                  viewport.extent.y / mFrustum.getHeight() );
 667   else
 668      scale.set(  ( mFrustum.getNearDist() * viewport.extent.x ) / mFrustum.getWidth(),
 669                  ( mFrustum.getNearDist() * viewport.extent.y ) / mFrustum.getHeight() );
 670
 671   return scale;
 672}
 673
 674//-----------------------------------------------------------------------------
 675// Set texture
 676//-----------------------------------------------------------------------------
 677void GFXDevice::setTexture( U32 stage, GFXTextureObject *texture )
 678{
 679   AssertFatal(stage < getNumSamplers(), "GFXDevice::setTexture - out of range stage!");
 680
 681   if (  mTexType[stage] == GFXTDT_Normal &&
 682         (  ( mTextureDirty[stage] && mNewTexture[stage].getPointer() == texture ) ||
 683            ( !mTextureDirty[stage] && mCurrentTexture[stage].getPointer() == texture ) ) )
 684      return;
 685
 686   mStateDirty = true;
 687   mTexturesDirty = true;
 688   mTextureDirty[stage] = true;
 689
 690   mNewTexture[stage] = texture;
 691   mTexType[stage] = GFXTDT_Normal;
 692
 693   // Clear out the cubemaps
 694   mNewCubemap[stage] = NULL;
 695   mCurrentCubemap[stage] = NULL;
 696   mNewCubemapArray[stage] = NULL;
 697   mCurrentCubemapArray[stage] = NULL;
 698   mNewTextureArray[stage] = NULL;
 699   mCurrentTextureArray[stage] = NULL;
 700}
 701
 702//-----------------------------------------------------------------------------
 703// Set cube texture
 704//-----------------------------------------------------------------------------
 705void GFXDevice::setCubeTexture( U32 stage, GFXCubemap *cubemap )
 706{
 707   AssertFatal(stage < getNumSamplers(), "GFXDevice::setTexture - out of range stage!");
 708
 709   if (  mTexType[stage] == GFXTDT_Cube &&
 710         (  ( mTextureDirty[stage] && mNewCubemap[stage].getPointer() == cubemap) ||
 711            ( !mTextureDirty[stage] && mCurrentCubemap[stage].getPointer() == cubemap) ) )
 712      return;
 713
 714   mStateDirty = true;
 715   mTexturesDirty = true;
 716   mTextureDirty[stage] = true;
 717
 718   mNewCubemap[stage] = cubemap;
 719   mTexType[stage] = GFXTDT_Cube;
 720
 721   // Clear out textures
 722   mNewTexture[stage] = NULL;
 723   mCurrentTexture[stage] = NULL;
 724   mNewCubemapArray[stage] = NULL;
 725   mCurrentCubemapArray[stage] = NULL;
 726   mNewTextureArray[stage] = NULL;
 727   mCurrentTextureArray[stage] = NULL;
 728}
 729
 730//-----------------------------------------------------------------------------
 731// Set cube texture array
 732//-----------------------------------------------------------------------------
 733void GFXDevice::setCubeArrayTexture(U32 stage, GFXCubemapArray *cubemapArray)
 734{
 735   AssertFatal(stage < getNumSamplers(), avar("GFXDevice::setTexture - out of range stage! %i>%i", stage, getNumSamplers()));
 736
 737   if (mTexType[stage] == GFXTDT_CubeArray &&
 738      ((mTextureDirty[stage] && mNewCubemapArray[stage].getPointer() == cubemapArray) ||
 739      (!mTextureDirty[stage] && mCurrentCubemapArray[stage].getPointer() == cubemapArray)))
 740      return;
 741
 742   mStateDirty = true;
 743   mTexturesDirty = true;
 744   mTextureDirty[stage] = true;
 745
 746   mNewCubemapArray[stage] = cubemapArray;
 747   mTexType[stage] = GFXTDT_CubeArray;
 748
 749   // Clear out textures
 750   mNewTexture[stage] = NULL;
 751   mCurrentTexture[stage] = NULL;
 752   mNewCubemap[stage] = NULL;
 753   mCurrentCubemap[stage] = NULL;
 754   mNewTextureArray[stage] = NULL;
 755   mCurrentTextureArray[stage] = NULL;
 756}
 757
 758//-----------------------------------------------------------------------------
 759// Set texture array
 760//-----------------------------------------------------------------------------
 761void GFXDevice::setTextureArray(U32 stage, GFXTextureArray *textureArray)
 762{
 763   AssertFatal(stage < getNumSamplers(), avar("GFXDevice::setTextureArray - out of range stage! %i>%i", stage, getNumSamplers()));
 764
 765   if (mTexType[stage] == GFXTDT_TextureArray &&
 766      ((mTextureDirty[stage] && mNewTextureArray[stage].getPointer() == textureArray) ||
 767      (!mTextureDirty[stage] && mCurrentTextureArray[stage].getPointer() == textureArray)))
 768      return;
 769
 770   mStateDirty = true;
 771   mTexturesDirty = true;
 772   mTextureDirty[stage] = true;
 773
 774   mNewTextureArray[stage] = textureArray;
 775   mTexType[stage] = GFXTDT_TextureArray;
 776
 777   // Clear out textures
 778   mNewTexture[stage] = NULL;
 779   mCurrentTexture[stage] = NULL;
 780   mNewCubemap[stage] = NULL;
 781   mCurrentCubemap[stage] = NULL;
 782   mNewCubemapArray[stage] = NULL;
 783   mCurrentCubemapArray[stage] = NULL;
 784}
 785
 786//------------------------------------------------------------------------------
 787
 788inline bool GFXDevice::beginScene()
 789{
 790   AssertFatal( mCanCurrentlyRender == false, "GFXDevice::beginScene() - The scene has already begun!" );
 791
 792   mDeviceStatistics.clear();
 793
 794   // Send the start of frame signal.
 795   getDeviceEventSignal().trigger( GFXDevice::deStartOfFrame );
 796   mFrameTime->reset();
 797   return beginSceneInternal();
 798}
 799
 800inline void GFXDevice::endScene()
 801{
 802   AssertFatal( mCanCurrentlyRender == true, "GFXDevice::endScene() - The scene has already ended!" );
 803   
 804   // End frame signal
 805   getDeviceEventSignal().trigger( GFXDevice::deEndOfFrame );
 806
 807   endSceneInternal();
 808   mDeviceStatistics.exportToConsole();
 809}
 810
 811inline void GFXDevice::beginField()
 812{
 813   AssertFatal( mCanCurrentlyRender == true, "GFXDevice::beginField() - The scene has not yet begun!" );
 814
 815   // Send the start of field signal.
 816   getDeviceEventSignal().trigger( GFXDevice::deStartOfField );
 817}
 818
 819inline void GFXDevice::endField()
 820{
 821   AssertFatal( mCanCurrentlyRender == true, "GFXDevice::endField() - The scene has not yet begun!" );
 822
 823   // Send the end of field signal.
 824   getDeviceEventSignal().trigger( GFXDevice::deEndOfField );
 825}
 826
 827void GFXDevice::setViewport( const RectI &inRect ) 
 828{
 829   // Clip the rect against the renderable size.
 830   Point2I size = mCurrentRT->getSize();
 831   RectI maxRect(Point2I(0,0), size);
 832   RectI rect = inRect;
 833   rect.intersect(maxRect);
 834
 835   if ( mViewport != rect )
 836   {
 837      mViewport = rect;
 838      mViewportDirty = true;
 839   }   
 840}
 841
 842void GFXDevice::pushActiveRenderTarget()
 843{
 844   // Push the current target on to the stack.
 845   mRTStack.push_back( mCurrentRT );
 846}
 847
 848void GFXDevice::popActiveRenderTarget()
 849{
 850   AssertFatal( mRTStack.size() > 0, "GFXDevice::popActiveRenderTarget() - stack is empty!" );
 851
 852   // Restore the last item on the stack and pop.
 853   setActiveRenderTarget( mRTStack.last() );
 854   mRTStack.pop_back();
 855}
 856
 857void GFXDevice::setActiveRenderTarget( GFXTarget *target, bool updateViewport )
 858{
 859   AssertFatal( target, 
 860      "GFXDevice::setActiveRenderTarget - must specify a render target!" );
 861
 862   if ( target == mCurrentRT )
 863      return;
 864   
 865   // If we're not dirty then store the 
 866   // current RT for deactivation later.
 867   if ( !mRTDirty )
 868   {
 869      // Deactivate the target queued for deactivation
 870      if(mRTDeactivate)
 871         mRTDeactivate->deactivate();
 872
 873      mRTDeactivate = mCurrentRT;
 874   }
 875
 876   mRTDirty = true;
 877   mCurrentRT = target;
 878
 879   // When a target changes we also change the viewport
 880   // to match it.  This causes problems when the viewport
 881   // has been modified for clipping to a GUI bounds.
 882   //
 883   // We should consider removing this and making it the
 884   // responsibility of the caller to set a proper viewport
 885   // when the target is changed.   
 886   if ( updateViewport )
 887   {
 888      setViewport( RectI( Point2I::Zero, mCurrentRT->getSize() ) );
 889   }
 890}
 891
 892/// Helper class for GFXDevice::describeResources.
 893class DescriptionOutputter
 894{
 895   /// Are we writing to a file?
 896   bool mWriteToFile;
 897
 898   /// File if we are writing to a file
 899   FileStream mFile;
 900public:
 901   DescriptionOutputter(const char* file)
 902   {
 903      mWriteToFile = false;
 904      // If we've been given what could be a valid file path, open it.
 905      if(file && file[0] != '\0')
 906      {
 907         mWriteToFile = mFile.open(file, Torque::FS::File::Write);
 908
 909         // Note that it is safe to retry.  If this is hit, we'll just write to the console instead of to the file.
 910         AssertFatal(mWriteToFile, avar("DescriptionOutputter::DescriptionOutputter - could not open file %s", file));
 911      }
 912   }
 913
 914   ~DescriptionOutputter()
 915   {
 916      // Close the file
 917      if(mWriteToFile)
 918         mFile.close();
 919   }
 920
 921   /// Writes line to the file or to the console, depending on what we want.
 922   void write(const char* line)
 923   {
 924      if(mWriteToFile)
 925         mFile.writeLine((const U8*)line);
 926      else
 927         Con::printf(line);
 928   }
 929};
 930
 931#ifndef TORQUE_SHIPPING
 932void GFXDevice::dumpStates( const char *fileName ) const
 933{
 934   DescriptionOutputter output(fileName);
 935
 936   output.write("Current state");
 937   if (!mCurrentStateBlock.isNull())
 938      output.write(mCurrentStateBlock->getDesc().describeSelf().c_str());
 939   else
 940      output.write("No state!");
 941
 942   output.write("\nAll states:\n");
 943   GFXResource* walk = mResourceListHead;
 944   while(walk)
 945   {
 946      const GFXStateBlock* sb = dynamic_cast<const GFXStateBlock*>(walk);
 947      if (sb)
 948      {
 949         output.write(sb->getDesc().describeSelf().c_str());
 950      }
 951      walk = walk->getNextResource();
 952   }
 953}
 954#endif
 955
 956void GFXDevice::listResources(bool unflaggedOnly)
 957{
 958   U32 numTextures = 0, numShaders = 0, numRenderToTextureTargs = 0, numWindowTargs = 0;
 959   U32 numCubemaps = 0, numVertexBuffers = 0, numPrimitiveBuffers = 0, numFences = 0;
 960   U32 numStateBlocks = 0;
 961
 962   GFXResource* walk = mResourceListHead;
 963   while(walk)
 964   {
 965      if(unflaggedOnly && walk->isFlagged())
 966      {
 967         walk = walk->getNextResource();
 968         continue;
 969      }
 970
 971      if(dynamic_cast<GFXTextureObject*>(walk))
 972         numTextures++;
 973      else if(dynamic_cast<GFXShader*>(walk))
 974         numShaders++;
 975      else if(dynamic_cast<GFXTextureTarget*>(walk))
 976         numRenderToTextureTargs++;
 977      else if(dynamic_cast<GFXWindowTarget*>(walk))
 978         numWindowTargs++;
 979      else if(dynamic_cast<GFXCubemap*>(walk))
 980         numCubemaps++;
 981      else if(dynamic_cast<GFXVertexBuffer*>(walk))
 982         numVertexBuffers++;
 983      else if(dynamic_cast<GFXPrimitiveBuffer*>(walk))
 984         numPrimitiveBuffers++;
 985      else if(dynamic_cast<GFXFence*>(walk))
 986         numFences++;
 987      else if (dynamic_cast<GFXStateBlock*>(walk))
 988         numStateBlocks++;
 989      else
 990         Con::warnf("Unknown resource: %x", walk);
 991
 992      walk = walk->getNextResource();
 993   }
 994   const char* flag = unflaggedOnly ? "unflagged" : "allocated";
 995
 996   Con::printf("GFX currently has:");
 997   Con::printf("   %i %s textures", numTextures, flag);
 998   Con::printf("   %i %s shaders", numShaders, flag);
 999   Con::printf("   %i %s texture targets", numRenderToTextureTargs, flag);
1000   Con::printf("   %i %s window targets", numWindowTargs, flag);
1001   Con::printf("   %i %s cubemaps", numCubemaps, flag);
1002   Con::printf("   %i %s vertex buffers", numVertexBuffers, flag);
1003   Con::printf("   %i %s primitive buffers", numPrimitiveBuffers, flag);
1004   Con::printf("   %i %s fences", numFences, flag);
1005   Con::printf("   %i %s state blocks", numStateBlocks, flag);
1006}
1007
1008void GFXDevice::fillResourceVectors(const char* resNames, bool unflaggedOnly, Vector<GFXResource*> &textureObjects,
1009                                 Vector<GFXResource*> &textureTargets, Vector<GFXResource*> &windowTargets, Vector<GFXResource*> &vertexBuffers, 
1010                                 Vector<GFXResource*> &primitiveBuffers, Vector<GFXResource*> &fences, Vector<GFXResource*> &cubemaps, 
1011                                 Vector<GFXResource*> &shaders, Vector<GFXResource*> &stateblocks)
1012{
1013   bool describeTexture = true, describeTextureTarget = true, describeWindowTarget = true, describeVertexBuffer = true, 
1014      describePrimitiveBuffer = true, describeFence = true, describeCubemap = true, describeShader = true,
1015      describeStateBlock = true;
1016
1017   // If we didn't specify a string of names, we'll print all of them
1018   if(resNames && resNames[0] != '\0')
1019   {
1020      // If we did specify a string of names, determine which names
1021      describeTexture =          (dStrstr(resNames, "GFXTextureObject")    != NULL);
1022      describeTextureTarget =    (dStrstr(resNames, "GFXTextureTarget")    != NULL);
1023      describeWindowTarget =     (dStrstr(resNames, "GFXWindowTarget")     != NULL);
1024      describeVertexBuffer =     (dStrstr(resNames, "GFXVertexBuffer")     != NULL);
1025      describePrimitiveBuffer =  (dStrstr(resNames, "GFXPrimitiveBuffer")   != NULL);
1026      describeFence =            (dStrstr(resNames, "GFXFence")            != NULL);
1027      describeCubemap =          (dStrstr(resNames, "GFXCubemap")          != NULL);
1028      describeShader =           (dStrstr(resNames, "GFXShader")           != NULL);
1029      describeStateBlock =       (dStrstr(resNames, "GFXStateBlock")           != NULL);
1030   }
1031
1032   // Start going through the list
1033   GFXResource* walk = mResourceListHead;
1034   while(walk)
1035   {
1036      // If we only want unflagged resources, skip all flagged resources
1037      if(unflaggedOnly && walk->isFlagged())
1038      {
1039         walk = walk->getNextResource();
1040         continue;
1041      }
1042
1043      // All of the following checks go through the same logic.
1044      // if(describingThisResource) 
1045      // {
1046      //    ResourceType* type = dynamic_cast<ResourceType*>(walk)
1047      //    if(type)
1048      //    {
1049      //       typeVector.push_back(type);
1050      //       walk = walk->getNextResource();
1051      //       continue;
1052      //    }
1053      // }
1054
1055      if(describeTexture)
1056      {
1057         GFXTextureObject* tex = dynamic_cast<GFXTextureObject*>(walk);
1058         {
1059            if(tex)
1060            {
1061               textureObjects.push_back(tex);
1062               walk = walk->getNextResource();
1063               continue;
1064            }
1065         }
1066      }
1067      if(describeShader)
1068      {
1069         GFXShader* shd = dynamic_cast<GFXShader*>(walk);
1070         if(shd)
1071         {
1072            shaders.push_back(shd);
1073            walk = walk->getNextResource();
1074            continue;
1075         }
1076      }
1077      if(describeVertexBuffer)
1078      {
1079         GFXVertexBuffer* buf = dynamic_cast<GFXVertexBuffer*>(walk);
1080         if(buf)
1081         {
1082            vertexBuffers.push_back(buf);
1083            walk = walk->getNextResource();
1084            continue;
1085         }
1086      }
1087      if(describePrimitiveBuffer)
1088      {
1089         GFXPrimitiveBuffer* buf = dynamic_cast<GFXPrimitiveBuffer*>(walk);
1090         if(buf)
1091         {
1092            primitiveBuffers.push_back(buf);
1093            walk = walk->getNextResource();
1094            continue;
1095         }
1096      }
1097      if(describeTextureTarget)
1098      {
1099         GFXTextureTarget* targ = dynamic_cast<GFXTextureTarget*>(walk);
1100         if(targ)
1101         {
1102            textureTargets.push_back(targ);
1103            walk = walk->getNextResource();
1104            continue;
1105         }
1106      }
1107      if(describeWindowTarget)
1108      {
1109         GFXWindowTarget* targ = dynamic_cast<GFXWindowTarget*>(walk);
1110         if(targ)
1111         {
1112            windowTargets.push_back(targ);
1113            walk = walk->getNextResource();
1114            continue;
1115         }
1116      }
1117      if(describeCubemap)
1118      {
1119         GFXCubemap* cube = dynamic_cast<GFXCubemap*>(walk);
1120         if(cube)
1121         {
1122            cubemaps.push_back(cube);
1123            walk = walk->getNextResource();
1124            continue;
1125         }
1126      }
1127      if(describeFence)
1128      {
1129         GFXFence* fence = dynamic_cast<GFXFence*>(walk);
1130         if(fence)
1131         {
1132            fences.push_back(fence);
1133            walk = walk->getNextResource();
1134            continue;
1135         }
1136      }
1137      if (describeStateBlock)
1138      {
1139         GFXStateBlock* sb = dynamic_cast<GFXStateBlock*>(walk);
1140         if (sb)
1141         {
1142            stateblocks.push_back(sb);
1143            walk = walk->getNextResource();
1144            continue;
1145         }
1146      }
1147      // Wasn't something we were looking for
1148      walk = walk->getNextResource();
1149   }
1150}
1151
1152void GFXDevice::describeResources(const char* resNames, const char* filePath, bool unflaggedOnly)
1153{
1154   const U32 numResourceTypes = 9;
1155   Vector<GFXResource*> resVectors[numResourceTypes];
1156   const char* reslabels[numResourceTypes] = { "texture", "texture target", "window target", "vertex buffers", "primitive buffers", "fences", "cubemaps", "shaders", "stateblocks" };   
1157
1158   // Fill the vectors with the right resources
1159   fillResourceVectors(resNames, unflaggedOnly, resVectors[0], resVectors[1], resVectors[2], resVectors[3], 
1160      resVectors[4], resVectors[5], resVectors[6], resVectors[7], resVectors[8]);
1161
1162   // Helper object
1163   DescriptionOutputter output(filePath);
1164
1165   // Print the info to the file
1166   // Note that we check if we have any objects of that type.
1167   for (U32 i = 0; i < numResourceTypes; i++)
1168   {
1169      if (resVectors[i].size())
1170      {
1171         // Header
1172         String header = String::ToString("--------Dumping GFX %s descriptions...----------", reslabels[i]);
1173         output.write(header);
1174         // Data
1175         for (U32 j = 0; j < resVectors[i].size(); j++)
1176         {
1177            GFXResource* resource = resVectors[i][j];
1178            String dataline = String::ToString("Addr: %x %s", resource, resource->describeSelf().c_str());
1179            output.write(dataline.c_str());
1180         }
1181         // Footer
1182         output.write("--------------------Done---------------------");
1183         output.write("");
1184      }
1185   }
1186}
1187
1188void GFXDevice::flagCurrentResources()
1189{
1190   GFXResource* walk = mResourceListHead;
1191   while(walk)
1192   {
1193      walk->setFlag();
1194      walk = walk->getNextResource();
1195   }
1196}
1197
1198void GFXDevice::clearResourceFlags()
1199{
1200   GFXResource* walk = mResourceListHead;
1201   while(walk)
1202   {
1203      walk->clearFlag();
1204      walk = walk->getNextResource();
1205   }
1206}
1207
1208DefineEngineFunction( listGFXResources, void, ( bool unflaggedOnly ), ( false ),
1209   "Returns a list of the unflagged GFX resources. See flagCurrentGFXResources for usage details.\n"
1210   "@ingroup GFX\n"
1211   "@see flagCurrentGFXResources, clearGFXResourceFlags, describeGFXResources" )
1212{
1213   GFX->listResources(unflaggedOnly);
1214}
1215
1216DefineEngineFunction( flagCurrentGFXResources, void, (),,
1217   "@brief Flags all currently allocated GFX resources.\n"
1218   "Used for resource allocation and leak tracking by flagging "
1219   "current resources then dumping a list of unflagged resources "
1220   "at some later point in execution.\n"
1221   "@ingroup GFX\n"
1222   "@see listGFXResources, clearGFXResourceFlags, describeGFXResources" )
1223{
1224   GFX->flagCurrentResources();
1225}
1226
1227DefineEngineFunction( clearGFXResourceFlags, void, (),,
1228   "Clears the flagged state on all allocated GFX resources. "
1229   "See flagCurrentGFXResources for usage details.\n"
1230   "@ingroup GFX\n"
1231   "@see flagCurrentGFXResources, listGFXResources, describeGFXResources" )
1232{
1233   GFX->clearResourceFlags();
1234}
1235
1236DefineEngineFunction( describeGFXResources, void, ( const char *resourceTypes, const char *filePath, bool unflaggedOnly ), ( false ),
1237   "@brief Dumps a description of GFX resources to a file or the console.\n"
1238   "@param resourceTypes A space seperated list of resource types or an empty string for all resources.\n"
1239   "@param filePath A file to dump the list to or an empty string to write to the console.\n"
1240   "@param unflaggedOnly If true only unflagged resources are dumped. See flagCurrentGFXResources.\n"
1241   "@note The resource types can be one or more of the following:\n\n"
1242   "  - texture\n"
1243   "  - texture target\n"
1244   "  - window target\n"
1245   "  - vertex buffers\n"
1246   "  - primitive buffers\n"
1247   "  - fences\n"
1248   "  - cubemaps\n"
1249   "  - shaders\n"
1250   "  - stateblocks\n\n"
1251   "@ingroup GFX\n" )
1252{
1253   GFX->describeResources( resourceTypes, filePath, unflaggedOnly );
1254}
1255
1256DefineEngineFunction( describeGFXStateBlocks, void, ( const char *filePath ),,
1257   "Dumps a description of all state blocks.\n"     
1258   "@param filePath A file to dump the state blocks to or an empty string to write to the console.\n"
1259   "@ingroup GFX\n" )
1260{
1261   GFX->dumpStates( filePath );   
1262}
1263
1264DefineEngineFunction( getPixelShaderVersion, F32, (),,
1265   "Returns the pixel shader version for the active device.\n"
1266   "@ingroup GFX\n" )
1267{
1268   return GFX->getPixelShaderVersion();
1269}   
1270
1271DefineEngineFunction( setPixelShaderVersion, void, ( F32 version ),,
1272   "@brief Sets the pixel shader version for the active device.\n"
1273   "This can be used to force a lower pixel shader version than is supported by "
1274   "the device for testing or performance optimization.\n"
1275   "@param version The floating point shader version number.\n"
1276   "@note This will only affect shaders/materials created after the call "
1277   "and should be used before the game begins.\n"
1278   "@see $pref::Video::forcedPixVersion\n"
1279   "@ingroup GFX\n" )
1280{
1281   GFX->setPixelShaderVersion( version );
1282}
1283
1284DefineEngineFunction( getDisplayDeviceInformation, const char*, (),,
1285   "Get the string describing the active GFX device.\n"
1286   "@ingroup GFX\n" )
1287{
1288   if (!GFXDevice::devicePresent())
1289      return "(no device)";
1290
1291   const GFXAdapter& adapter = GFX->getAdapter();
1292   return adapter.getName();
1293}
1294
1295DefineEngineFunction(getDisplayDeviceType, GFXAdapterType, (), ,
1296   "Get the string describing the active GFX device type.\n"
1297   "@ingroup GFX\n")
1298{
1299   if (!GFXDevice::devicePresent())
1300      return NullDevice;
1301
1302   const GFXAdapter& adapter = GFX->getAdapter();
1303   return adapter.mType;
1304}
1305
1306DefineEngineFunction( getBestHDRFormat, GFXFormat, (),,
1307   "Returns the best texture format for storage of HDR data for the active device.\n"
1308   "@ingroup GFX\n" )
1309{
1310   // TODO: Maybe expose GFX::selectSupportedFormat() so that this
1311   // specialized method can be moved to script.
1312
1313   // Figure out the best HDR format.  This is the smallest
1314   // format which supports blending and filtering.
1315   Vector<GFXFormat> formats;
1316   formats.push_back(GFXFormatR16G16B16A16F);
1317   formats.push_back( GFXFormatR10G10B10A2 );   
1318   GFXFormat format = GFX->selectSupportedFormat(  &GFXRenderTargetProfile,
1319                                                   formats, 
1320                                                   true,
1321                                                   true,
1322                                                   true );
1323
1324   return format;
1325}
1326
1327DefineEngineFunction(ResetGFX, void, (), , "forces the gbuffer to be reinitialized in cases of improper/lack of buffer clears.")
1328{
1329   GFX->beginReset();
1330}
1331