[info-performer] pfGeoArray redesign for Performer 3.2

Date view Thread view Subject view Author view

From: Stace Peterson (stacep++at++sgi.com)
Date: 02/01/2005 11:21:02


There have been a few questions recently about the use of pfGeoArrays,
and so we'd like to write a quick bit about them to hopefully answer
some of these and provide some help and direction to those currently
using them or considering it.

First, the big question is when to use pfGeoArrays compared to
pfGeoSets. There are two benefits of pfGeoArrays:

1) On modern hardware (SGI's Onyx4 or Prism systems, PCs with recent
graphics cards), appllications will typically see a performance increase
when using pfGeoArrays. Older hardware which doesn't support either the
vertex_buffer_object or vertex_array_object extensions will typically
not see any performance benefit (and may even be slower). This benefit
is only for static geometry. For geometry which is going to change
every frame, the cost of resending the vertex data to the card and
binding new buffers is at least as expensive as simply rendering the
object immediate mode usually. In this case, it may be more convenient
to simply use pfGeoSet (typically, fluxed geoset) objects.

2) Improved support for per-vertex data for use in vertex / fragment
programs (through either the pfVertexProgram / pfFragmentProgram objects
or the pfShaderProgram object).

Using the geoa and gopt pseudo-loaders is an easy way to experiment with
using pfGeoArrays on your system and determining whether or not they may
be beneficial.

Secondly, there are some changes in the pfGeoArray interface from 3.1 to
3.2. In the previous version, all attribute types were global, and
needed to be explicitly added to a pfGeoArray object (through the
queryAttrType and addAttrType functions). Now, the interface is more
similar to the pfGeoSet interface, in which the user must simply create
a new pfGeoArray, and then call setAttr() with the relevant tokens. The
relevant functions look like:

pfVertexAttr* pfGeoArray::setAttr(int attrType, int size,
    GLenum type, GLenum stride, void *ptr);

pfVertexAttr* setMultiAttr(int attrType, int stage, int size,
    GLenum type, GLenum stride, void *ptr);

where attrType is one of:

PFGA_COORD_ARRAY
PFGA_NORMAL_ARRAY
PFGA_COLOR_ARRAY
PFGA_TEX_ARRAY
PFGA_GENERIC_ARRAY

These are slightly different from the pfGeoSet versions, but operate
similarily. Additionally, in Performer 3.2, pfVertexAttr objects are
per pfGeoArray, and not global. See src/pguide/libpr/C++/geoArray.C for
a full example.

Thirdly, the pfGeoArray class now has better support of the pfGeoSet
interface. For various reasons, it is useful for pfGeoArray to be a
child of the pfGeoSet class, but previously many of the pfGeoSet
functions did not interact correctly with pfGeoArray data. Many of
these problems have been cleared, such that for many applications, all
that will need to be changed is the call to the constructor (i.e.,
change gs = new pfGeoSet() to gs = new pfGeoArray()). However,
pfGeoArrays do not directly support bind types PFGS_OVERALL or
PFGS_PER_PRIM, and do not support per attribute indexing. We do provide
some intelligent unrolling of vertex data and indices, however, in these
cases it may be preferable to convert pfGeoSets to pfGeoArrays by using
the pfdOptimizeGraph pipeline (and this provides options for enabling
several optimizations as well). Database conversions can be done easily
by using either the geoa (conversion to indexed triangle pfGeoArrays) or
gopt (graph optimizer with many options - see man gopt) pseudo-loaders.

Fourthly, rendering pfGeoArrays is often touchier than rendering
pfGeoSets. Using the appropriate data types, primitive types and sizes
can have a significant impact on performance on all modern hardware.
Currently, it tends to be faster to build larger pfGeoArrays even when
decreasing the effectiveness of culling. Small pfGeoArrays can be very
costly due to the overhead of rendering each object. Additionally,
using small stripped primitives can also be costly. Using the
pfdOptimizeGraph pipeline to merge pfGeoArrays, change to non-stripped
primitives or join stripped primitives together, and to convert
pfGeoSets to pfGeoArrays can make big differences in performance. On
some systems, a direct conversion shows no improvement, while using the
correct options can make a big difference. On SGI systems, I suggest
using the following options with the gopt pseudo loader:

pfconv
xxx.pfb.indexedtris,cachelength=12,nobreakup,spatialize,geoarray.gopt
xxx_index.pfb

for indexed triangles or

pfconv
xxx.pfb.aggressive,cachelength=12,nobreakup,spatialize,indexed,geoarray.gopt
xxx_agg.pfb

for joined triangle strips. The latter typically performs better,
especially on databases which strip up well (where triangle strips can
be made up of many triangles). I would suggest playing with the various
options using available databases and perfly to get a feel for their
use.

Finally, we are still performing on-going enhancement to the behavior of
many of these functions and trying to improve rendering performance for
general purpose use of pfGeoArrays, so please let us know if there are
more questions, problems or suggestions, and we will do our best to
respond to them.

Thanks,
Stace Peterson

-- 
------------------------------------------------------------------
Stace Peterson                                      stacep++at++sgi.com
Silicon Graphics, Inc.                              (650) 933-2323


Date view Thread view Subject view Author view

This archive was generated by hypermail 2b29 : Tue Feb 01 2005 - 11:21:14 PST