tweakoz
10-31-2003, 11:05 AM
why is the following code so slow on a NVidia Geforce FX 5200 Ultra ?
I Get 44FPS in debug without VBO, 8FPS with VBO.
this pipeline is entirely VertexProgram and Generic Attribute Array Based.
void CGfxTargetW32GL::VtxBuf_Draw( CVtxBufferBase *pVBuf, int iNumIDX, U16 *pIDX, EPrimitiveType eTyp, void *pVBOR, bool bwire )
{
int iNum = pVBuf->GetNum();
if( iNum )
{
//glPushClientAttrib( GL_CLIENT_ALL_ATTRIB_BITS );
if( IsPickState() )
{
SetVertexShaderConstant( 27, GetObjID() );
}
EVtxStreamFormat eStrFmt = pVBuf->GetStreamFormat();
int iStride = pVBuf->GetVtxSize();
U8 *pVtxBase = (U8*)pVBuf->GetVertexPointer();
////////////////////////////////////////////////////////////////////
// setup VBO or DL
#if USEVBO
{
VtxBufH hPB = pVBuf->GetPBHandle();
if( hPB )
{
glBindBufferARB( GL_ARRAY_BUFFER_ARB, hPB );
pVtxBase = 0;
}
else if( (EVTXBUFFLAG_GFXRES==pVBuf->GetFlags()) )
{
// Create A VBO and copy data into it
U32 ubh = 0;
glGenBuffersARB( 1, (GLuint*) & ubh );
hPB = (VtxBufH) ubh;
pVBuf->SetPBHandle( hPB );
glBindBufferARB( GL_ARRAY_BUFFER_ARB, hPB );
GL_ERRORCHECK();
int iVBlen = pVBuf->GetVtxSize()*pVBuf->GetMax();
glBufferDataARB( GL_ARRAY_BUFFER_ARB, iVBlen, pVBuf->GetVertexPointer(), GL_STATIC_DRAW_ARB );
GL_ERRORCHECK();
int nParam_ArrayObjectSize = 0;
glGetBufferParameterivARB( GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &nParam_ArrayObjectSize );
if( nParam_ArrayObjectSize <= 0 )
{
MessageBox(NULL,"glBufferDataARB failed to allocate any memory!",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
}
glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
glBindBufferARB( GL_ARRAY_BUFFER_ARB, hPB );
pVtxBase = 0;
}
else
{
glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
}
GL_ERRORCHECK();
#if USEIBO
{
static map<U16*,VtxBufH> IdxBufferMap;
if( hPB )
{
VtxBufH hIB = MagSTXFindValFromKey( IdxBufferMap, pIDX, (VtxBufH) 0 );
if( 0==hIB )
{
glGenBuffersARB( 1, &hIB );
glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, hIB );
glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, iNumIDX*sizeof(U16), pIDX, GL_STATIC_DRAW_ARB );
MagSTXMapInsert( IdxBufferMap, pIDX, hIB );
GL_ERRORCHECK();
}
else
{
glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, hIB );
GL_ERRORCHECK();
}
pIDX = 0;
}
}
#endif
}
#endif
////////////////////////////////////////////////////////////////////
// set stream format
switch( eStrFmt )
{
case EVTXSTREAMFMT_V12C4N6I2T8:
{
glEnableVertexAttribArrayARB( 0 );
glEnableVertexAttribArrayARB( 1 );
glEnableVertexAttribArrayARB( 2 );
glEnableVertexAttribArrayARB( 3 );
glEnableVertexAttribArrayARB( 4 );
//////////////////////////////////////////////////////////////////////
#if( _BUILD_LEVEL > 1 )
//////////////////////////////////////////////////////////////////////
int iRenderMode = CSystem::GetGlobalIntVariable( "iRenderMode" );
switch( iRenderMode )
{
case 3: // route Normals to color
glVertexAttribPointerARB( 0, 3, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[0] ); // V12
glVertexAttribPointerARB( 2, 3, GL_SHORT, KVANRM_TRUE, iStride, (void*) & pVtxBase[16] ); // N6
glVertexAttribPointerARB( 3, 1, GL_UNSIGNED_SHORT, KVANRM_FALSE, iStride, (void*) & pVtxBase[22] ); // I2
glVertexAttribPointerARB( 4, 2, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[24] ); // T8
glVertexAttribPointerARB( 1, 3, GL_SHORT, KVANRM_TRUE, iStride, (void*) & pVtxBase[16] ); // N6
break;
case 2: // route UVs to color
glVertexAttribPointerARB( 0, 3, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[0] ); // V12
glVertexAttribPointerARB( 2, 3, GL_SHORT, KVANRM_TRUE, iStride, (void*) & pVtxBase[16] ); // N6
glVertexAttribPointerARB( 3, 1, GL_UNSIGNED_SHORT, KVANRM_FALSE, iStride, (void*) & pVtxBase[22] ); // I2
glVertexAttribPointerARB( 4, 2, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[24] ); // T8
glVertexAttribPointerARB( 1, 2, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[24] ); // T8
break;
case 0:
default:
glVertexAttribPointerARB( 0, 3, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[0] ); // V12
glVertexAttribPointerARB( 1, 4, GL_UNSIGNED_BYTE, KVANRM_TRUE, iStride, (void*) & pVtxBase[12] ); // C4
glVertexAttribPointerARB( 2, 3, GL_SHORT, KVANRM_TRUE, iStride, (void*) & pVtxBase[16] ); // N6
glVertexAttribPointerARB( 3, 1, GL_UNSIGNED_SHORT, KVANRM_FALSE, iStride, (void*) & pVtxBase[22] ); // I2
glVertexAttribPointerARB( 4, 2, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[24] ); // T8
break;
}
//////////////////////////////////////////////////////////////////////
#else
//////////////////////////////////////////////////////////////////////
glVertexAttribPointerARB( 0, 3, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[0] ); // V12
glVertexAttribPointerARB( 1, 4, GL_UNSIGNED_BYTE, KVANRM_TRUE, iStride, (void*) & pVtxBase[12] ); // C4
glVertexAttribPointerARB( 2, 3, GL_SHORT, KVANRM_TRUE, iStride, (void*) & pVtxBase[16] ); // N6
glVertexAttribPointerARB( 3, 1, GL_UNSIGNED_SHORT, KVANRM_FALSE, iStride, (void*) & pVtxBase[22] ); // I2
glVertexAttribPointerARB( 4, 2, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[24] ); // T8
//////////////////////////////////////////////////////////////////////
#endif
//////////////////////////////////////////////////////////////////////
GL_ERRORCHECK();
break;
}
case EVTXSTREAMFMT_V12C4T4:
{ glDisableVertexAttribArrayARB( 3 );
glDisableVertexAttribArrayARB( 4 );
glEnableVertexAttribArrayARB( 0 );
glEnableVertexAttribArrayARB( 1 );
glEnableVertexAttribArrayARB( 2 );
glVertexAttribPointerARB( 0, 3, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[0] ); // V12
glVertexAttribPointerARB( 1, 4, GL_UNSIGNED_BYTE, KVANRM_TRUE, iStride, (void*) & pVtxBase[12] ); // C4
glVertexAttribPointerARB( 2, 2, GL_SHORT, KVANRM_FALSE, iStride, (void*) & pVtxBase[16] ); // N6
GL_ERRORCHECK();
break;
}
case EVTXSTREAMFMT_V4C4:
{ glDisableVertexAttribArrayARB( 2 );
glDisableVertexAttribArrayARB( 3 );
glDisableVertexAttribArrayARB( 4 );
glEnableVertexAttribArrayARB( 0 );
glEnableVertexAttribArrayARB( 1 );
glVertexAttribPointerARB( 0, 2, GL_SHORT, KVANRM_FALSE, 8, (void*) & pVtxBase[0] ); // V4
glVertexAttribPointerARB( 1, 4, GL_UNSIGNED_BYTE, KVANRM_TRUE, 8, (void*) & pVtxBase[4] ); // C4
GL_ERRORCHECK();
break;
}
case EVTXSTREAMFMT_V4T4:
{ glDisableVertexAttribArrayARB( 2 );
glDisableVertexAttribArrayARB( 3 );
glDisableVertexAttribArrayARB( 4 );
glEnableVertexAttribArrayARB( 0 );
glEnableVertexAttribArrayARB( 1 );
glVertexAttribPointerARB( 0, 2, GL_SHORT, KVANRM_FALSE, 8, (void*) & pVtxBase[0] ); // V4
glVertexAttribPointerARB( 1, 2, GL_SHORT, KVANRM_FALSE, 8, (void*) & pVtxBase[4] ); // T4
GL_ERRORCHECK();
break;
}
default:
break;
}
////////////////////////////////////////////////////////////////////
// draw it
int inumpasses = mpCurMaterial->GetNumPasses();
for( int ipass=0; ipass<inumpasses; ipass++ )
{
mpCurMaterial->SetupPass( ipass );
static bool lbwire = false;
if( iNumIDX ) switch( eTyp ) // Primitive / Indices Override
{
case EPRIM_LINES:
GL_ERRORCHECK();
glDrawElements( GL_LINES, iNumIDX, GL_UNSIGNED_SHORT, pIDX );
GL_ERRORCHECK();
break;
case EPRIM_TRIANGLES:
GL_ERRORCHECK();
glDrawElements( GL_TRIANGLES, iNumIDX, GL_UNSIGNED_SHORT, pIDX );
miTrianglesRendered += (iNumIDX/3);
GL_ERRORCHECK();
break;
case EPRIM_TRIANGLESTRIP:
GL_ERRORCHECK();
glDrawElements( GL_TRIANGLE_STRIP, iNumIDX, GL_UNSIGNED_SHORT, pIDX );
miTrianglesRendered += (iNumIDX-2);
GL_ERRORCHECK();
break;
default:
glDrawElements( GL_POINTS, iNumIDX, GL_UNSIGNED_SHORT, pIDX );
MagAssert( false );
break;
}
else switch( pVBuf->GetPrimType() )
{ case EPRIM_LINES:
GL_ERRORCHECK();
glDrawArrays( GL_LINES, 0, iNum );
GL_ERRORCHECK();
break;
case EPRIM_TRIANGLES:
GL_ERRORCHECK();
glDrawArrays( GL_TRIANGLES, 0, iNum );
GL_ERRORCHECK();
break;
default:
glDrawArrays( GL_POINTS, 0, iNum );
MagAssert( false );
break;
}
PopRenderState();
} // for( int ipass=0; ipass<inumpasses; ipass++ )
//////////////////////////////////////////////////////
//glPopClientAttrib();
glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
} // if( iNum )
GL_ERRORCHECK();
}
[This message has been edited by tweakoz (edited 11-03-2003).]
[This message has been edited by tweakoz (edited 11-03-2003).]
I Get 44FPS in debug without VBO, 8FPS with VBO.
this pipeline is entirely VertexProgram and Generic Attribute Array Based.
void CGfxTargetW32GL::VtxBuf_Draw( CVtxBufferBase *pVBuf, int iNumIDX, U16 *pIDX, EPrimitiveType eTyp, void *pVBOR, bool bwire )
{
int iNum = pVBuf->GetNum();
if( iNum )
{
//glPushClientAttrib( GL_CLIENT_ALL_ATTRIB_BITS );
if( IsPickState() )
{
SetVertexShaderConstant( 27, GetObjID() );
}
EVtxStreamFormat eStrFmt = pVBuf->GetStreamFormat();
int iStride = pVBuf->GetVtxSize();
U8 *pVtxBase = (U8*)pVBuf->GetVertexPointer();
////////////////////////////////////////////////////////////////////
// setup VBO or DL
#if USEVBO
{
VtxBufH hPB = pVBuf->GetPBHandle();
if( hPB )
{
glBindBufferARB( GL_ARRAY_BUFFER_ARB, hPB );
pVtxBase = 0;
}
else if( (EVTXBUFFLAG_GFXRES==pVBuf->GetFlags()) )
{
// Create A VBO and copy data into it
U32 ubh = 0;
glGenBuffersARB( 1, (GLuint*) & ubh );
hPB = (VtxBufH) ubh;
pVBuf->SetPBHandle( hPB );
glBindBufferARB( GL_ARRAY_BUFFER_ARB, hPB );
GL_ERRORCHECK();
int iVBlen = pVBuf->GetVtxSize()*pVBuf->GetMax();
glBufferDataARB( GL_ARRAY_BUFFER_ARB, iVBlen, pVBuf->GetVertexPointer(), GL_STATIC_DRAW_ARB );
GL_ERRORCHECK();
int nParam_ArrayObjectSize = 0;
glGetBufferParameterivARB( GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &nParam_ArrayObjectSize );
if( nParam_ArrayObjectSize <= 0 )
{
MessageBox(NULL,"glBufferDataARB failed to allocate any memory!",
"ERROR",MB_OK|MB_ICONEXCLAMATION);
}
glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
glBindBufferARB( GL_ARRAY_BUFFER_ARB, hPB );
pVtxBase = 0;
}
else
{
glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
}
GL_ERRORCHECK();
#if USEIBO
{
static map<U16*,VtxBufH> IdxBufferMap;
if( hPB )
{
VtxBufH hIB = MagSTXFindValFromKey( IdxBufferMap, pIDX, (VtxBufH) 0 );
if( 0==hIB )
{
glGenBuffersARB( 1, &hIB );
glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, hIB );
glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, iNumIDX*sizeof(U16), pIDX, GL_STATIC_DRAW_ARB );
MagSTXMapInsert( IdxBufferMap, pIDX, hIB );
GL_ERRORCHECK();
}
else
{
glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, hIB );
GL_ERRORCHECK();
}
pIDX = 0;
}
}
#endif
}
#endif
////////////////////////////////////////////////////////////////////
// set stream format
switch( eStrFmt )
{
case EVTXSTREAMFMT_V12C4N6I2T8:
{
glEnableVertexAttribArrayARB( 0 );
glEnableVertexAttribArrayARB( 1 );
glEnableVertexAttribArrayARB( 2 );
glEnableVertexAttribArrayARB( 3 );
glEnableVertexAttribArrayARB( 4 );
//////////////////////////////////////////////////////////////////////
#if( _BUILD_LEVEL > 1 )
//////////////////////////////////////////////////////////////////////
int iRenderMode = CSystem::GetGlobalIntVariable( "iRenderMode" );
switch( iRenderMode )
{
case 3: // route Normals to color
glVertexAttribPointerARB( 0, 3, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[0] ); // V12
glVertexAttribPointerARB( 2, 3, GL_SHORT, KVANRM_TRUE, iStride, (void*) & pVtxBase[16] ); // N6
glVertexAttribPointerARB( 3, 1, GL_UNSIGNED_SHORT, KVANRM_FALSE, iStride, (void*) & pVtxBase[22] ); // I2
glVertexAttribPointerARB( 4, 2, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[24] ); // T8
glVertexAttribPointerARB( 1, 3, GL_SHORT, KVANRM_TRUE, iStride, (void*) & pVtxBase[16] ); // N6
break;
case 2: // route UVs to color
glVertexAttribPointerARB( 0, 3, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[0] ); // V12
glVertexAttribPointerARB( 2, 3, GL_SHORT, KVANRM_TRUE, iStride, (void*) & pVtxBase[16] ); // N6
glVertexAttribPointerARB( 3, 1, GL_UNSIGNED_SHORT, KVANRM_FALSE, iStride, (void*) & pVtxBase[22] ); // I2
glVertexAttribPointerARB( 4, 2, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[24] ); // T8
glVertexAttribPointerARB( 1, 2, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[24] ); // T8
break;
case 0:
default:
glVertexAttribPointerARB( 0, 3, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[0] ); // V12
glVertexAttribPointerARB( 1, 4, GL_UNSIGNED_BYTE, KVANRM_TRUE, iStride, (void*) & pVtxBase[12] ); // C4
glVertexAttribPointerARB( 2, 3, GL_SHORT, KVANRM_TRUE, iStride, (void*) & pVtxBase[16] ); // N6
glVertexAttribPointerARB( 3, 1, GL_UNSIGNED_SHORT, KVANRM_FALSE, iStride, (void*) & pVtxBase[22] ); // I2
glVertexAttribPointerARB( 4, 2, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[24] ); // T8
break;
}
//////////////////////////////////////////////////////////////////////
#else
//////////////////////////////////////////////////////////////////////
glVertexAttribPointerARB( 0, 3, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[0] ); // V12
glVertexAttribPointerARB( 1, 4, GL_UNSIGNED_BYTE, KVANRM_TRUE, iStride, (void*) & pVtxBase[12] ); // C4
glVertexAttribPointerARB( 2, 3, GL_SHORT, KVANRM_TRUE, iStride, (void*) & pVtxBase[16] ); // N6
glVertexAttribPointerARB( 3, 1, GL_UNSIGNED_SHORT, KVANRM_FALSE, iStride, (void*) & pVtxBase[22] ); // I2
glVertexAttribPointerARB( 4, 2, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[24] ); // T8
//////////////////////////////////////////////////////////////////////
#endif
//////////////////////////////////////////////////////////////////////
GL_ERRORCHECK();
break;
}
case EVTXSTREAMFMT_V12C4T4:
{ glDisableVertexAttribArrayARB( 3 );
glDisableVertexAttribArrayARB( 4 );
glEnableVertexAttribArrayARB( 0 );
glEnableVertexAttribArrayARB( 1 );
glEnableVertexAttribArrayARB( 2 );
glVertexAttribPointerARB( 0, 3, GL_FLOAT, KVANRM_FALSE, iStride, (void*) & pVtxBase[0] ); // V12
glVertexAttribPointerARB( 1, 4, GL_UNSIGNED_BYTE, KVANRM_TRUE, iStride, (void*) & pVtxBase[12] ); // C4
glVertexAttribPointerARB( 2, 2, GL_SHORT, KVANRM_FALSE, iStride, (void*) & pVtxBase[16] ); // N6
GL_ERRORCHECK();
break;
}
case EVTXSTREAMFMT_V4C4:
{ glDisableVertexAttribArrayARB( 2 );
glDisableVertexAttribArrayARB( 3 );
glDisableVertexAttribArrayARB( 4 );
glEnableVertexAttribArrayARB( 0 );
glEnableVertexAttribArrayARB( 1 );
glVertexAttribPointerARB( 0, 2, GL_SHORT, KVANRM_FALSE, 8, (void*) & pVtxBase[0] ); // V4
glVertexAttribPointerARB( 1, 4, GL_UNSIGNED_BYTE, KVANRM_TRUE, 8, (void*) & pVtxBase[4] ); // C4
GL_ERRORCHECK();
break;
}
case EVTXSTREAMFMT_V4T4:
{ glDisableVertexAttribArrayARB( 2 );
glDisableVertexAttribArrayARB( 3 );
glDisableVertexAttribArrayARB( 4 );
glEnableVertexAttribArrayARB( 0 );
glEnableVertexAttribArrayARB( 1 );
glVertexAttribPointerARB( 0, 2, GL_SHORT, KVANRM_FALSE, 8, (void*) & pVtxBase[0] ); // V4
glVertexAttribPointerARB( 1, 2, GL_SHORT, KVANRM_FALSE, 8, (void*) & pVtxBase[4] ); // T4
GL_ERRORCHECK();
break;
}
default:
break;
}
////////////////////////////////////////////////////////////////////
// draw it
int inumpasses = mpCurMaterial->GetNumPasses();
for( int ipass=0; ipass<inumpasses; ipass++ )
{
mpCurMaterial->SetupPass( ipass );
static bool lbwire = false;
if( iNumIDX ) switch( eTyp ) // Primitive / Indices Override
{
case EPRIM_LINES:
GL_ERRORCHECK();
glDrawElements( GL_LINES, iNumIDX, GL_UNSIGNED_SHORT, pIDX );
GL_ERRORCHECK();
break;
case EPRIM_TRIANGLES:
GL_ERRORCHECK();
glDrawElements( GL_TRIANGLES, iNumIDX, GL_UNSIGNED_SHORT, pIDX );
miTrianglesRendered += (iNumIDX/3);
GL_ERRORCHECK();
break;
case EPRIM_TRIANGLESTRIP:
GL_ERRORCHECK();
glDrawElements( GL_TRIANGLE_STRIP, iNumIDX, GL_UNSIGNED_SHORT, pIDX );
miTrianglesRendered += (iNumIDX-2);
GL_ERRORCHECK();
break;
default:
glDrawElements( GL_POINTS, iNumIDX, GL_UNSIGNED_SHORT, pIDX );
MagAssert( false );
break;
}
else switch( pVBuf->GetPrimType() )
{ case EPRIM_LINES:
GL_ERRORCHECK();
glDrawArrays( GL_LINES, 0, iNum );
GL_ERRORCHECK();
break;
case EPRIM_TRIANGLES:
GL_ERRORCHECK();
glDrawArrays( GL_TRIANGLES, 0, iNum );
GL_ERRORCHECK();
break;
default:
glDrawArrays( GL_POINTS, 0, iNum );
MagAssert( false );
break;
}
PopRenderState();
} // for( int ipass=0; ipass<inumpasses; ipass++ )
//////////////////////////////////////////////////////
//glPopClientAttrib();
glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
} // if( iNum )
GL_ERRORCHECK();
}
[This message has been edited by tweakoz (edited 11-03-2003).]
[This message has been edited by tweakoz (edited 11-03-2003).]