GeomVertexFormat::maybe_align_columns_for_animation()

This commit is contained in:
David Rose 2011-12-19 23:52:06 +00:00
parent cb3b1423c0
commit 95db6ebaca
11 changed files with 108 additions and 76 deletions

View File

@ -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();
}

View File

@ -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();

View File

@ -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);

View File

@ -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<AutoTextureScale> textures_power_2
("textures-power-2", ATS_down,

View File

@ -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<AutoTextureScale> textures_power_2;
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<AutoTextureScale> textures_square;

View File

@ -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

View File

@ -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;

View File

@ -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";
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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;
}