mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 01:44:06 -04:00
robustify collect_vertex_data some more
This commit is contained in:
parent
d36604ab05
commit
500f17c091
@ -47,11 +47,16 @@
|
||||
|
||||
PStatCollector GraphicsStateGuardian::_total_texusage_pcollector("Texture usage");
|
||||
PStatCollector GraphicsStateGuardian::_active_texusage_pcollector("Texture usage:Active");
|
||||
PStatCollector GraphicsStateGuardian::_texture_count_pcollector("Prepared Textures");
|
||||
PStatCollector GraphicsStateGuardian::_active_texture_count_pcollector("Prepared Textures:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_buffer_count_pcollector("Vertex buffer count");
|
||||
PStatCollector GraphicsStateGuardian::_active_vertex_buffer_count_pcollector("Vertex buffer count:Active vertex");
|
||||
PStatCollector GraphicsStateGuardian::_active_index_buffer_count_pcollector("Vertex buffer count:Active index");
|
||||
PStatCollector GraphicsStateGuardian::_total_geom_pcollector("Prepared Geoms");
|
||||
PStatCollector GraphicsStateGuardian::_active_geom_pcollector("Prepared Geoms:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_buffers_pcollector("Vertex buffers");
|
||||
PStatCollector GraphicsStateGuardian::_active_vertex_buffers_pcollector("Vertex buffers:Active vertex");
|
||||
PStatCollector GraphicsStateGuardian::_active_index_buffers_pcollector("Vertex buffers:Active index");
|
||||
PStatCollector GraphicsStateGuardian::_total_buffers_pcollector("Vertex buffer size");
|
||||
PStatCollector GraphicsStateGuardian::_active_vertex_buffers_pcollector("Vertex buffer size:Active vertex");
|
||||
PStatCollector GraphicsStateGuardian::_active_index_buffers_pcollector("Vertex buffer size:Active index");
|
||||
PStatCollector GraphicsStateGuardian::_total_geom_node_pcollector("Prepared GeomNodes");
|
||||
PStatCollector GraphicsStateGuardian::_active_geom_node_pcollector("Prepared GeomNodes:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_texmem_pcollector("Texture memory");
|
||||
@ -1552,6 +1557,8 @@ init_frame_pstats() {
|
||||
_active_geom_node_pcollector.clear_level();
|
||||
_active_vertex_buffers_pcollector.clear_level();
|
||||
_active_index_buffers_pcollector.clear_level();
|
||||
_active_vertex_buffer_count_pcollector.clear_level();
|
||||
_active_index_buffer_count_pcollector.clear_level();
|
||||
|
||||
// Also clear out our other counters while we're here.
|
||||
_vertices_tristrip_pcollector.clear_level();
|
||||
@ -1606,8 +1613,8 @@ add_to_geom_record(GeomContext *gc) {
|
||||
// Access: Protected
|
||||
// Description: Records that the indicated data array has been drawn
|
||||
// this frame. This function is only used to update the
|
||||
// PStats active_vertex_buffers collector; it gets compiled out
|
||||
// if we aren't using PStats.
|
||||
// PStats active_vertex_buffers collector; it gets
|
||||
// compiled out if we aren't using PStats.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
add_to_vertex_buffer_record(VertexBufferContext *vbc) {
|
||||
@ -1617,6 +1624,7 @@ add_to_vertex_buffer_record(VertexBufferContext *vbc) {
|
||||
if (PStatClient::is_connected()) {
|
||||
if (_current_vertex_buffers.insert(vbc).second) {
|
||||
_active_vertex_buffers_pcollector.add_level(vbc->get_data()->get_data_size_bytes());
|
||||
_active_vertex_buffer_count_pcollector.add_level(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1638,6 +1646,7 @@ add_to_index_buffer_record(IndexBufferContext *ibc) {
|
||||
if (PStatClient::is_connected()) {
|
||||
if (_current_index_buffers.insert(ibc).second) {
|
||||
_active_index_buffers_pcollector.add_level(ibc->get_data()->get_data_size_bytes());
|
||||
_active_index_buffer_count_pcollector.add_level(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -332,6 +332,11 @@ public:
|
||||
// Statistics
|
||||
static PStatCollector _total_texusage_pcollector;
|
||||
static PStatCollector _active_texusage_pcollector;
|
||||
static PStatCollector _texture_count_pcollector;
|
||||
static PStatCollector _active_texture_count_pcollector;
|
||||
static PStatCollector _total_buffer_count_pcollector;
|
||||
static PStatCollector _active_vertex_buffer_count_pcollector;
|
||||
static PStatCollector _active_index_buffer_count_pcollector;
|
||||
static PStatCollector _total_geom_pcollector;
|
||||
static PStatCollector _active_geom_pcollector;
|
||||
static PStatCollector _total_buffers_pcollector;
|
||||
|
@ -46,6 +46,7 @@ load_from_loader(EggLoader &loader) {
|
||||
|
||||
SceneGraphReducer gr;
|
||||
int num_reduced = gr.flatten(loader._root, combine_siblings_bits);
|
||||
// gr.collect_vertex_data(loader._root);
|
||||
egg2pg_cat.info() << "Flattened " << num_reduced << " nodes.\n";
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,8 @@
|
||||
#include "mutexHolder.h"
|
||||
|
||||
PStatCollector PreparedGraphicsObjects::_total_texusage_pcollector("Texture usage");
|
||||
PStatCollector PreparedGraphicsObjects::_total_buffers_pcollector("Vertex buffers");
|
||||
PStatCollector PreparedGraphicsObjects::_total_buffers_pcollector("Vertex buffer size");
|
||||
PStatCollector PreparedGraphicsObjects::_total_buffer_count_pcollector("Vertex buffer count");
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::Constructor
|
||||
@ -449,6 +450,7 @@ release_vertex_buffer(VertexBufferContext *vbc) {
|
||||
|
||||
vbc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(vbc->get_data_size_bytes());
|
||||
_total_buffer_count_pcollector.sub_level(1);
|
||||
|
||||
// We have to set the Data pointer to NULL at this point, since
|
||||
// the Data itself might destruct at any time after it has been
|
||||
@ -482,6 +484,7 @@ release_all_vertex_buffers() {
|
||||
VertexBufferContext *vbc = (*vbci);
|
||||
vbc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(vbc->get_data_size_bytes());
|
||||
_total_buffer_count_pcollector.sub_level(1);
|
||||
vbc->_data = (qpGeomVertexArrayData *)NULL;
|
||||
|
||||
_released_vertex_buffers.insert(vbc);
|
||||
@ -532,6 +535,7 @@ prepare_vertex_buffer_now(qpGeomVertexArrayData *data, GraphicsStateGuardianBase
|
||||
// GraphicsStateGuardian::add_to_vertex_buffer_record(); we don't need to
|
||||
// count it again here.
|
||||
//_total_buffers_pcollector.add_level(vbc->get_data_size_bytes());
|
||||
_total_buffer_count_pcollector.add_level(1);
|
||||
}
|
||||
|
||||
return vbc;
|
||||
@ -596,6 +600,7 @@ release_index_buffer(IndexBufferContext *ibc) {
|
||||
|
||||
ibc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(ibc->get_data_size_bytes());
|
||||
_total_buffer_count_pcollector.sub_level(1);
|
||||
|
||||
// We have to set the Data pointer to NULL at this point, since
|
||||
// the Data itself might destruct at any time after it has been
|
||||
@ -629,6 +634,7 @@ release_all_index_buffers() {
|
||||
IndexBufferContext *ibc = (*ibci);
|
||||
ibc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(ibc->get_data_size_bytes());
|
||||
_total_buffer_count_pcollector.sub_level(1);
|
||||
ibc->_data = (qpGeomPrimitive *)NULL;
|
||||
|
||||
_released_index_buffers.insert(ibc);
|
||||
@ -679,6 +685,7 @@ prepare_index_buffer_now(qpGeomPrimitive *data, GraphicsStateGuardianBase *gsg)
|
||||
// GraphicsStateGuardian::add_to_index_buffer_record(); we don't need to
|
||||
// count it again here.
|
||||
//_total_buffers_pcollector.add_level(ibc->get_data_size_bytes());
|
||||
_total_buffer_count_pcollector.add_level(1);
|
||||
}
|
||||
|
||||
return ibc;
|
||||
|
@ -116,6 +116,7 @@ private:
|
||||
|
||||
static PStatCollector _total_texusage_pcollector;
|
||||
static PStatCollector _total_buffers_pcollector;
|
||||
static PStatCollector _total_buffer_count_pcollector;
|
||||
|
||||
friend class GraphicsStateGuardian;
|
||||
};
|
||||
|
@ -17,6 +17,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "geomTransformer.h"
|
||||
#include "sceneGraphReducer.h"
|
||||
#include "geomNode.h"
|
||||
#include "qpgeom.h"
|
||||
#include "qpgeomVertexRewriter.h"
|
||||
@ -528,29 +529,23 @@ apply_state(GeomNode *node, const RenderState *state) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomTransformer::collect_vertex_data
|
||||
// Access: Public
|
||||
// Description: Transforms the vertices and the normals in the
|
||||
// indicated Geom by the indicated matrix. Returns true
|
||||
// if the Geom was changed, false otherwise.
|
||||
// Description: Collects together GeomVertexDatas from different
|
||||
// geoms into one big (or several big) GeomVertexDatas.
|
||||
// Returns the number of unique GeomVertexDatas created.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomTransformer::
|
||||
collect_vertex_data(Geom *geom, bool keep_names) {
|
||||
if (!geom->is_of_type(qpGeom::get_class_type())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
qpGeom *qpgeom = DCAST(qpGeom, geom);
|
||||
|
||||
const qpGeomVertexData *vdata = qpgeom->get_vertex_data();
|
||||
int GeomTransformer::
|
||||
collect_vertex_data(qpGeom *geom, int collect_bits) {
|
||||
const qpGeomVertexData *vdata = geom->get_vertex_data();
|
||||
|
||||
if (vdata->get_num_vertices() > _max_collect_vertices) {
|
||||
// Don't even bother.
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const qpGeomVertexFormat *format = vdata->get_format();
|
||||
|
||||
NewCollectedKey key;
|
||||
if (keep_names) {
|
||||
if ((collect_bits & SceneGraphReducer::CVD_name) != 0) {
|
||||
key._name = vdata->get_name();
|
||||
}
|
||||
key._format = format;
|
||||
@ -561,12 +556,13 @@ collect_vertex_data(Geom *geom, bool keep_names) {
|
||||
if (ai != _already_collected.end()) {
|
||||
// We've previously collected this vertex data; reuse it.
|
||||
const AlreadyCollectedData &acd = (*ai).second;
|
||||
qpgeom->offset_vertices(acd._data, acd._offset);
|
||||
return true;
|
||||
geom->offset_vertices(acd._data, acd._offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We haven't collected this vertex data yet; append the vertices
|
||||
// onto the new data.
|
||||
int num_created = 0;
|
||||
|
||||
NewCollectedData::iterator ni = _new_collected_data.find(key);
|
||||
PT(qpGeomVertexData) new_data;
|
||||
@ -576,6 +572,7 @@ collect_vertex_data(Geom *geom, bool keep_names) {
|
||||
new_data = new qpGeomVertexData(vdata->get_name(), format,
|
||||
vdata->get_usage_hint());
|
||||
_new_collected_data[key] = new_data;
|
||||
++num_created;
|
||||
}
|
||||
|
||||
int offset = new_data->get_num_vertices();
|
||||
@ -588,6 +585,7 @@ collect_vertex_data(Geom *geom, bool keep_names) {
|
||||
_new_collected_data[key] = new_data;
|
||||
offset = 0;
|
||||
new_num_vertices = vdata->get_num_vertices();
|
||||
++num_created;
|
||||
}
|
||||
|
||||
new_data->set_num_vertices(new_num_vertices);
|
||||
@ -604,12 +602,12 @@ collect_vertex_data(Geom *geom, bool keep_names) {
|
||||
old_array->get_data(), copy_bytes);
|
||||
}
|
||||
|
||||
qpgeom->offset_vertices(new_data, offset);
|
||||
AlreadyCollectedData &acd = _already_collected[vdata];
|
||||
acd._data = new_data;
|
||||
acd._offset = offset;
|
||||
geom->offset_vertices(new_data, offset);
|
||||
|
||||
return true;
|
||||
return num_created;
|
||||
}
|
||||
|
||||
|
||||
@ -621,20 +619,38 @@ collect_vertex_data(Geom *geom, bool keep_names) {
|
||||
// GeomVertexData structure. This is designed to
|
||||
// minimize context switches on the graphics card.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomTransformer::
|
||||
collect_vertex_data(GeomNode *node, bool keep_names) {
|
||||
bool any_changed = false;
|
||||
int GeomTransformer::
|
||||
collect_vertex_data(GeomNode *node, int collect_bits) {
|
||||
int num_created = 0;
|
||||
|
||||
GeomTransformer *dynamic = NULL;
|
||||
|
||||
GeomNode::CDWriter cdata(node->_cycler);
|
||||
GeomNode::Geoms::iterator gi;
|
||||
for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
|
||||
GeomNode::GeomEntry &entry = (*gi);
|
||||
PT(Geom) new_geom = entry._geom->make_copy();
|
||||
if (collect_vertex_data(new_geom, keep_names)) {
|
||||
if (entry._geom->is_of_type(qpGeom::get_class_type())) {
|
||||
PT(qpGeom) new_geom = DCAST(qpGeom, entry._geom->make_copy());
|
||||
entry._geom = new_geom;
|
||||
any_changed = true;
|
||||
|
||||
if ((collect_bits & SceneGraphReducer::CVD_avoid_dynamic) != 0 &&
|
||||
new_geom->get_vertex_data()->get_usage_hint() < qpGeomUsageHint::UH_static) {
|
||||
// This one has some dynamic properties. Collect it
|
||||
// independently of the outside world.
|
||||
if (dynamic == (GeomTransformer *)NULL) {
|
||||
dynamic = new GeomTransformer(*this);
|
||||
}
|
||||
num_created += dynamic->collect_vertex_data(new_geom, collect_bits);
|
||||
|
||||
} else {
|
||||
num_created += collect_vertex_data(new_geom, collect_bits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return any_changed;
|
||||
if (dynamic != (GeomTransformer *)NULL) {
|
||||
delete dynamic;
|
||||
}
|
||||
|
||||
return num_created;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
class GeomNode;
|
||||
class RenderState;
|
||||
class InternalName;
|
||||
class qpGeom;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : GeomTransformer
|
||||
@ -72,8 +73,8 @@ public:
|
||||
|
||||
bool apply_state(GeomNode *node, const RenderState *state);
|
||||
|
||||
bool collect_vertex_data(Geom *geom, bool keep_names);
|
||||
bool collect_vertex_data(GeomNode *node, bool keep_names);
|
||||
int collect_vertex_data(qpGeom *geom, int collect_bits);
|
||||
int collect_vertex_data(GeomNode *node, int collect_bits);
|
||||
|
||||
private:
|
||||
int _max_collect_vertices;
|
||||
|
@ -574,37 +574,50 @@ choose_name(PandaNode *preserve, PandaNode *source1, PandaNode *source2) {
|
||||
int SceneGraphReducer::
|
||||
r_collect_vertex_data(PandaNode *node, int collect_bits,
|
||||
GeomTransformer &transformer) {
|
||||
int num_collected = 0;
|
||||
int num_created = 0;
|
||||
|
||||
if ((collect_bits & CVD_model) != 0 &&
|
||||
node->is_of_type(ModelNode::get_class_type())) {
|
||||
// When we come to a model node, start a new collection.
|
||||
int this_node_bits = 0;
|
||||
if (node->is_of_type(ModelNode::get_class_type())) {
|
||||
this_node_bits |= CVD_model;
|
||||
}
|
||||
if (!node->get_transform()->is_identity()) {
|
||||
this_node_bits |= CVD_transform;
|
||||
}
|
||||
|
||||
if ((collect_bits & this_node_bits) != 0) {
|
||||
// We need to start a unique collection here.
|
||||
GeomTransformer new_transformer(transformer);
|
||||
|
||||
if (node->is_geom_node()) {
|
||||
// When we come to geom node, collect.
|
||||
if (new_transformer.collect_vertex_data(DCAST(GeomNode, node), collect_bits)) {
|
||||
++num_created;
|
||||
}
|
||||
}
|
||||
|
||||
PandaNode::Children children = node->get_children();
|
||||
int num_children = children.get_num_children();
|
||||
for (int i = 0; i < num_children; ++i) {
|
||||
num_collected +=
|
||||
num_created +=
|
||||
r_collect_vertex_data(children.get_child(i), collect_bits, new_transformer);
|
||||
}
|
||||
return num_collected;
|
||||
}
|
||||
|
||||
if (node->is_geom_node()) {
|
||||
// When we come to geom node, collect.
|
||||
bool keep_names = ((collect_bits & SceneGraphReducer::CVD_name) != 0);
|
||||
if (transformer.collect_vertex_data(DCAST(GeomNode, node), keep_names)) {
|
||||
++num_collected;
|
||||
} else {
|
||||
// Keep the same collection.
|
||||
|
||||
if (node->is_geom_node()) {
|
||||
if (transformer.collect_vertex_data(DCAST(GeomNode, node), collect_bits)) {
|
||||
++num_created;
|
||||
}
|
||||
}
|
||||
|
||||
PandaNode::Children children = node->get_children();
|
||||
int num_children = children.get_num_children();
|
||||
for (int i = 0; i < num_children; ++i) {
|
||||
num_created +=
|
||||
r_collect_vertex_data(children.get_child(i), collect_bits, transformer);
|
||||
}
|
||||
}
|
||||
|
||||
// Then recurse.
|
||||
PandaNode::Children children = node->get_children();
|
||||
int num_children = children.get_num_children();
|
||||
for (int i = 0; i < num_children; ++i) {
|
||||
num_collected +=
|
||||
r_collect_vertex_data(children.get_child(i), collect_bits, transformer);
|
||||
}
|
||||
|
||||
return num_collected;
|
||||
|
||||
return num_created;
|
||||
}
|
||||
|
@ -62,8 +62,25 @@ PUBLISHED:
|
||||
};
|
||||
|
||||
enum CollectVertexData {
|
||||
// If set, two GeomVertexDatas with different names will not be
|
||||
// collected together.
|
||||
CVD_name = 0x001,
|
||||
|
||||
// If set, a ModelNode begins a subgraph of nodes whose
|
||||
// GeomVertexDatas will not be collected with nodes outside the
|
||||
// subgraph.
|
||||
CVD_model = 0x002,
|
||||
|
||||
// If set, a non-identity transform begins a subgraph of nodes
|
||||
// whose GeomVertexDatas will not be collected with nodes outside
|
||||
// the subgraph.
|
||||
CVD_transform = 0x004,
|
||||
|
||||
// If set, GeomVertexDatas with any usage_hint other than
|
||||
// UH_static will not be collected with any other Geoms in a
|
||||
// different GeomNode. However, two different Geoms within the
|
||||
// same node might still be collected together.
|
||||
CVD_avoid_dynamic = 0x008,
|
||||
};
|
||||
|
||||
INLINE void apply_attribs(PandaNode *node, int attrib_types = ~0);
|
||||
|
@ -151,13 +151,18 @@ static LevelCollectorProperties level_properties[] = {
|
||||
{ 1, "Texture memory:In use", { 0.0, 1.0, 1.0 } },
|
||||
{ 1, "Texture manager", { 1.0, 0.0, 0.0 }, "MB", 12, 1048576 },
|
||||
{ 1, "Texture manager:Resident", { 1.0, 1.0, 0.0 } },
|
||||
{ 1, "Prepared Textures", { 0.6, 0.8, 0.0 }, "", 500 },
|
||||
{ 1, "Prepared Textures:Active", { 0.0, 0.6, 0.8 } },
|
||||
{ 1, "Prepared Geoms", { 1.0, 0.0, 0.5 }, "", 500 },
|
||||
{ 1, "Prepared Geoms:Active", { 0.5, 1.0, 0.8 } },
|
||||
{ 1, "Prepared GeomNodes", { 1.0, 0.0, 0.5 }, "", 500 },
|
||||
{ 1, "Prepared GeomNodes:Active", { 0.5, 1.0, 0.8 } },
|
||||
{ 1, "Vertex buffers:Active vertex", { 1.0, 0.0, 0.5 } },
|
||||
{ 1, "Vertex buffers:Active index" , { 0.5, 0.6, 1.0 } },
|
||||
{ 1, "Vertex buffers", { 0.0, 0.0, 1.0 }, "MB", 12, 1048576 },
|
||||
{ 1, "Vertex buffer size", { 0.0, 0.0, 1.0 }, "MB", 12, 1048576 },
|
||||
{ 1, "Vertex buffer size:Active vertex", { 1.0, 0.0, 0.5 } },
|
||||
{ 1, "Vertex buffer size:Active index" , { 0.5, 0.6, 1.0 } },
|
||||
{ 1, "Vertex buffer count", { 0.0, 0.6, 0.8 }, "", 500 },
|
||||
{ 1, "Vertex buffer count:Active vertex", { 0.8, 0.0, 0.6 } },
|
||||
{ 1, "Vertex buffer count:Active index", { 0.8, 0.6, 0.3 } },
|
||||
{ 1, "Vertices", { 0.5, 0.2, 0.0 }, "K", 10, 1000 },
|
||||
{ 1, "Vertices:Other", { 0.2, 0.2, 0.2 } },
|
||||
{ 1, "Vertices:Triangles", { 0.8, 0.8, 0.8 } },
|
||||
|
Loading…
x
Reference in New Issue
Block a user