mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
pstats TransformState, RenderState
This commit is contained in:
parent
0fc0c3f811
commit
b2c9c49805
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user