From 95db6ebacaa1c2a4c135a9ea97e5fba064f6a8e9 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 19 Dec 2011 23:52:06 +0000 Subject: [PATCH] GeomVertexFormat::maybe_align_columns_for_animation() --- panda/src/egg2pg/config_egg2pg.cxx | 15 ------- panda/src/egg2pg/config_egg2pg.h | 1 - panda/src/egg2pg/eggLoader.cxx | 50 ++++++------------------ panda/src/gobj/config_gobj.cxx | 21 +++++++++- panda/src/gobj/config_gobj.h | 1 + panda/src/gobj/geomVertexArrayFormat.cxx | 35 +++++++++++++++++ panda/src/gobj/geomVertexArrayFormat.h | 1 + panda/src/gobj/geomVertexFormat.cxx | 37 +++++++++++++++++- panda/src/gobj/geomVertexFormat.h | 2 + panda/src/grutil/rigidBodyCombiner.cxx | 1 + panda/src/pgraph/geomTransformer.cxx | 20 +--------- 11 files changed, 108 insertions(+), 76 deletions(-) diff --git a/panda/src/egg2pg/config_egg2pg.cxx b/panda/src/egg2pg/config_egg2pg.cxx index cf62cd742e..5cf3fa03d1 100644 --- a/panda/src/egg2pg/config_egg2pg.cxx +++ b/panda/src/egg2pg/config_egg2pg.cxx @@ -184,21 +184,6 @@ ConfigVariableInt egg_vertex_max_num_joints "more than this number of joints, the joints with the lesser membership " "value are ignored. Set this to -1 to allow any number of joints.")); -ConfigVariableBool egg_vertex_animation_align_16 -("egg-vertex-animation-align-16", -#ifdef LINMATH_ALIGN - true, -#else - false, -#endif - PRC_DESC("If this is true, then animated vertices will be created with 4-component " - "floats and aligned to 16-byte boundaries, to allow efficient vectorization " - "(e.g. SSE2) operations when computing animations. If this is false, " - "animated vertices will be packed as tightly as possible, in the normal way, " - "which will optimize the amount of memory that must be sent to the graphics " - "card, but prevent the use of SSE2 to calculate animation. This does not " - "affect unanimated vertices, which are always packed tightly.")); - ConfigureFn(config_egg2pg) { init_libegg2pg(); } diff --git a/panda/src/egg2pg/config_egg2pg.h b/panda/src/egg2pg/config_egg2pg.h index 527a096905..62fe95ce22 100644 --- a/panda/src/egg2pg/config_egg2pg.h +++ b/panda/src/egg2pg/config_egg2pg.h @@ -54,7 +54,6 @@ extern EXPCL_PANDAEGG ConfigVariableBool egg_emulate_bface; extern EXPCL_PANDAEGG ConfigVariableBool egg_preload_simple_textures; extern EXPCL_PANDAEGG ConfigVariableDouble egg_vertex_membership_quantize; extern EXPCL_PANDAEGG ConfigVariableInt egg_vertex_max_num_joints; -extern EXPCL_PANDAEGG ConfigVariableBool egg_vertex_animation_align_16; extern EXPCL_PANDAEGG void init_libegg2pg(); diff --git a/panda/src/egg2pg/eggLoader.cxx b/panda/src/egg2pg/eggLoader.cxx index 56895f2fe9..832fcf44e2 100644 --- a/panda/src/egg2pg/eggLoader.cxx +++ b/panda/src/egg2pg/eggLoader.cxx @@ -2212,37 +2212,16 @@ make_vertex_data(const EggRenderState *render_state, if (di != _vertex_pool_data.end()) { return (*di).second; } - - bool align_16 = false; - if (is_dynamic) { - align_16 = egg_vertex_animation_align_16; - } PT(GeomVertexArrayFormat) array_format = new GeomVertexArrayFormat; - if (align_16) { - // Enforce a 4-component float and a 16-byte alignment. - array_format->add_column - (InternalName::get_vertex(), 4, - Geom::NT_stdfloat, Geom::C_point, -1, 16); - } else { - // Allow a tightly-packed 3-component float. - array_format->add_column - (InternalName::get_vertex(), vertex_pool->get_num_dimensions(), - Geom::NT_stdfloat, Geom::C_point); - } + array_format->add_column + (InternalName::get_vertex(), vertex_pool->get_num_dimensions(), + Geom::NT_stdfloat, Geom::C_point); if (vertex_pool->has_normals()) { - if (align_16) { - // Enforce a 4-component float and a 16-byte alignment. - array_format->add_column - (InternalName::get_normal(), 4, - Geom::NT_stdfloat, Geom::C_vector, -1, 16); - } else { - // Allow a tightly-packed 3-component float. - array_format->add_column - (InternalName::get_normal(), 3, - Geom::NT_stdfloat, Geom::C_vector); - } + array_format->add_column + (InternalName::get_normal(), 3, + Geom::NT_stdfloat, Geom::C_vector); } if (!ignore_color) { @@ -2274,17 +2253,10 @@ make_vertex_data(const EggRenderState *render_state, PT(InternalName) iname_t = InternalName::get_tangent_name(name); PT(InternalName) iname_b = InternalName::get_binormal_name(name); - if (align_16) { - array_format->add_column - (iname_t, 4, Geom::NT_stdfloat, Geom::C_vector, -1, 16); - array_format->add_column - (iname_b, 4, Geom::NT_stdfloat, Geom::C_vector, -1, 16); - } else { - array_format->add_column - (iname_t, 3, Geom::NT_stdfloat, Geom::C_vector); - array_format->add_column - (iname_b, 3, Geom::NT_stdfloat, Geom::C_vector); - } + array_format->add_column + (iname_t, 3, Geom::NT_stdfloat, Geom::C_vector); + array_format->add_column + (iname_b, 3, Geom::NT_stdfloat, Geom::C_vector); } vector_string aux_names; @@ -2379,6 +2351,8 @@ make_vertex_data(const EggRenderState *render_state, name = character_maker->get_name(); } + temp_format->maybe_align_columns_for_animation(); + CPT(GeomVertexFormat) format = GeomVertexFormat::register_format(temp_format); diff --git a/panda/src/gobj/config_gobj.cxx b/panda/src/gobj/config_gobj.cxx index 0095971869..e1b247f1e8 100644 --- a/panda/src/gobj/config_gobj.cxx +++ b/panda/src/gobj/config_gobj.cxx @@ -282,8 +282,25 @@ ConfigVariableInt vertex_column_alignment "GeomVertexFormat. Setting this value globally could result in " "much needless wasted space in all vertex data objects, but it " "could be useful for simple experiments. Also see " - "egg-vertex-animation-align-16 for a variable that controls " - "this alignment for the vertex-animation columns only.")); + "vertex-animation-align-16 for a variable that controls " + "this alignment for the vertex animation columns only.")); + +ConfigVariableBool vertex_animation_align_16 +("vertex-animation-align-16", +#ifdef LINMATH_ALIGN + true, +#else + false, +#endif + PRC_DESC("If this is true, then animated vertices will be created with 4-component " + "floats and aligned to 16-byte boundaries, to allow efficient vectorization " + "(e.g. SSE2) operations when computing animations. If this is false, " + "animated vertices will be packed as tightly as possible, in the normal way, " + "which will optimize the amount of memory that must be sent to the graphics " + "card, but prevent the use of SSE2 to calculate animation. This does not " + "affect unanimated vertices, which are always packed tightly. This also " + "impacts only vertex formats created within Panda subsystems; custom " + "vertex formats are not affected.")); ConfigVariableEnum textures_power_2 ("textures-power-2", ATS_down, diff --git a/panda/src/gobj/config_gobj.h b/panda/src/gobj/config_gobj.h index 4e2e08d8cd..b5aa5571e5 100644 --- a/panda/src/gobj/config_gobj.h +++ b/panda/src/gobj/config_gobj.h @@ -65,6 +65,7 @@ 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 ConfigVariableBool vertex_animation_align_16; extern EXPCL_PANDA_GOBJ ConfigVariableEnum textures_power_2; extern EXPCL_PANDA_GOBJ ConfigVariableEnum textures_square; diff --git a/panda/src/gobj/geomVertexArrayFormat.cxx b/panda/src/gobj/geomVertexArrayFormat.cxx index 5c688524f3..809771788e 100644 --- a/panda/src/gobj/geomVertexArrayFormat.cxx +++ b/panda/src/gobj/geomVertexArrayFormat.cxx @@ -364,6 +364,41 @@ pack_columns() { } } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexArrayFormat::align_columns_for_animation +// Access: Published +// Description: Reprocesses the columns in the format to align the +// C_point and C_vector columns to 16-byte boundaries to +// allow for the more efficient SSE2 operations +// (assuming SSE2 is enabled in the build). +// +// The caller is responsible for testing +// vertex_animation_align_16 to decide whether to call +// this method. +//////////////////////////////////////////////////////////////////// +void GeomVertexArrayFormat:: +align_columns_for_animation() { + nassertv(!_is_registered); + + Columns orig_columns; + orig_columns.swap(_columns); + clear_columns(); + + Columns::const_iterator ci; + for (ci = orig_columns.begin(); ci != orig_columns.end(); ++ci) { + GeomVertexColumn *column = (*ci); + if ((column->get_contents() == C_point || column->get_contents() == C_vector) && + (column->get_numeric_type() == NT_float32 || column->get_numeric_type() == NT_float64) && + column->get_num_components() >= 3) { + add_column(column->get_name(), 4, column->get_numeric_type(), column->get_contents(), -1, 16); + } else { + add_column(column->get_name(), column->get_num_components(), + column->get_numeric_type(), column->get_contents()); + } + } +} + + //////////////////////////////////////////////////////////////////// // Function: GeomVertexArrayFormat::get_column // Access: Published diff --git a/panda/src/gobj/geomVertexArrayFormat.h b/panda/src/gobj/geomVertexArrayFormat.h index 16203047fa..2a8867428b 100644 --- a/panda/src/gobj/geomVertexArrayFormat.h +++ b/panda/src/gobj/geomVertexArrayFormat.h @@ -97,6 +97,7 @@ PUBLISHED: void remove_column(const InternalName *name); void clear_columns(); void pack_columns(); + void align_columns_for_animation(); INLINE int get_num_columns() const; INLINE const GeomVertexColumn *get_column(int i) const; diff --git a/panda/src/gobj/geomVertexFormat.cxx b/panda/src/gobj/geomVertexFormat.cxx index a665234b32..9562a59b74 100644 --- a/panda/src/gobj/geomVertexFormat.cxx +++ b/panda/src/gobj/geomVertexFormat.cxx @@ -566,6 +566,41 @@ pack_columns() { } } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexFormat::align_columns_for_animation +// Access: Published +// Description: Reprocesses the columns in the format to align the +// C_point and C_vector columns to 16-byte boundaries to +// allow for the more efficient SSE2 operations +// (assuming SSE2 is enabled in the build). +// +// Also see maybe_align_columns_for_animation(). +//////////////////////////////////////////////////////////////////// +void GeomVertexFormat:: +align_columns_for_animation() { + nassertv(!_is_registered); + Arrays::iterator ai; + for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) { + if ((*ai)->is_registered()) { + (*ai) = new GeomVertexArrayFormat(*(*ai)); + } + (*ai)->align_columns_for_animation(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexFormat::maybe_align_columns_for_animation +// Access: Published +// Description: Calls align_columns_for_animation() if this format's +// AnimationSpec indicates that it contains animated +// vertices, and if vertex-animation-align-16 is true. +//////////////////////////////////////////////////////////////////// +void GeomVertexFormat:: +maybe_align_columns_for_animation() { + if (_animation.get_animation_type() == AT_panda && vertex_animation_align_16) { + align_columns_for_animation(); + } +} //////////////////////////////////////////////////////////////////// // Function: GeomVertexFormat::output @@ -608,7 +643,7 @@ write(ostream &out, int indent_level) const { if (_animation.get_animation_type() != AT_none) { indent(out, indent_level) - << "anim " << _animation; + << "anim " << _animation << "\n"; } } diff --git a/panda/src/gobj/geomVertexFormat.h b/panda/src/gobj/geomVertexFormat.h index e42f10103c..10e4cf992c 100644 --- a/panda/src/gobj/geomVertexFormat.h +++ b/panda/src/gobj/geomVertexFormat.h @@ -100,6 +100,8 @@ PUBLISHED: void remove_column(const InternalName *name); void pack_columns(); + void align_columns_for_animation(); + void maybe_align_columns_for_animation(); INLINE int get_num_points() const; INLINE const InternalName *get_point(int n) const; diff --git a/panda/src/grutil/rigidBodyCombiner.cxx b/panda/src/grutil/rigidBodyCombiner.cxx index dc533c62cf..ef9584f5a1 100644 --- a/panda/src/grutil/rigidBodyCombiner.cxx +++ b/panda/src/grutil/rigidBodyCombiner.cxx @@ -252,6 +252,7 @@ convert_vd(const VertexTransform *transform, const GeomVertexData *orig) { GeomVertexAnimationSpec spec; spec.set_panda(); format->set_animation(spec); + format->maybe_align_columns_for_animation(); CPT(GeomVertexFormat) new_format = GeomVertexFormat::register_format(format); CPT(GeomVertexData) converted = orig->convert_to(new_format); diff --git a/panda/src/pgraph/geomTransformer.cxx b/panda/src/pgraph/geomTransformer.cxx index 0c2fbd6b28..60e8d5b151 100644 --- a/panda/src/pgraph/geomTransformer.cxx +++ b/panda/src/pgraph/geomTransformer.cxx @@ -131,25 +131,7 @@ transform_vertices(Geom *geom, const LMatrix4 &mat) { if (new_data._vdata.is_null()) { // We have not yet converted these vertices. Do so now. PT(GeomVertexData) new_vdata = new GeomVertexData(*sv._vertex_data); - CPT(GeomVertexFormat) format = new_vdata->get_format(); - - int ci; - for (ci = 0; ci < format->get_num_points(); ci++) { - GeomVertexRewriter data(new_vdata, format->get_point(ci)); - - while (!data.is_at_end()) { - const LPoint3 &point = data.get_data3(); - data.set_data3(point * mat); - } - } - for (ci = 0; ci < format->get_num_vectors(); ci++) { - GeomVertexRewriter data(new_vdata, format->get_vector(ci)); - - while (!data.is_at_end()) { - const LVector3 &vector = data.get_data3(); - data.set_data3(normalize(vector * mat)); - } - } + new_vdata->transform_vertices(mat); new_data._vdata = new_vdata; }