Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

260 lines
7.2 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include <stdlib.h>
  7. #include <tier0/dbg.h>
  8. #include "interface.h"
  9. #include "istudiorender.h"
  10. #include "studio.h"
  11. #include "optimize.h"
  12. #include "cmdlib.h"
  13. #include "studiomdl.h"
  14. #include "perfstats.h"
  15. #include "tier1/tier1_logging.h"
  16. extern void MdlError( char const *pMsg, ... );
  17. static StudioRenderConfig_t s_StudioRenderConfig;
  18. class CStudioDataCache : public CBaseAppSystem<IStudioDataCache>
  19. {
  20. public:
  21. bool VerifyHeaders( studiohdr_t *pStudioHdr );
  22. vertexFileHeader_t *CacheVertexData( studiohdr_t *pStudioHdr );
  23. };
  24. static CStudioDataCache g_StudioDataCache;
  25. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CStudioDataCache, IStudioDataCache, STUDIO_DATA_CACHE_INTERFACE_VERSION, g_StudioDataCache );
  26. /*
  27. =================
  28. VerifyHeaders
  29. Minimal presence and header validation, no data loads
  30. Return true if successful, false otherwise.
  31. =================
  32. */
  33. bool CStudioDataCache::VerifyHeaders( studiohdr_t *pStudioHdr )
  34. {
  35. // default valid
  36. return true;
  37. }
  38. /*
  39. =================
  40. CacheVertexData
  41. Cache model's specified dynamic data
  42. =================
  43. */
  44. vertexFileHeader_t *CStudioDataCache::CacheVertexData( studiohdr_t *pStudioHdr )
  45. {
  46. // minimal implementation - return persisted data
  47. return (vertexFileHeader_t*)pStudioHdr->VertexBase();
  48. }
  49. static void UpdateStudioRenderConfig( void )
  50. {
  51. memset( &s_StudioRenderConfig, 0, sizeof(s_StudioRenderConfig) );
  52. s_StudioRenderConfig.bEyeMove = true;
  53. s_StudioRenderConfig.fEyeShiftX = 0.0f;
  54. s_StudioRenderConfig.fEyeShiftY = 0.0f;
  55. s_StudioRenderConfig.fEyeShiftZ = 0.0f;
  56. s_StudioRenderConfig.fEyeSize = 10.0f;
  57. s_StudioRenderConfig.bSoftwareSkin = false;
  58. s_StudioRenderConfig.bNoHardware = false;
  59. s_StudioRenderConfig.bNoSoftware = false;
  60. s_StudioRenderConfig.bTeeth = true;
  61. s_StudioRenderConfig.drawEntities = true;
  62. s_StudioRenderConfig.bFlex = true;
  63. s_StudioRenderConfig.bEyes = true;
  64. s_StudioRenderConfig.bWireframe = false;
  65. s_StudioRenderConfig.bDrawZBufferedWireframe = false;
  66. s_StudioRenderConfig.bDrawNormals = false;
  67. s_StudioRenderConfig.skin = 0;
  68. s_StudioRenderConfig.maxDecalsPerModel = 0;
  69. s_StudioRenderConfig.bWireframeDecals = false;
  70. s_StudioRenderConfig.fullbright = false;
  71. s_StudioRenderConfig.bSoftwareLighting = false;
  72. s_StudioRenderConfig.bShowEnvCubemapOnly = false;
  73. g_pStudioRender->UpdateConfig( s_StudioRenderConfig );
  74. }
  75. static CBufferedLoggingListener s_BufferedLoggingListener;
  76. void SpewPerfStats( studiohdr_t *pStudioHdr, const char *pFilename, unsigned int flags )
  77. {
  78. char fileName[260];
  79. vertexFileHeader_t *pNewVvdHdr;
  80. vertexFileHeader_t *pVvdHdr = 0;
  81. OptimizedModel::FileHeader_t *pVtxHdr = 0;
  82. studiohwdata_t studioHWData;
  83. int vvdSize = 0;
  84. const char *prefix[] = { ".dx90.vtx", ".dx80.vtx", ".sw.vtx" };
  85. const int numVtxFiles = ( g_gameinfo.bSupportsDX8 && !g_bFastBuild ) ? ARRAYSIZE( prefix ) : 1;
  86. bool bExtraData = (pStudioHdr->flags & STUDIOHDR_FLAGS_EXTRA_VERTEX_DATA) != 0;
  87. if( !( flags & SPEWPERFSTATS_SHOWSTUDIORENDERWARNINGS ) )
  88. {
  89. LoggingSystem_PushLoggingState();
  90. LoggingSystem_RegisterLoggingListener( &s_BufferedLoggingListener );
  91. }
  92. // no stats on these
  93. if (!pStudioHdr->numbodyparts)
  94. return;
  95. // Need to update the render config to spew perf stats.
  96. UpdateStudioRenderConfig();
  97. // persist the vvd data
  98. Q_StripExtension( pFilename, fileName, sizeof( fileName ) );
  99. strcat( fileName, ".vvd" );
  100. if (FileExists( fileName ))
  101. {
  102. vvdSize = LoadFile( fileName, (void**)&pVvdHdr );
  103. }
  104. else
  105. {
  106. MdlError( "Could not open '%s'\n", fileName );
  107. }
  108. // validate header
  109. if (pVvdHdr->id != MODEL_VERTEX_FILE_ID)
  110. {
  111. MdlError( "Bad id for '%s' (got %d expected %d)\n", fileName, pVvdHdr->id, MODEL_VERTEX_FILE_ID);
  112. }
  113. if (pVvdHdr->version != MODEL_VERTEX_FILE_VERSION)
  114. {
  115. MdlError( "Bad version for '%s' (got %d expected %d)\n", fileName, pVvdHdr->version, MODEL_VERTEX_FILE_VERSION);
  116. }
  117. if (pVvdHdr->checksum != pStudioHdr->checksum)
  118. {
  119. MdlError( "Bad checksum for '%s' (got %d expected %d)\n", fileName, pVvdHdr->checksum, pStudioHdr->checksum);
  120. }
  121. if (pVvdHdr->numFixups)
  122. {
  123. // need to perform mesh relocation fixups
  124. // allocate a new copy
  125. pNewVvdHdr = (vertexFileHeader_t *)malloc( vvdSize );
  126. if (!pNewVvdHdr)
  127. {
  128. MdlError( "Error allocating %d bytes for Vertex File '%s'\n", vvdSize, fileName );
  129. }
  130. Studio_LoadVertexes( pVvdHdr, pNewVvdHdr, 0, true, bExtraData );
  131. // discard original
  132. free( pVvdHdr );
  133. pVvdHdr = pNewVvdHdr;
  134. }
  135. // iterate all ???.vtx files
  136. for (int j = 0; j< numVtxFiles; j++)
  137. {
  138. // make vtx filename
  139. Q_StripExtension( pFilename, fileName, sizeof( fileName ) );
  140. strcat( fileName, prefix[j] );
  141. // persist the vtx data
  142. if (FileExists(fileName))
  143. {
  144. LoadFile( fileName, (void**)&pVtxHdr );
  145. }
  146. else
  147. {
  148. MdlError( "Could not open '%s'\n", fileName );
  149. }
  150. // validate header
  151. if (pVtxHdr->version != OPTIMIZED_MODEL_FILE_VERSION)
  152. {
  153. MdlError( "Bad version for '%s' (got %d expected %d)\n", fileName, pVtxHdr->version, OPTIMIZED_MODEL_FILE_VERSION );
  154. }
  155. if (pVtxHdr->checkSum != pStudioHdr->checksum)
  156. {
  157. MdlError( "Bad checksum for '%s' (got %d expected %d)\n", fileName, pVtxHdr->checkSum, pStudioHdr->checksum );
  158. }
  159. // studio render will request these through cache interface
  160. pStudioHdr->SetVertexBase( (void *)pVvdHdr );
  161. pStudioHdr->SetIndexBase( (void *)pVtxHdr );
  162. g_pStudioRender->LoadModel( pStudioHdr, pVtxHdr, &studioHWData );
  163. if( flags & SPEWPERFSTATS_SHOWPERF )
  164. {
  165. if( flags & SPEWPERFSTATS_SPREADSHEET )
  166. {
  167. printf( "%s,%s,%d,", fileName, prefix[j], studioHWData.m_NumLODs - studioHWData.m_RootLOD );
  168. }
  169. else
  170. {
  171. printf( "\n" );
  172. printf( "Performance Stats: %s\n", fileName );
  173. printf( "------------------\n" );
  174. }
  175. }
  176. int i;
  177. if( flags & SPEWPERFSTATS_SHOWPERF )
  178. {
  179. for( i = studioHWData.m_RootLOD; i < studioHWData.m_NumLODs; i++ )
  180. {
  181. DrawModelInfo_t drawModelInfo;
  182. drawModelInfo.m_Skin = 0;
  183. drawModelInfo.m_Body = 0;
  184. drawModelInfo.m_HitboxSet = 0;
  185. drawModelInfo.m_pClientEntity = 0;
  186. drawModelInfo.m_pColorMeshes = 0;
  187. drawModelInfo.m_pStudioHdr = pStudioHdr;
  188. drawModelInfo.m_pHardwareData = &studioHWData;
  189. CUtlBuffer statsOutput( 0, 0, CUtlBuffer::TEXT_BUFFER );
  190. if( !( flags & SPEWPERFSTATS_SPREADSHEET ) )
  191. {
  192. printf( "LOD:%d\n", i );
  193. }
  194. drawModelInfo.m_Lod = i;
  195. DrawModelResults_t results;
  196. g_pStudioRender->GetPerfStats( &results, drawModelInfo, &statsOutput );
  197. if( flags & SPEWPERFSTATS_SPREADSHEET )
  198. {
  199. printf( "%d,%d,%d,", results.m_ActualTriCount, results.m_NumBatches, results.m_NumMaterials );
  200. }
  201. else
  202. {
  203. printf( " actual tris:%d\n", ( int )results.m_ActualTriCount );
  204. printf( " texture memory bytes: %d (only valid in a rendering app)\n", ( int )results.m_TextureMemoryBytes );
  205. printf( ( char * )statsOutput.Base() );
  206. }
  207. }
  208. if( flags & SPEWPERFSTATS_SPREADSHEET )
  209. {
  210. printf( "\n" );
  211. }
  212. }
  213. g_pStudioRender->UnloadModel( &studioHWData );
  214. free(pVtxHdr);
  215. }
  216. if (pVvdHdr)
  217. free(pVvdHdr);
  218. if( !( flags & SPEWPERFSTATS_SHOWSTUDIORENDERWARNINGS ) )
  219. {
  220. LoggingSystem_PopLoggingState();
  221. s_BufferedLoggingListener.EmitBufferedSpew();
  222. }
  223. }