This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/ww3d2/statistics.cpp

378 lines
11 KiB
C++

/*
** 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();
}
// ----------------------------------------------------------------------------