pstats TransformState, RenderState

This commit is contained in:
David Rose 2002-07-16 01:10:53 +00:00
parent 0fc0c3f811
commit b2c9c49805
9 changed files with 233 additions and 40 deletions

View File

@ -68,9 +68,10 @@ const bool cull_sorting = config_display.GetBool("cull-sorting", true);
// (primarily useful for debugging). // (primarily useful for debugging).
const bool view_frustum_cull = config_display.GetBool("view-frustum-cull", true); const bool view_frustum_cull = config_display.GetBool("view-frustum-cull", true);
const float gsg_clear_r = config_display.GetFloat("gsg-clear-r", 0.0); // Set this true to show the number of unused states in the pstats
const float gsg_clear_g = config_display.GetFloat("gsg-clear-g", 0.0); // graph for TransformState and RenderState counts. This adds a bit
const float gsg_clear_b = config_display.GetFloat("gsg-clear-b", 0.0); // of per-frame overhead to count these things up.
const bool pstats_unused_states = config_display.GetBool("pstats-unused-states", false);
Config::ConfigTable::Symbol::iterator pipe_modules_begin(void) { Config::ConfigTable::Symbol::iterator pipe_modules_begin(void) {

View File

@ -38,10 +38,7 @@ extern const bool pipe_spec_is_remote;
extern const bool compare_state_by_pointer; extern const bool compare_state_by_pointer;
extern const bool cull_sorting; extern const bool cull_sorting;
extern const bool view_frustum_cull; extern const bool view_frustum_cull;
extern const bool pstats_unused_states;
extern const float gsg_clear_r;
extern const float gsg_clear_g;
extern const float gsg_clear_b;
extern Config::ConfigTable::Symbol::iterator pipe_modules_begin(void); extern Config::ConfigTable::Symbol::iterator pipe_modules_begin(void);
extern Config::ConfigTable::Symbol::iterator pipe_modules_end(void); extern Config::ConfigTable::Symbol::iterator pipe_modules_end(void);

View File

@ -66,6 +66,10 @@ PStatCollector GraphicsStateGuardian::_frustum_cull_transforms_pcollector("Cull
PStatCollector GraphicsStateGuardian::_set_state_pcollector("Draw:Set state"); PStatCollector GraphicsStateGuardian::_set_state_pcollector("Draw:Set state");
PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector("Draw:Primitive"); PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector("Draw:Primitive");
PStatCollector GraphicsStateGuardian::_transform_states_pcollector("TransformStates");
PStatCollector GraphicsStateGuardian::_transform_states_unused_pcollector("TransformStates:Unused");
PStatCollector GraphicsStateGuardian::_render_states_pcollector("RenderStates");
PStatCollector GraphicsStateGuardian::_render_states_unused_pcollector("RenderStates:Unused");
#endif #endif
@ -134,10 +138,10 @@ reset() {
_transform = TransformState::make_identity(); _transform = TransformState::make_identity();
_buffer_mask = 0; _buffer_mask = 0;
_color_clear_value.set(gsg_clear_r, gsg_clear_g, gsg_clear_b, 0.0); _color_clear_value.set(0.0f, 0.0f, 0.0f, 0.0f);
_depth_clear_value = 1.0; _depth_clear_value = 1.0f;
_stencil_clear_value = 0.0; _stencil_clear_value = 0.0f;
_accum_clear_value.set(0.0, 0.0, 0.0, 0.0); _accum_clear_value.set(0.0f, 0.0f, 0.0f, 0.0f);
_clear_buffer_type = RenderBuffer::T_back | RenderBuffer::T_depth; _clear_buffer_type = RenderBuffer::T_back | RenderBuffer::T_depth;
_normals_enabled = false; _normals_enabled = false;
@ -1357,29 +1361,38 @@ close_gsg() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian:: void GraphicsStateGuardian::
init_frame_pstats() { init_frame_pstats() {
_current_textures.clear(); if (PStatClient::is_connected()) {
_current_geoms.clear(); _current_textures.clear();
_current_geom_nodes.clear(); _current_geoms.clear();
_active_texusage_pcollector.clear_level(); _current_geom_nodes.clear();
_active_geom_pcollector.clear_level(); _active_texusage_pcollector.clear_level();
_active_geom_node_pcollector.clear_level(); _active_geom_pcollector.clear_level();
_active_geom_node_pcollector.clear_level();
// Also clear out our other counters while we're here.
_vertices_tristrip_pcollector.clear_level(); // Also clear out our other counters while we're here.
_vertices_trifan_pcollector.clear_level(); _vertices_tristrip_pcollector.clear_level();
_vertices_tri_pcollector.clear_level(); _vertices_trifan_pcollector.clear_level();
_vertices_other_pcollector.clear_level(); _vertices_tri_pcollector.clear_level();
_vertices_other_pcollector.clear_level();
_state_changes_pcollector.clear_level();
_transform_state_pcollector.clear_level(); _state_changes_pcollector.clear_level();
_texture_state_pcollector.clear_level(); _transform_state_pcollector.clear_level();
_texture_state_pcollector.clear_level();
_nodes_pcollector.clear_level();
_geom_nodes_pcollector.clear_level(); _nodes_pcollector.clear_level();
_geom_nodes_pcollector.clear_level();
// Not to mention the view-frustum-cull counters.
_frustum_cull_volumes_pcollector.clear_level(); // Not to mention the view-frustum-cull counters.
_frustum_cull_transforms_pcollector.clear_level(); _frustum_cull_volumes_pcollector.clear_level();
_frustum_cull_transforms_pcollector.clear_level();
_transform_states_pcollector.set_level(TransformState::get_num_states());
_render_states_pcollector.set_level(RenderState::get_num_states());
if (pstats_unused_states) {
_transform_states_unused_pcollector.set_level(TransformState::get_num_unused_states());
_render_states_unused_pcollector.set_level(RenderState::get_num_unused_states());
}
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -284,6 +284,10 @@ public:
static PStatCollector _frustum_cull_transforms_pcollector; static PStatCollector _frustum_cull_transforms_pcollector;
static PStatCollector _set_state_pcollector; static PStatCollector _set_state_pcollector;
static PStatCollector _draw_primitive_pcollector; static PStatCollector _draw_primitive_pcollector;
static PStatCollector _transform_states_pcollector;
static PStatCollector _transform_states_unused_pcollector;
static PStatCollector _render_states_pcollector;
static PStatCollector _render_states_unused_pcollector;
private: private:
class LightInfo { class LightInfo {

View File

@ -622,20 +622,106 @@ get_max_priority() {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: RenderState::get_cache_size // Function: RenderState::get_num_states
// Access: Published, Static // Access: Published, Static
// Description: Returns the total number of unique RenderState // Description: Returns the total number of unique RenderState
// objects allocated in the world. This will go up and // objects allocated in the world. This will go up and
// down during normal operations. // down during normal operations.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
int RenderState:: int RenderState::
get_cache_size() { get_num_states() {
if (_states == (States *)NULL) { if (_states == (States *)NULL) {
return 0; return 0;
} }
return _states->size(); return _states->size();
} }
////////////////////////////////////////////////////////////////////
// Function: RenderState::get_num_unused_states
// Access: Published, Static
// Description: Returns the total number of RenderState objects that
// have been allocated but have no references outside of
// the internal RenderState map.
////////////////////////////////////////////////////////////////////
int RenderState::
get_num_unused_states() {
if (_states == (States *)NULL) {
return 0;
}
int num_unused = 0;
// First, we need to count the number of times each RenderState
// object is recorded in the cache.
typedef pmap<const RenderState *, int> StateCount;
StateCount state_count;
States::iterator si;
for (si = _states->begin(); si != _states->end(); ++si) {
const RenderState *state = (*si);
CompositionCache::const_iterator ci;
for (ci = state->_composition_cache.begin();
ci != state->_composition_cache.end();
++ci) {
const RenderState *result = (*ci).second._result;
if (result != (const RenderState *)NULL) {
// Here's a RenderState that's recorded in the cache.
// Count it.
pair<StateCount::iterator, bool> ir =
state_count.insert(StateCount::value_type(result, 1));
if (!ir.second) {
// If the above insert operation fails, then it's already in
// the cache; increment its value.
(*(ir.first)).second++;
}
}
}
for (ci = state->_invert_composition_cache.begin();
ci != state->_invert_composition_cache.end();
++ci) {
const RenderState *result = (*ci).second._result;
if (result != (const RenderState *)NULL) {
pair<StateCount::iterator, bool> ir =
state_count.insert(StateCount::value_type(result, 1));
if (!ir.second) {
(*(ir.first)).second++;
}
}
}
// Finally, check the self_compose field, which might be reference
// counted too.
if (state->_self_compose != (const RenderState *)NULL &&
state->_self_compose != state) {
const RenderState *result = state->_self_compose;
if (result != (const RenderState *)NULL) {
pair<StateCount::iterator, bool> ir =
state_count.insert(StateCount::value_type(result, 1));
if (!ir.second) {
(*(ir.first)).second++;
}
}
}
}
// Now that we have the appearance count of each RenderState
// object, we can tell which ones are unreferenced outside of the
// RenderState cache, by comparing these to the reference counts.
StateCount::iterator sci;
for (sci = state_count.begin(); sci != state_count.end(); ++sci) {
const RenderState *state = (*sci).first;
int count = (*sci).second;
nassertr(count <= state->get_ref_count(), num_unused);
if (count == state->get_ref_count()) {
num_unused++;
}
}
return num_unused;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: RenderState::clear_cache // Function: RenderState::clear_cache
// Access: Published, Static // Access: Published, Static

View File

@ -95,7 +95,8 @@ PUBLISHED:
static int get_max_priority(); static int get_max_priority();
static int get_cache_size(); static int get_num_states();
static int get_num_unused_states();
static int clear_cache(); static int clear_cache();
public: public:

View File

@ -653,20 +653,106 @@ write(ostream &out, int indent_level) const {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: TransformState::get_cache_size // Function: TransformState::get_num_states
// Access: Published, Static // Access: Published, Static
// Description: Returns the total number of unique TransformState // Description: Returns the total number of unique TransformState
// objects allocated in the world. This will go up and // objects allocated in the world. This will go up and
// down during normal operations. // down during normal operations.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
int TransformState:: int TransformState::
get_cache_size() { get_num_states() {
if (_states == (States *)NULL) { if (_states == (States *)NULL) {
return 0; return 0;
} }
return _states->size(); return _states->size();
} }
////////////////////////////////////////////////////////////////////
// Function: TransformState::get_num_unused_states
// Access: Published, Static
// Description: Returns the total number of TransformState objects
// that have been allocated but have no references
// outside of the internal TransformState map.
////////////////////////////////////////////////////////////////////
int TransformState::
get_num_unused_states() {
if (_states == (States *)NULL) {
return 0;
}
int num_unused = 0;
// First, we need to count the number of times each TransformState
// object is recorded in the cache.
typedef pmap<const TransformState *, int> StateCount;
StateCount state_count;
States::iterator si;
for (si = _states->begin(); si != _states->end(); ++si) {
const TransformState *state = (*si);
CompositionCache::const_iterator ci;
for (ci = state->_composition_cache.begin();
ci != state->_composition_cache.end();
++ci) {
const TransformState *result = (*ci).second._result;
if (result != (const TransformState *)NULL) {
// Here's a TransformState that's recorded in the cache.
// Count it.
pair<StateCount::iterator, bool> ir =
state_count.insert(StateCount::value_type(result, 1));
if (!ir.second) {
// If the above insert operation fails, then it's already in
// the cache; increment its value.
(*(ir.first)).second++;
}
}
}
for (ci = state->_invert_composition_cache.begin();
ci != state->_invert_composition_cache.end();
++ci) {
const TransformState *result = (*ci).second._result;
if (result != (const TransformState *)NULL) {
pair<StateCount::iterator, bool> ir =
state_count.insert(StateCount::value_type(result, 1));
if (!ir.second) {
(*(ir.first)).second++;
}
}
}
// Finally, check the self_compose field, which might be reference
// counted too.
if (state->_self_compose != (const TransformState *)NULL &&
state->_self_compose != state) {
const TransformState *result = state->_self_compose;
if (result != (const TransformState *)NULL) {
pair<StateCount::iterator, bool> ir =
state_count.insert(StateCount::value_type(result, 1));
if (!ir.second) {
(*(ir.first)).second++;
}
}
}
}
// Now that we have the appearance count of each TransformState
// object, we can tell which ones are unreferenced outside of the
// TransformState cache, by comparing these to the reference counts.
StateCount::iterator sci;
for (sci = state_count.begin(); sci != state_count.end(); ++sci) {
const TransformState *state = (*sci).first;
int count = (*sci).second;
nassertr(count <= state->get_ref_count(), num_unused);
if (count == state->get_ref_count()) {
num_unused++;
}
}
return num_unused;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: TransformState::clear_cache // Function: TransformState::clear_cache
// Access: Published, Static // Access: Published, Static

View File

@ -115,7 +115,8 @@ PUBLISHED:
void output(ostream &out) const; void output(ostream &out) const;
void write(ostream &out, int indent_level) const; void write(ostream &out, int indent_level) const;
static int get_cache_size(); static int get_num_states();
static int get_num_unused_states();
static int clear_cache(); static int clear_cache();
private: private:

View File

@ -169,6 +169,10 @@ static LevelCollectorProperties level_properties[] = {
{ 1, "Memory usage", { 0.5, 1.0, 0.5 }, "MB", 64, 1048576 }, { 1, "Memory usage", { 0.5, 1.0, 0.5 }, "MB", 64, 1048576 },
{ 1, "Memory usage:C++", { 0.2, 0.2, 1.0 } }, { 1, "Memory usage:C++", { 0.2, 0.2, 1.0 } },
{ 1, "Memory usage:Interpreter", { 0.8, 0.2, 0.5 } }, { 1, "Memory usage:Interpreter", { 0.8, 0.2, 0.5 } },
{ 1, "TransformStates", { 1.0, 0.5, 0.5 }, "", 5000 },
{ 1, "TransformStates:Unused", { 0.2, 0.2, 0.2 } },
{ 1, "RenderStates", { 0.5, 0.5, 1.0 }, "", 1000 },
{ 1, "RenderStates:Unused", { 0.2, 0.2, 0.2 } },
{ 0, NULL } { 0, NULL }
}; };