Using Dynamic Vertex and Index Buffers

Dynamic vertex and index buffers have a difference in performance based the size and usage. The usage styles below help to determine whether to use D3DLOCK_DISCARD or D3DLOCK_NOOVERWRITE for the Flags parameter of the Lock method.

Usage Style 1:

for loop()
{
    pBuffer->Lock(...D3DLOCK_DISCARD...); //Ensures that hardware 
                                          //does not stall by returning 
                                          //a new pointer.
    Fill data (optimally 1000s of vertices/indices, no fewer) in pBuffer.
    pBuffer->Unlock()
    Change state(s).
    DrawPrimitive() or DrawIndexedPrimitive()
}

Usage Style 2:

for loop()
{
    pVB->Lock(...D3DLOCK_DISCARD...); //Ensures that hardware does not 
                                      //stall by returning a new 
                                      //pointer.
    Fill data (optimally 1000s of vertices/indices, no fewer) in pBuffer.
    pBuffer->Unlock
    for loop( 100s of times )
    {
        Change State
        DrawPrimitive() or DrawIndexPrimitives() //Tens of primitives
    }
}

Usage Style 3:

for loop()
{
    If there is space in the Buffer
    {
        //Append vertices/indices.
        pBuffer->Lock(D3DLOCK_NOOVERWRITE);
    }
    Else
    {
        //Reset to beginning.
        pBuffer->Lock(D3DLOCK_DISCARD);
    }
    Fill few 10s of vertices/indices in pBuffer
    pBuffer->Unlock
    Change State
    DrawPrimitive() or DrawIndexedPrimitive() //A few primitives
}

Style 1 is faster than either style 2 or 3, but is generally not very practical. Style 2 is usually faster than style 3, provided that the application fills at least a couple thousand vertices/indices for every Lock, on average. If the application fills fewer than that on average, then style 3 is faster. There is no guaranteed answer as to which lock method is faster and the best way to find out is to experiment.

 Last updated on Thursday, April 08, 2004

© 1992-2003 Microsoft Corporation. All rights reserved.