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).]