소스 검색

add vertex-column-alignment

David Rose 14 년 전
부모
커밋
7de805989f

+ 6 - 0
panda/src/gobj/config_gobj.cxx

@@ -272,6 +272,12 @@ ConfigVariableBool vertices_float64
           "driver to downsample the vertices at load time, making everything "
           "slower."));
 
+ConfigVariableInt vertex_column_alignment
+("vertex-column-alignment", 0,
+ PRC_DESC("This specifies the default byte alignment for each column of "
+          "data within a GeomVertexData when it is assembled using the default "
+          "interfaces.  See GeomVertexFormat::set_column_alignment()."));
+
 ConfigVariableEnum<AutoTextureScale> textures_power_2
 ("textures-power-2", ATS_down,
  PRC_DESC("Specify whether textures should automatically be constrained to "

+ 1 - 0
panda/src/gobj/config_gobj.h

@@ -64,6 +64,7 @@ extern EXPCL_PANDA_GOBJ ConfigVariableBool preserve_triangle_strips;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool dump_generated_shaders;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool enforce_attrib_lock;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool vertices_float64;
+extern EXPCL_PANDA_GOBJ ConfigVariableInt vertex_column_alignment;
 
 extern EXPCL_PANDA_GOBJ ConfigVariableEnum<AutoTextureScale> textures_power_2;
 extern EXPCL_PANDA_GOBJ ConfigVariableEnum<AutoTextureScale> textures_square;

+ 0 - 13
panda/src/gobj/geomPrimitive.I

@@ -415,19 +415,6 @@ add_vertices(int v1, int v2, int v3, int v4) {
   add_vertex(v4);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: GeomPrimitive::get_index_format
-//       Access: Public
-//  Description: Returns a registered format appropriate for using to
-//               store the index table.
-////////////////////////////////////////////////////////////////////
-INLINE CPT(GeomVertexArrayFormat) GeomPrimitive::
-get_index_format() const {
-  return GeomVertexArrayFormat::register_format
-    (new GeomVertexArrayFormat(InternalName::get_index(), 1, 
-                               get_index_type(), C_index));
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomPrimitive::make_index_data
 //       Access: Public

+ 16 - 0
panda/src/gobj/geomPrimitive.cxx

@@ -1416,6 +1416,22 @@ release_all() {
   return num_freed;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomPrimitive::get_index_format
+//       Access: Public
+//  Description: Returns a registered format appropriate for using to
+//               store the index table.
+////////////////////////////////////////////////////////////////////
+CPT(GeomVertexArrayFormat) GeomPrimitive::
+get_index_format() const {
+  PT(GeomVertexArrayFormat) format = new GeomVertexArrayFormat;
+  // It's important that the index format not attempt to have any kind
+  // of SSE2 alignment or whatever.  It needs to be tightly packed.
+  format->set_column_alignment(1);
+  format->add_column(InternalName::get_index(), 1, get_index_type(), C_index);
+  return GeomVertexArrayFormat::register_format(format);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomPrimitive::clear_prepared
 //       Access: Private

+ 1 - 1
panda/src/gobj/geomPrimitive.h

@@ -186,7 +186,7 @@ public:
   bool release(PreparedGraphicsObjects *prepared_objects);
   int release_all();
 
-  INLINE CPT(GeomVertexArrayFormat) get_index_format() const;
+  CPT(GeomVertexArrayFormat) get_index_format() const;
   INLINE PT(GeomVertexArrayData) make_index_data() const;
 
 private:

+ 45 - 1
panda/src/gobj/geomVertexArrayFormat.I

@@ -60,14 +60,58 @@ get_stride() const {
 //     Function: GeomVertexArrayFormat::set_stride
 //       Access: Published
 //  Description: Changes the total number of bytes reserved in the
-//               array for each vertex.
+//               array for each vertex.  You may not reduce this below
+//               get_total_bytes(), but you may increase it
+//               arbitrarily.
 ////////////////////////////////////////////////////////////////////
 INLINE void GeomVertexArrayFormat::
 set_stride(int stride) {
   nassertv(!_is_registered);
+  nassertv(_stride >= _total_bytes);
   _stride = stride;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexArrayFormat::get_column_alignment
+//       Access: Published
+//  Description: See set_column_alignment().
+////////////////////////////////////////////////////////////////////
+INLINE int GeomVertexArrayFormat::
+get_column_alignment() const {
+  return _column_alignment;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexArrayFormat::set_column_alignment
+//       Access: Published
+//  Description: This specifies the byte alignment for each
+//               column of data within the format when add_column() is
+//               subsequently called with default parameters.
+//               Normally this is 0 or 1 to specify no particular
+//               alignment, but you may specify a higher number, for
+//               instace 4 to guarantee that all columns start at a
+//               word alignment, or 16 to align all columns for SSE2
+//               processing.  This will introduce unused bytes between
+//               columns as needed to guarantee the requested
+//               alignment.  
+//
+//               Note that this does not change existing columns, only
+//               subsequent columns; and if you specify the start byte
+//               explicitly in add_column(), it will override this
+//               setting.  Note also that there is no point in
+//               exceeding the memory alignment of Panda3D itself,
+//               which is compiled into Panda and can be determined by
+//               MemoryHook::get_memory_alignment().
+//
+//               Also see the config variable vertex-column-alignment
+//               for a way to change the global default.
+////////////////////////////////////////////////////////////////////
+INLINE void GeomVertexArrayFormat::
+set_column_alignment(int column_alignment) {
+  nassertv(!_is_registered);
+  _column_alignment = column_alignment;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomVertexArrayFormat::get_total_bytes
 //       Access: Published

+ 32 - 2
panda/src/gobj/geomVertexArrayFormat.cxx

@@ -34,6 +34,7 @@ GeomVertexArrayFormat::
 GeomVertexArrayFormat() :
   _is_registered(false),
   _stride(0),
+  _column_alignment(vertex_column_alignment),
   _total_bytes(0),
   _pad_to(1),
   _columns_unsorted(false)
@@ -51,6 +52,7 @@ GeomVertexArrayFormat(InternalName *name0, int num_components0,
                       GeomVertexArrayFormat::Contents contents0) :
   _is_registered(false),
   _stride(0),
+  _column_alignment(vertex_column_alignment),
   _total_bytes(0),
   _pad_to(1),
   _columns_unsorted(false)
@@ -72,6 +74,7 @@ GeomVertexArrayFormat(InternalName *name0, int num_components0,
                       GeomVertexArrayFormat::Contents contents1) :
   _is_registered(false),
   _stride(0),
+  _column_alignment(vertex_column_alignment),
   _total_bytes(0),
   _pad_to(1),
   _columns_unsorted(false)
@@ -97,6 +100,7 @@ GeomVertexArrayFormat(InternalName *name0, int num_components0,
                       GeomVertexArrayFormat::Contents contents2) :
   _is_registered(false),
   _stride(0),
+  _column_alignment(vertex_column_alignment),
   _total_bytes(0),
   _pad_to(1),
   _columns_unsorted(false)
@@ -126,6 +130,7 @@ GeomVertexArrayFormat(InternalName *name0, int num_components0,
                       GeomVertexArrayFormat::Contents contents3) :
   _is_registered(false),
   _stride(0),
+  _column_alignment(vertex_column_alignment),
   _total_bytes(0),
   _pad_to(1),
   _columns_unsorted(false)
@@ -145,6 +150,7 @@ GeomVertexArrayFormat::
 GeomVertexArrayFormat(const GeomVertexArrayFormat &copy) :
   _is_registered(false),
   _stride(copy._stride),
+  _column_alignment(copy._column_alignment),
   _total_bytes(copy._total_bytes),
   _pad_to(copy._pad_to),
   _columns_unsorted(copy._columns_unsorted)
@@ -164,6 +170,7 @@ void GeomVertexArrayFormat::
 operator = (const GeomVertexArrayFormat &copy) {
   nassertv(!_is_registered);
   _stride = copy._stride;
+  _column_alignment = copy._column_alignment;
   _total_bytes = copy._total_bytes;
   _pad_to = copy._pad_to;
 
@@ -233,6 +240,10 @@ add_column(InternalName *name, int num_components,
            GeomVertexArrayFormat::Contents contents, int start) {
   if (start < 0) {
     start = _total_bytes;
+    if (_column_alignment > 1) {
+      // Round up to the next multiple of _column_alignment.
+      start = ((start + (_column_alignment - 1)) / _column_alignment) * _column_alignment;
+    }
 
     GeomVertexColumn temp_column
       (name, num_components, numeric_type, contents, 0);
@@ -275,9 +286,19 @@ add_column(const GeomVertexColumn &column) {
     orig_column = get_column(column.get_start(), column.get_total_bytes());
   }
 
-  _total_bytes = max(_total_bytes, column.get_start() + column.get_total_bytes());
+  int column_bytes = column.get_total_bytes();
+  if (_column_alignment > 1 && (column.get_start() % _column_alignment == 0)) {
+    // Round up to the next multiple of _column_alignment.
+    column_bytes = ((column_bytes + _column_alignment - 1) / _column_alignment) * _column_alignment;
+  }
+
+  _total_bytes = max(_total_bytes, column.get_start() + column_bytes);
   _pad_to = max(_pad_to, column.get_component_bytes());
-  _stride = max(_stride, ((_total_bytes + _pad_to - 1) / _pad_to) * _pad_to);
+  _stride = max(_stride, _total_bytes);
+  _stride = ((_stride + _pad_to - 1) / _pad_to) * _pad_to;
+  if (_column_alignment > 1) {
+    _stride = ((_stride + _column_alignment - 1) / _column_alignment) * _column_alignment;
+  }
 
   GeomVertexColumn *new_column = new GeomVertexColumn(column);
 
@@ -554,6 +575,14 @@ compare_to(const GeomVertexArrayFormat &other) const {
   if (_stride != other._stride) {
     return _stride - other._stride;
   }
+  /*
+    // We don't compare column_alignment.  That's a setting used only
+    // when constructing the format, and no longer relevant after it's
+    // been constructed.
+  if (_column_alignment != other._column_alignment) {
+    return _column_alignment - other._column_alignment;
+  }
+  */
   if (_total_bytes != other._total_bytes) {
     return _total_bytes - other._total_bytes;
   }
@@ -731,6 +760,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
   TypedWritableReferenceCount::fillin(scan, manager);
   nassertv(!_is_registered);
 
+  // Maybe we should record _column_alignment, but we don't.
   _stride = scan.get_uint16();
   _total_bytes = scan.get_uint16();
   _pad_to = scan.get_uint8();

+ 4 - 0
panda/src/gobj/geomVertexArrayFormat.h

@@ -85,6 +85,9 @@ PUBLISHED:
   INLINE int get_stride() const;
   INLINE void set_stride(int stride);
 
+  INLINE int get_column_alignment() const;
+  INLINE void set_column_alignment(int column_alignment);
+
   INLINE int get_total_bytes() const;
   INLINE int get_pad_to() const;
 
@@ -128,6 +131,7 @@ private:
 
   bool _is_registered;
   int _stride;
+  int _column_alignment;
   int _total_bytes;
   int _pad_to;