| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "statistics.h"
- #include "wwstring.h"
- #include "simplevec.h"
- #include "dx8renderer.h"
- #include "dx8wrapper.h"
- #include "dx8caps.h"
- #include "textureloader.h"
- #include "texture.h"
- #include <cstdio>
- #include <memory.h>
- #ifdef _UNIX
- #include "osdep.h"
- #endif
- // ----------------------------------------------------------------------------
- //
- // Texture memory tracking system
- //
- // ----------------------------------------------------------------------------
- static int texture_memory;
- static int texture_count;
- static int lightmap_texture_memory;
- static int lightmap_texture_count;
- static int procedural_texture_memory;
- static int procedural_texture_count;
- static int record_count;
- static int texture_change_count;
- static int last_frame_texture_memory;
- static int last_frame_texture_count;
- static int last_frame_lightmap_texture_memory;
- static int last_frame_lightmap_texture_count;
- static int last_frame_procedural_texture_memory;
- static int last_frame_procedural_texture_count;
- static int last_frame_record_count;
- static int last_frame_texture_change_count;
- static TextureClass* latest_texture;
- static Debug_Statistics::RecordTextureMode record_texture_mode;
- static StringClass texture_statistics_string;
- struct TextureStatisticsStruct
- {
- TextureClass* tex;
- int usage_count;
- int change_count;
- };
- static SimpleDynVecClass<TextureStatisticsStruct> texture_statistics;
- static void Record_Texture_Begin()
- {
- texture_memory=0;
- texture_count=0;
- lightmap_texture_memory=0;
- lightmap_texture_count=0;
- procedural_texture_memory=0;
- procedural_texture_count=0;
- record_count=0;
- texture_change_count=0;
- latest_texture=NULL;
- texture_statistics.Resize(0);
- }
- static void Record_Texture_End()
- {
- last_frame_texture_memory=texture_memory;
- last_frame_texture_count=texture_count;
- last_frame_lightmap_texture_memory=lightmap_texture_memory;
- last_frame_lightmap_texture_count=lightmap_texture_count;
- last_frame_procedural_texture_memory=procedural_texture_memory;
- last_frame_procedural_texture_count=procedural_texture_count;
- last_frame_record_count=record_count;
- last_frame_texture_change_count=texture_change_count;
- texture_statistics_string="";
- if (record_texture_mode==Debug_Statistics::RECORD_TEXTURE_DETAILS) {
- char tmp_text[1024];
- _snprintf(tmp_text,sizeof(tmp_text),
- "Set_DX8_Texture count: %d\nactual changes: %d\n\n"
- "id refs changes size name\n"
- "--------------------------------------\n",
- last_frame_record_count,last_frame_texture_change_count);
- texture_statistics_string+=tmp_text;
- for (int a=0;a<texture_count;++a) {
- StringClass working_string;
- TextureClass* t=texture_statistics[a].tex;
- int id=0;
- StringClass flash=" ";
- // if (t && t->getClassID() == ID_TEXTURE_FILE_CLASS) {
- // TextureFileClass* tfc=static_cast<TextureFileClass*>(t);
- // id=tfc->ID();
- // if (tfc->Get_Texture_Flash()) flash="F";
- // }
- working_string.Format("%4.4d %3.3d %3.3d %s ",id,texture_statistics[a].usage_count,texture_statistics[a].change_count,flash.Peek_Buffer());
- texture_statistics_string+=working_string;
- StringClass error="";
- if (t) {
- // int red_factor=t->Get_Current_Reduction_Factor();
- unsigned bytes=t->Get_Texture_Memory_Usage();
- // unsigned non_red_bytes=t->Get_Non_Reduced_Texture_Memory_Usage();
- if (!t->Is_Initialized()) {
- // non_red_bytes=bytes;
- texture_statistics_string+="*";
- }
- else {
- texture_statistics_string+=" ";
- }
- // if (!non_red_bytes) non_red_bytes=1;
- // int percents=100-100*bytes/non_red_bytes;
- working_string.Format("%4.4dkb ",bytes/1024);
- texture_statistics_string+=working_string;
- }
- else {
- texture_statistics_string+="N/A ";
- }
- texture_statistics_string+=t->Get_Texture_Name();//getTextureName();
- texture_statistics_string+=error;
- texture_statistics_string+="\n";
- }
- texture_statistics_string+="\nid = id of texture. Use with command 'flash_texture [id]'\n";
- texture_statistics_string+="refs = # of times texture is used when rendering\n";
- texture_statistics_string+="changes = # of times texture change needed - BAD IF HIGH!\n";
- texture_statistics_string+="red = texture reduction factor\n";
- texture_statistics_string+="size = amount of memory needed for texture\n";
- texture_statistics_string+="(w/o red) = size of reduction not used\n";
- texture_statistics_string+="percent = savings of reduction system, in percents\n";
- texture_statistics_string+="\n* = thumbnail used\n";
- texture_statistics_string+="\n";
- // texture_statistics_string+=TextureFileClass::List_Missing_Files();
- }
- }
- void Debug_Statistics::Record_Texture_Mode(RecordTextureMode mode)
- {
- record_texture_mode=mode;
- }
- Debug_Statistics::RecordTextureMode Debug_Statistics::Get_Record_Texture_Mode()
- {
- return record_texture_mode;
- }
- static bool Find_Record_Texture(TextureClass* t)
- {
- for (int a=0;a<texture_count;++a) {
- if (texture_statistics[a].tex==t) {
- if (record_texture_mode==Debug_Statistics::RECORD_TEXTURE_DETAILS) {
- texture_statistics[a].usage_count++;
- if (t!=latest_texture) {
- texture_statistics[a].change_count++;
- }
- }
-
- return true;
- }
- }
- return false;
- }
- static void Add_Record_Texture(TextureClass* t)
- {
- TextureStatisticsStruct tss;
- tss.tex=t;
- tss.usage_count=1;
- tss.change_count=1;
- texture_statistics.Add(tss);
- texture_count++;
- if (t->Is_Lightmap()) lightmap_texture_count++;
- if (t->Is_Procedural()) procedural_texture_count++;
- }
- void Debug_Statistics::Record_Texture(TextureClass* t)
- {
- record_count++;
- if (t!=latest_texture) {
- texture_change_count++;
- }
- if (record_texture_mode==RECORD_TEXTURE_NONE) {
- latest_texture=t;
- return;
- }
- if (!t) {
- latest_texture=t;
- return;
- }
- if (Find_Record_Texture(t)) {
- latest_texture=t;
- return;
- }
- Add_Record_Texture(t);
- texture_memory+=t->Get_Texture_Memory_Usage();
- latest_texture=t;
- if (t->Is_Lightmap()) lightmap_texture_memory+=t->Get_Texture_Memory_Usage();
- if (t->Is_Procedural()) procedural_texture_memory+=t->Get_Texture_Memory_Usage();
- }
- int Debug_Statistics::Get_Record_Texture_Size() // Return total textures used during latest frame, in bytes
- {
- return last_frame_texture_memory;
- }
- int Debug_Statistics::Get_Record_Texture_Count() // Return total textures used during latest frame, in bytes
- {
- return last_frame_texture_count;
- }
- int Debug_Statistics::Get_Record_Texture_Change_Count()
- {
- return last_frame_texture_change_count;
- }
- int Debug_Statistics::Get_Record_Lightmap_Texture_Size() // Return total lightmap textures used during latest frame, in bytes
- {
- return last_frame_lightmap_texture_memory;
- }
- int Debug_Statistics::Get_Record_Lightmap_Texture_Count() // Return total lightmap textures used during latest frame, in bytes
- {
- return last_frame_lightmap_texture_count;
- }
- int Debug_Statistics::Get_Record_Procedural_Texture_Size() // Return total procedural textures used during latest frame, in bytes
- {
- return last_frame_procedural_texture_memory;
- }
- int Debug_Statistics::Get_Record_Procedural_Texture_Count() // Return total procedural textures used during latest frame, in bytes
- {
- return last_frame_procedural_texture_count;
- }
- const StringClass& Debug_Statistics::Get_Record_Texture_String()
- {
- return texture_statistics_string;
- }
- // ----------------------------------------------------------------------------
- static int dx8_skin_renders;
- static int last_frame_dx8_skin_renders;
- static int dx8_skin_polygons;
- static int last_frame_dx8_skin_polygons;
- static int dx8_skin_vertices;
- static int last_frame_dx8_skin_vertices;
- static int dx8_polygons;
- static int last_frame_dx8_polygons;
- static int dx8_vertices;
- static int last_frame_dx8_vertices;
- static int sorting_polygons;
- static int last_frame_sorting_polygons;
- static int sorting_vertices;
- static int last_frame_sorting_vertices;
- void Debug_Statistics::Record_DX8_Skin_Polys_And_Vertices(int pcount,int vcount)
- {
- dx8_skin_polygons+=pcount;
- dx8_skin_vertices+=vcount;
- dx8_skin_renders++;
- }
- void Debug_Statistics::Record_DX8_Polys_And_Vertices(int pcount,int vcount,const ShaderClass& shader)
- {
- if (shader.Get_NPatch_Enable()==ShaderClass::NPATCH_ENABLE && DX8Wrapper::Get_Current_Caps()->Support_NPatches()) {
- unsigned level=WW3D::Get_NPatches_Level();
- level*=level;
- pcount*=level;
- }
- dx8_polygons+=pcount;
- dx8_vertices+=vcount;
- }
- int Debug_Statistics::Get_DX8_Skin_Renders()
- {
- return last_frame_dx8_skin_renders;
- }
- int Debug_Statistics::Get_DX8_Skin_Polygons()
- {
- return last_frame_dx8_skin_polygons;
- }
- int Debug_Statistics::Get_DX8_Skin_Vertices()
- {
- return last_frame_dx8_skin_vertices;
- }
- int Debug_Statistics::Get_DX8_Polygons()
- {
- return last_frame_dx8_polygons;
- }
- int Debug_Statistics::Get_DX8_Vertices()
- {
- return last_frame_dx8_vertices;
- }
- void Debug_Statistics::Record_Sorting_Polys_And_Vertices(int pcount,int vcount)
- {
- sorting_polygons+=pcount;
- sorting_vertices+=vcount;
- }
- int Debug_Statistics::Get_Sorting_Polygons()
- {
- return last_frame_sorting_polygons;
- }
- int Debug_Statistics::Get_Sorting_Vertices()
- {
- return last_frame_sorting_vertices;
- }
- // ----------------------------------------------------------------------------
- //
- //
- //
- // ----------------------------------------------------------------------------
- void Debug_Statistics::Begin_Statistics()
- {
- dx8_polygons=0;
- dx8_vertices=0;
- dx8_skin_polygons=0;
- dx8_skin_vertices=0;
- dx8_skin_renders=0;
- sorting_polygons=0;
- sorting_vertices=0;
- Record_Texture_Begin();
- DX8Wrapper::Begin_Statistics();
- // DX8MeshRendererClass::Begin_Statistics();
- }
- void Debug_Statistics::End_Statistics()
- {
- Record_Texture_End();
- last_frame_dx8_skin_polygons=dx8_skin_polygons;
- last_frame_dx8_skin_vertices=dx8_skin_vertices;
- last_frame_dx8_skin_renders=dx8_skin_renders;
- last_frame_dx8_polygons=dx8_polygons;
- last_frame_dx8_vertices=dx8_vertices;
- last_frame_sorting_polygons=sorting_polygons;
- last_frame_sorting_vertices=sorting_vertices;
- // DX8MeshRendererClass::End_Statistics();
- DX8Wrapper::End_Statistics();
- }
- // ----------------------------------------------------------------------------
|