瀏覽代碼

real state sorting

David Rose 21 年之前
父節點
當前提交
6512581e90

+ 1 - 0
panda/src/display/graphicsEngine.cxx

@@ -499,6 +499,7 @@ render_frame() {
   // Reset our pcollectors that track data across the frame.
   CullTraverser::_nodes_pcollector.clear_level();
   CullTraverser::_geom_nodes_pcollector.clear_level();
+  CullTraverser::_geoms_pcollector.clear_level();
   
   _transform_states_pcollector.set_level(TransformState::get_num_states());
   _render_states_pcollector.set_level(RenderState::get_num_states());

+ 1 - 1
panda/src/display/graphicsStateGuardian.I

@@ -393,7 +393,7 @@ set_state(const RenderState *state) {
   if (state != _state) {
 #ifndef NDEBUG
     if (gsg_cat.is_spam()) {
-      gsg_cat.spam() << "Setting GSG state to:\n";
+      gsg_cat.spam() << "Setting GSG state to " << (void *)state << ":\n";
       state->write(gsg_cat.spam(false), 2);
     }
 #endif

+ 0 - 3
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -2609,8 +2609,6 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) {
 bool DXGraphicsStateGuardian8::
 begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger,
                       const qpGeomVertexData *vertex_data) {
-  DO_PSTATS_STUFF(_draw_primitive_pcollector.start());
-
   if (!GraphicsStateGuardian::begin_draw_primitives(geom, munger, vertex_data)) {
     return false;
   }
@@ -2718,7 +2716,6 @@ draw_tristrips(const qpGeomTristrips *primitive) {
 void DXGraphicsStateGuardian8::
 end_draw_primitives() {
   GraphicsStateGuardian::end_draw_primitives();
-  DO_PSTATS_STUFF(_draw_primitive_pcollector.stop());
 }
 
 ////////////////////////////////////////////////////////////////////

+ 3 - 0
panda/src/pgraph/Sources.pp

@@ -31,6 +31,7 @@
     cullBinFixed.I cullBinFixed.h \
     cullBinFrontToBack.I cullBinFrontToBack.h \
     cullBinManager.I cullBinManager.h \
+    cullBinStateSorted.I cullBinStateSorted.h \
     cullBinUnsorted.I cullBinUnsorted.h \
     cullFaceAttrib.I cullFaceAttrib.h \
     cullHandler.I cullHandler.h \
@@ -127,6 +128,7 @@
     cullBinFixed.cxx \
     cullBinFrontToBack.cxx \
     cullBinManager.cxx \
+    cullBinStateSorted.cxx \
     cullBinUnsorted.cxx \
     cullFaceAttrib.cxx \
     cullHandler.cxx \
@@ -221,6 +223,7 @@
     cullBinFixed.I cullBinFixed.h \
     cullBinFrontToBack.I cullBinFrontToBack.h \
     cullBinManager.I cullBinManager.h \
+    cullBinStateSorted.I cullBinStateSorted.h \
     cullBinUnsorted.I cullBinUnsorted.h \
     cullFaceAttrib.I cullFaceAttrib.h \
     cullHandler.I cullHandler.h \

+ 2 - 0
panda/src/pgraph/config_pgraph.cxx

@@ -36,6 +36,7 @@
 #include "cullBinBackToFront.h"
 #include "cullBinFixed.h"
 #include "cullBinFrontToBack.h"
+#include "cullBinStateSorted.h"
 #include "cullBinUnsorted.h"
 #include "cullTraverser.h"
 #include "cullableObject.h"
@@ -236,6 +237,7 @@ init_libpgraph() {
   CullBinBackToFront::init_type();
   CullBinFixed::init_type();
   CullBinFrontToBack::init_type();
+  CullBinStateSorted::init_type();
   CullBinUnsorted::init_type();
   CullTraverser::init_type();
   CullableObject::init_type();

+ 4 - 0
panda/src/pgraph/cullBinManager.cxx

@@ -20,6 +20,7 @@
 #include "cullBinBackToFront.h"
 #include "cullBinFrontToBack.h"
 #include "cullBinFixed.h"
+#include "cullBinStateSorted.h"
 #include "cullBinUnsorted.h"
 #include "renderState.h"
 #include "cullResult.h"
@@ -212,6 +213,9 @@ make_new_bin(int bin_index, GraphicsStateGuardianBase *gsg) {
   case BT_fixed:
     return new CullBinFixed(name, gsg);
 
+  case BT_state_sorted:
+    return new CullBinStateSorted(name, gsg);
+
   default:
     return new CullBinUnsorted(name, gsg);
   }

+ 71 - 0
panda/src/pgraph/cullBinStateSorted.I

@@ -0,0 +1,71 @@
+// Filename: cullBinStateSorted.I
+// Created by:  drose (22Mar05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: CullBinStateSorted::ObjectData::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE CullBinStateSorted::ObjectData::
+ObjectData(CullableObject *object) :
+  _object(object)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CullBinStateSorted::ObjectData::operator <
+//       Access: Public
+//  Description: Specifies the correct sort ordering for these
+//               objects.
+////////////////////////////////////////////////////////////////////
+INLINE bool CullBinStateSorted::ObjectData::
+operator < (const ObjectData &other) const {
+  const RenderState *sa = _object->_state;
+  const RenderState *sb = other._object->_state;
+
+  if (sa != sb) {
+    // First, group objects by texture, since conventional wisdom is
+    // that texture changes are the most expensive state changes in a
+    // graphics context.
+    const TextureAttrib *ta = sa->get_texture();
+    const TextureAttrib *tb = sb->get_texture();
+    if (ta != tb) {
+      return ta < tb;
+    }
+
+    // Then, sort by all the other states, in no particular order,
+    // just as long as objects with identical state are all grouped
+    // together.
+    return sa < sb;
+  }
+
+  return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: CullBinStateSorted::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE CullBinStateSorted::
+CullBinStateSorted(const string &name, GraphicsStateGuardianBase *gsg) :
+  CullBin(name, gsg)
+{
+}

+ 87 - 0
panda/src/pgraph/cullBinStateSorted.cxx

@@ -0,0 +1,87 @@
+// Filename: cullBinStateSorted.cxx
+// Created by:  drose (22Mar05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "cullBinStateSorted.h"
+#include "graphicsStateGuardianBase.h"
+#include "geometricBoundingVolume.h"
+#include "cullableObject.h"
+#include "cullHandler.h"
+#include "pStatTimer.h"
+
+#include <algorithm>
+
+
+TypeHandle CullBinStateSorted::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: CullBinStateSorted::Destructor
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+CullBinStateSorted::
+~CullBinStateSorted() {
+  Objects::iterator oi;
+  for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
+    CullableObject *object = (*oi)._object;
+    delete object;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CullBinStateSorted::add_object
+//       Access: Public, Virtual
+//  Description: Adds a geom, along with its associated state, to
+//               the bin for rendering.
+////////////////////////////////////////////////////////////////////
+void CullBinStateSorted::
+add_object(CullableObject *object) {
+  _objects.push_back(ObjectData(object));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CullBinStateSorted::finish_cull
+//       Access: Public
+//  Description: Called after all the geoms have been added, this
+//               indicates that the cull process is finished for this
+//               frame and gives the bins a chance to do any
+//               post-processing (like sorting) before moving on to
+//               draw.
+////////////////////////////////////////////////////////////////////
+void CullBinStateSorted::
+finish_cull() {
+  PStatTimer timer(_cull_this_pcollector);
+  sort(_objects.begin(), _objects.end());
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: CullBinStateSorted::draw
+//       Access: Public
+//  Description: Draws all the geoms in the bin, in the appropriate
+//               order.
+////////////////////////////////////////////////////////////////////
+void CullBinStateSorted::
+draw() {
+  PStatTimer timer(_draw_this_pcollector);
+  Objects::const_iterator oi;
+  for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
+    CullableObject *object = (*oi)._object;
+    CullHandler::draw(object, _gsg);
+  }
+}
+

+ 86 - 0
panda/src/pgraph/cullBinStateSorted.h

@@ -0,0 +1,86 @@
+// Filename: cullBinStateSorted.h
+// Created by:  drose (22Mar05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef CULLBINSTATESORTED_H
+#define CULLBINSTATESORTED_H
+
+#include "pandabase.h"
+
+#include "cullBin.h"
+#include "geom.h"
+#include "transformState.h"
+#include "renderState.h"
+#include "pointerTo.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : CullBinStateSorted
+// Description : A specific kind of CullBin that sorts geometry to
+//               collect items of the same state together, so that
+//               minimal state changes are required on the GSG to
+//               render them.
+//
+//               This also sorts objects front-to-back within a
+//               particular state, to take advantage of hierarchical
+//               Z-buffer algorithms which can early-out when an
+//               object appears behind another one.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA CullBinStateSorted : public CullBin {
+public:
+  INLINE CullBinStateSorted(const string &name, GraphicsStateGuardianBase *gsg);
+  virtual ~CullBinStateSorted();
+
+  virtual void add_object(CullableObject *object);
+  virtual void finish_cull();
+  virtual void draw();
+
+private:
+  class ObjectData {
+  public:
+    INLINE ObjectData(CullableObject *object);
+    INLINE bool operator < (const ObjectData &other) const;
+    
+    CullableObject *_object;
+  };
+
+  typedef pvector<ObjectData> Objects;
+  Objects _objects;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    CullBin::init_type();
+    register_type(_type_handle, "CullBinStateSorted",
+                  CullBin::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "cullBinStateSorted.I"
+
+#endif
+
+
+  

+ 5 - 0
panda/src/pgraph/cullTraverser.cxx

@@ -36,6 +36,7 @@
 
 PStatCollector CullTraverser::_nodes_pcollector("Nodes");
 PStatCollector CullTraverser::_geom_nodes_pcollector("Nodes:GeomNodes");
+PStatCollector CullTraverser::_geoms_pcollector("Geoms");
 
 TypeHandle CullTraverser::_type_handle;
 
@@ -210,6 +211,7 @@ traverse_below(CullTraverserData &data) {
       
       // Get all the Geoms, with no decalling.
       int num_geoms = geom_node->get_num_geoms();
+      _geoms_pcollector.add_level(num_geoms);
       for (int i = 0; i < num_geoms; i++) {
         CullableObject *object = new CullableObject(data, geom_node, i);
         _cull_handler->record_object(object);
@@ -264,6 +266,7 @@ show_bounds(CullTraverserData &data) {
 
   PT(Geom) bounds_viz = make_bounds_viz(node->get_bound());
   if (bounds_viz != (Geom *)NULL) {
+    _geoms_pcollector.add_level(2);
     CullableObject *outer_viz = 
       new CullableObject(bounds_viz, get_bounds_outer_viz_state(), 
                          data._render_transform);
@@ -417,6 +420,7 @@ start_decal(const CullTraverserData &data) {
   CullableObject *object = separator;
   GeomNode *geom_node = DCAST(GeomNode, node);
   int num_geoms = geom_node->get_num_geoms();
+  _geoms_pcollector.add_level(num_geoms);
   for (int i = num_geoms - 1; i >= 0; i--) {
     object = new CullableObject(data, geom_node, i, object);
   }
@@ -474,6 +478,7 @@ r_get_decals(CullTraverserData &data, CullableObject *decals) {
       GeomNode *geom_node = DCAST(GeomNode, node);
       
       int num_geoms = geom_node->get_num_geoms();
+      _geoms_pcollector.add_level(num_geoms);
       for (int i = num_geoms - 1; i >= 0; i--) {
         decals = new CullableObject(data, geom_node, i, decals);
       }

+ 1 - 0
panda/src/pgraph/cullTraverser.h

@@ -89,6 +89,7 @@ public:
   // Statistics
   static PStatCollector _nodes_pcollector;
   static PStatCollector _geom_nodes_pcollector;
+  static PStatCollector _geoms_pcollector;
 
 private:
   void show_bounds(CullTraverserData &data);

+ 1 - 0
panda/src/pgraph/pgraph_composite1.cxx

@@ -19,6 +19,7 @@
 #include "cullBinFixed.cxx"
 #include "cullBinFrontToBack.cxx"
 #include "cullBinManager.cxx"
+#include "cullBinStateSorted.cxx"
 #include "cullBinUnsorted.cxx"
 #include "cullFaceAttrib.cxx"
 #include "cullHandler.cxx"

+ 1 - 0
panda/src/pstatclient/pStatProperties.cxx

@@ -165,6 +165,7 @@ static LevelCollectorProperties level_properties[] = {
   { 1, "Vertices:Display lists",           { 0.8, 0.5, 1.0 } },
   { 1, "Nodes",                            { 0.4, 0.2, 0.8 },  "", 500.0 },
   { 1, "Nodes:GeomNodes",                  { 0.8, 0.2, 0.0 } },
+  { 1, "Geoms",                            { 0.4, 0.8, 0.3 },  "", 500.0 },
   { 1, "Cull volumes",                     { 0.7, 0.6, 0.9 },  "", 500.0 },
   { 1, "Cull volumes:Transforms",          { 0.9, 0.6, 0.0 } },
   { 1, "State changes",                    { 1.0, 0.5, 0.2 },  "", 500.0 },