mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
micro-optimize inner vertex loop
This commit is contained in:
parent
afc63b5844
commit
4c90448b95
@ -99,10 +99,14 @@ const int VERT_BUFFER_SIZE = (32*6*1024L);
|
||||
TypeHandle DXGraphicsStateGuardian::_type_handle;
|
||||
|
||||
// bit masks used for drawing primitives
|
||||
#define PER_TEXCOORD 0x8
|
||||
#define PER_COLOR 0x4
|
||||
#define PER_NORMAL 0x2
|
||||
#define PER_COORD 0x1
|
||||
// bitmask type: normal=0x1,color=0x2,texcoord=0x4
|
||||
typedef enum { NothingSet=0,NormalOnly,ColorOnly,Normal_Color,TexCoordOnly,
|
||||
Normal_TexCoord,Color_TexCoord,Normal_Color_TexCoord
|
||||
} DrawLoopFlags;
|
||||
|
||||
#define PER_NORMAL NormalOnly
|
||||
#define PER_COLOR ColorOnly
|
||||
#define PER_TEXCOORD TexCoordOnly
|
||||
|
||||
// technically DX7's front-end has no limit on the number of lights, but it's simpler for
|
||||
// this implementation to set a small GL-like limit to make the light array traversals short
|
||||
@ -1809,6 +1813,16 @@ draw_prim_setup(const Geom *geom) {
|
||||
}}
|
||||
|
||||
////////
|
||||
|
||||
// this stuff should eventually replace the iterators below
|
||||
geom->get_coords(_coords,_vindexes);
|
||||
if(_vindexes!=NULL) {
|
||||
_pCurCoordIndex = &_vindexes[0];
|
||||
} else {
|
||||
_pCurCoord = &_coords[0];
|
||||
}
|
||||
|
||||
///////////////
|
||||
|
||||
vi = geom->make_vertex_iterator();
|
||||
_curFVFflags = D3DFVF_XYZ;
|
||||
@ -1846,10 +1860,21 @@ draw_prim_setup(const Geom *geom) {
|
||||
p_normal = geom->get_next_normal(ni); // set overall normal if there is one
|
||||
}
|
||||
|
||||
if (geom->get_binding(G_TEXCOORD) != G_OFF) {
|
||||
ti = geom->make_texcoord_iterator();
|
||||
_curFVFflags |= (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
|
||||
vertex_size += sizeof(float) * 2;
|
||||
|
||||
GeomBindType TexCoordBinding;
|
||||
geom->get_texcoords(_texcoords,TexCoordBinding,_texcoord_indexes);
|
||||
if (TexCoordBinding != G_OFF) {
|
||||
|
||||
// used by faster path
|
||||
if(_texcoord_indexes!=NULL) {
|
||||
_pCurTexCoordIndex = &_texcoord_indexes[0];
|
||||
} else {
|
||||
_pCurTexCoord = &_texcoords[0];
|
||||
}
|
||||
|
||||
ti = geom->make_texcoord_iterator();
|
||||
_curFVFflags |= (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
|
||||
vertex_size += sizeof(float) * 2;
|
||||
}
|
||||
|
||||
// If we have per-vertex colors or normals, we need smooth shading.
|
||||
@ -1903,36 +1928,34 @@ wants_colors() const {
|
||||
// for component normals and color
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian::
|
||||
draw_prim_inner_loop(int nVerts, const Geom *geom, DWORD perFlags) {
|
||||
|
||||
draw_prim_inner_loop(int nVerts, const Geom *geom, ushort perFlags) {
|
||||
Vertexf NextVert;
|
||||
perFlags &= ~PER_COORD; // should always be set anyway
|
||||
|
||||
for(;nVerts > 0;nVerts--) {
|
||||
|
||||
// coord info will always be _perVertex
|
||||
GET_NEXT_VERTEX(NextVert); // need to optimize these
|
||||
add_to_FVFBuf((void *)&NextVert, sizeof(D3DVECTOR));
|
||||
|
||||
if(perFlags==0xC) {
|
||||
// break out the common case first
|
||||
if(perFlags==(ushort)TexCoordOnly) {
|
||||
// break out the common case (for animated chars) 1st
|
||||
GET_NEXT_TEXCOORD();
|
||||
GET_NEXT_COLOR();
|
||||
} else {
|
||||
switch (perFlags) {
|
||||
case 0x4:
|
||||
switch (DrawLoopFlags(perFlags)) {
|
||||
case Color_TexCoord:
|
||||
GET_NEXT_TEXCOORD();
|
||||
case ColorOnly:
|
||||
GET_NEXT_COLOR();
|
||||
break;
|
||||
case 0x6:
|
||||
case Normal_Color:
|
||||
GET_NEXT_COLOR();
|
||||
case 0x2:
|
||||
case NormalOnly:
|
||||
GET_NEXT_NORMAL();
|
||||
break;
|
||||
case 0xE:
|
||||
case Normal_Color_TexCoord:
|
||||
GET_NEXT_COLOR();
|
||||
case 0xA:
|
||||
case Normal_TexCoord:
|
||||
GET_NEXT_NORMAL();
|
||||
case 0x8:
|
||||
// case TexCoordOnly:
|
||||
GET_NEXT_TEXCOORD();
|
||||
break;
|
||||
}
|
||||
@ -1947,6 +1970,54 @@ draw_prim_inner_loop(int nVerts, const Geom *geom, DWORD perFlags) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian::draw_prim_inner_loop_coordtexonly
|
||||
// Access: Private
|
||||
// Description: FastPath loop used by animated character data
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian::
|
||||
draw_prim_inner_loop_coordtexonly(int nVerts, const Geom *geom) {
|
||||
// inc'ing local ptrs avoids 'this' ptr derefs for member fields
|
||||
Vertexf *pCurVert = _pCurCoord;
|
||||
ushort *pCurVertIndex = _pCurCoordIndex;
|
||||
TexCoordf *pCurTexCoord = _pCurTexCoord;
|
||||
ushort *pCurTexCoordIndex = _pCurTexCoordIndex;
|
||||
char *LocalFvfBufPtr=_pCurFvfBufPtr;
|
||||
DWORD cur_color = _curD3Dcolor;
|
||||
bool bDoIndexedTexCoords = (_texcoord_indexes != NULL);
|
||||
bool bDoIndexedCoords = (_vindexes != NULL);
|
||||
|
||||
for(;nVerts > 0;nVerts--) {
|
||||
if(bDoIndexedCoords) {
|
||||
memcpy(LocalFvfBufPtr,(void*)&_coords[*pCurVertIndex],sizeof(D3DVECTOR));
|
||||
pCurVertIndex++;
|
||||
} else {
|
||||
memcpy(LocalFvfBufPtr,(void*)pCurVert,sizeof(D3DVECTOR));
|
||||
pCurVert++;
|
||||
}
|
||||
|
||||
LocalFvfBufPtr+=sizeof(D3DVECTOR);
|
||||
|
||||
*((DWORD *)LocalFvfBufPtr) = cur_color;
|
||||
LocalFvfBufPtr += sizeof(DWORD);
|
||||
|
||||
if(bDoIndexedTexCoords) {
|
||||
memcpy(LocalFvfBufPtr,(void*)&_texcoords[*pCurTexCoordIndex],sizeof(TexCoordf));
|
||||
pCurTexCoordIndex++;
|
||||
} else {
|
||||
memcpy(LocalFvfBufPtr,(void*)pCurTexCoord,sizeof(TexCoordf));
|
||||
pCurTexCoord++;
|
||||
}
|
||||
LocalFvfBufPtr+=sizeof(TexCoordf);
|
||||
}
|
||||
|
||||
_pCurFvfBufPtr=LocalFvfBufPtr;
|
||||
_pCurCoord = pCurVert;
|
||||
_pCurCoordIndex = pCurVertIndex;
|
||||
_pCurTexCoord = pCurTexCoord;
|
||||
_pCurTexCoordIndex = pCurTexCoordIndex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian::draw_point
|
||||
// Access: Public, Virtual
|
||||
@ -2016,9 +2087,8 @@ draw_point(GeomPoint *geom, GeomContext *gc) {
|
||||
// values (may only be possible to handle certain cases without reverting to old pipeline)
|
||||
if (GeomVrtFmt!=FlatVerts) {
|
||||
|
||||
_perVertex = PER_COORD;
|
||||
_perVertex = 0x0;
|
||||
_perPrim = 0;
|
||||
if (geom->get_binding(G_COORD) == G_PER_VERTEX) _perVertex |= PER_COORD;
|
||||
if (geom->get_binding(G_NORMAL) == G_PER_VERTEX) _perVertex |= PER_NORMAL;
|
||||
if (geom->get_binding(G_COLOR) == G_PER_VERTEX) _perVertex |= PER_COLOR;
|
||||
|
||||
@ -2123,9 +2193,9 @@ draw_line(GeomLine* geom, GeomContext *gc) {
|
||||
}
|
||||
|
||||
assert(geom->get_binding(G_COORD) == G_PER_VERTEX);
|
||||
_perVertex = PER_COORD;
|
||||
_perVertex = 0x0;
|
||||
_perPrim = _perComp = 0x0;
|
||||
|
||||
_perPrim = _perComp = 0;
|
||||
switch(geom->get_binding(G_NORMAL)) {
|
||||
case G_PER_VERTEX:
|
||||
_perVertex |= PER_NORMAL;
|
||||
@ -2226,7 +2296,7 @@ draw_linestrip_base(Geom* geom, GeomContext *gc, bool bConnectEnds) {
|
||||
}
|
||||
|
||||
assert(geom->get_binding(G_COORD) == G_PER_VERTEX);
|
||||
_perVertex = PER_COORD;
|
||||
_perVertex = 0x0;
|
||||
|
||||
_perPrim = _perComp = 0;
|
||||
switch(geom->get_binding(G_NORMAL)) {
|
||||
@ -2252,6 +2322,7 @@ draw_linestrip_base(Geom* geom, GeomContext *gc, bool bConnectEnds) {
|
||||
}
|
||||
|
||||
size_t vertex_size = draw_prim_setup(geom);
|
||||
ushort perFlags = _perVertex | _perComp;
|
||||
|
||||
for (int i = 0; i < nPrims; i++) {
|
||||
if (_perPrim & PER_COLOR) {
|
||||
@ -2260,19 +2331,17 @@ draw_linestrip_base(Geom* geom, GeomContext *gc, bool bConnectEnds) {
|
||||
|
||||
int nVerts;
|
||||
|
||||
if(plen==NULL) {
|
||||
nVerts=4; // we've been called by draw_quad, which has no lengths array
|
||||
} else {
|
||||
if(plen!=NULL) {
|
||||
nVerts= *(plen++);
|
||||
nassertv(nVerts >= 2);
|
||||
} else {
|
||||
nVerts=4; // we've been called by draw_quad, which has no lengths array
|
||||
}
|
||||
|
||||
nassertv(_pCurFvfBufPtr == NULL); // make sure the storage pointer is clean.
|
||||
nassertv(nVerts * vertex_size < VERT_BUFFER_SIZE);
|
||||
_pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't
|
||||
|
||||
DWORD perFlags = _perVertex | _perComp;
|
||||
|
||||
draw_prim_inner_loop(nVerts, geom, perFlags);
|
||||
|
||||
if(bConnectEnds) {
|
||||
@ -2830,15 +2899,21 @@ draw_tri(GeomTri *geom, GeomContext *gc) {
|
||||
if (GeomVrtFmt!=FlatVerts) {
|
||||
// this is the old geom setup, it reformats every vtx into an output array passed to d3d
|
||||
|
||||
_perVertex = PER_COORD;
|
||||
_perVertex = 0x0;
|
||||
_perPrim = 0x0;
|
||||
|
||||
if (NormalBinding == G_PER_VERTEX) _perVertex |= PER_NORMAL;
|
||||
if (ColorBinding == G_PER_VERTEX) _perVertex |= PER_COLOR;
|
||||
if (TexCoordBinding == G_PER_VERTEX) _perVertex |= PER_TEXCOORD;
|
||||
if(NormalBinding == G_PER_VERTEX)
|
||||
_perVertex |= PER_NORMAL;
|
||||
else if(NormalBinding == G_PER_PRIM)
|
||||
_perPrim |= PER_NORMAL;
|
||||
|
||||
_perPrim = 0;
|
||||
if (NormalBinding == G_PER_PRIM) _perPrim |= PER_NORMAL;
|
||||
if (ColorBinding == G_PER_PRIM) _perPrim |= PER_COLOR;
|
||||
if(ColorBinding == G_PER_PRIM)
|
||||
_perPrim |= PER_COLOR;
|
||||
else if(ColorBinding == G_PER_VERTEX)
|
||||
_perVertex |= PER_COLOR;
|
||||
|
||||
if (TexCoordBinding == G_PER_VERTEX)
|
||||
_perVertex |= PER_TEXCOORD;
|
||||
|
||||
size_t vertex_size = draw_prim_setup(geom);
|
||||
|
||||
@ -2856,7 +2931,10 @@ draw_tri(GeomTri *geom, GeomContext *gc) {
|
||||
if (_perPrim & PER_NORMAL)
|
||||
p_normal = geom->get_next_normal(ni); // set primitive normal if there is one.
|
||||
|
||||
draw_prim_inner_loop(3, geom, _perVertex);
|
||||
|
||||
if(_perVertex==TexCoordOnly)
|
||||
draw_prim_inner_loop_coordtexonly(3, geom);
|
||||
else draw_prim_inner_loop(3, geom, _perVertex);
|
||||
}
|
||||
|
||||
DWORD nVerts=nPrims*3;
|
||||
@ -3181,10 +3259,12 @@ draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) {
|
||||
if (GeomVrtFmt!=FlatVerts) {
|
||||
|
||||
// this is the old geom setup, it reformats every vtx into an output array passed to d3d
|
||||
_perVertex = PER_COORD;
|
||||
_perVertex = 0x0;
|
||||
_perPrim = _perComp = 0;
|
||||
|
||||
switch (NormalBinding) {
|
||||
case G_OFF:
|
||||
break;
|
||||
case G_PER_VERTEX:
|
||||
_perVertex |= PER_NORMAL;
|
||||
break;
|
||||
@ -3197,15 +3277,15 @@ draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) {
|
||||
}
|
||||
|
||||
switch (ColorBinding) {
|
||||
case G_PER_VERTEX:
|
||||
_perVertex |= PER_COLOR;
|
||||
break;
|
||||
case G_PER_PRIM:
|
||||
_perPrim |= PER_COLOR;
|
||||
break;
|
||||
case G_PER_COMPONENT:
|
||||
_perComp |= PER_COLOR;
|
||||
break;
|
||||
case G_PER_VERTEX:
|
||||
_perVertex |= PER_COLOR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (TexCoordBinding == G_PER_VERTEX)
|
||||
@ -3240,7 +3320,9 @@ draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) {
|
||||
_pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't
|
||||
|
||||
if(_perComp==0x0) {
|
||||
draw_prim_inner_loop(nVerts, geom, _perVertex);
|
||||
if(_perVertex==TexCoordOnly)
|
||||
draw_prim_inner_loop_coordtexonly(nVerts, geom);
|
||||
else draw_prim_inner_loop(nVerts, geom, _perVertex);
|
||||
} else {
|
||||
if(trilisttype==D3DPT_TRIANGLESTRIP) {
|
||||
// in flat shade mode, D3D strips color using the 1st vertex.
|
||||
@ -3960,36 +4042,6 @@ apply_texture(TextureContext *tc) {
|
||||
|
||||
D3DTEXTUREMINFILTER minfilter = PandaToD3DMinType[(DWORD)ft];
|
||||
D3DTEXTUREMIPFILTER mipfilter = PandaToD3DMipType[(DWORD)ft];
|
||||
/*
|
||||
switch (ft) {
|
||||
case Texture::FT_nearest:
|
||||
minfilter = D3DTFN_POINT;
|
||||
mipfilter = D3DTFP_NONE;
|
||||
break;
|
||||
case Texture::FT_linear:
|
||||
minfilter = D3DTFN_LINEAR;
|
||||
mipfilter = D3DTFP_NONE;
|
||||
break;
|
||||
case Texture::FT_nearest_mipmap_nearest:
|
||||
minfilter = D3DTFN_POINT;
|
||||
mipfilter = D3DTFP_POINT;
|
||||
break;
|
||||
case Texture::FT_linear_mipmap_nearest:
|
||||
minfilter = D3DTFN_LINEAR;
|
||||
mipfilter = D3DTFP_POINT;
|
||||
break;
|
||||
case Texture::FT_nearest_mipmap_linear:
|
||||
minfilter = D3DTFN_POINT;
|
||||
mipfilter = D3DTFP_LINEAR;
|
||||
break;
|
||||
case Texture::FT_linear_mipmap_linear:
|
||||
minfilter = D3DTFN_LINEAR;
|
||||
mipfilter = D3DTFP_LINEAR;
|
||||
break;
|
||||
default:
|
||||
dxgsg_cat.error() << "Unknown tex filter type for tex: " << tex->get_name() << " filter: "<<(DWORD)ft<<"\n";
|
||||
}
|
||||
*/
|
||||
|
||||
#ifndef NDEBUG
|
||||
extern char *PandaFilterNameStrs[];
|
||||
|
@ -310,23 +310,19 @@ protected:
|
||||
INLINE void enable_dither(bool val);
|
||||
INLINE void enable_stencil_test(bool val);
|
||||
bool enable_light(int light, bool val);
|
||||
|
||||
void draw_prim_inner_loop(int nVerts, const Geom *geom, DWORD perFlags);
|
||||
size_t draw_prim_setup(const Geom *geom) ;
|
||||
void report_texmgr_stats();
|
||||
void draw_multitri(Geom *geom, D3DPRIMITIVETYPE tri_id);
|
||||
|
||||
void report_texmgr_stats();
|
||||
void draw_prim_inner_loop(int nVerts, const Geom *geom, ushort perFlags);
|
||||
void draw_prim_inner_loop_coordtexonly(int nVerts, const Geom *geom);
|
||||
size_t draw_prim_setup(const Geom *geom) ;
|
||||
|
||||
// for drawing primitives
|
||||
// Colorf p_color; bypassed by _curD3Dcolor;
|
||||
// Vertexf p_vertex;
|
||||
Normalf p_normal; // still used to hold G_OVERALL, G_PER_PRIM values
|
||||
TexCoordf p_texcoord;
|
||||
D3DCOLOR _curD3Dcolor;
|
||||
DWORD _curFVFflags;
|
||||
short _perPrim;
|
||||
short _perVertex;
|
||||
short _perComp;
|
||||
DWORD _perPrim,_perVertex,_perComp; // these hold DrawLoopFlags bitmask values
|
||||
|
||||
bool _issued_color_enabled; // WBD ADDED
|
||||
bool _enable_all_color;
|
||||
@ -352,11 +348,16 @@ protected:
|
||||
PTA_ushort _vindexes;
|
||||
ushort *_pCurCoordIndex;
|
||||
|
||||
PTA_TexCoordf _texcoords;
|
||||
TexCoordf *_pCurTexCoord;
|
||||
PTA_ushort _texcoord_indexes;
|
||||
ushort *_pCurTexCoordIndex;
|
||||
|
||||
/* not used yet
|
||||
PTA_Normalf _norms;
|
||||
PTA_Colorf _colors;
|
||||
PTA_TexCoordf _texcoords;
|
||||
PTA_ushort _cindexes,_nindexes,_tindexes;
|
||||
PTA_ushort _cindexes,_nindexes;
|
||||
*/
|
||||
|
||||
Colorf _lmodel_ambient;
|
||||
float _material_ambient;
|
||||
|
Loading…
x
Reference in New Issue
Block a user