Archived

This topic is now archived and is closed to further replies.

VertexBuffer->Lock() issues

This topic is 5093 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Good day, I have strange errors using streaming vertex buffer - sometimes vb->Lock() returns pointer, correct one at first glance, but it turns out to reference smaller amount of memory than I had requested. Here''s the example code:
// setup streams

VbHandle        vb = APP0->GetVbXyznt1();

// lock

VertexXYZNT1*   dv = (VertexXYZNT1*)RENDER->LockVbStreaming( vb, mh.m_numVertices, vofs );
ASSERT_( dv != 0 );
memcpy( dv, takeFrom, sizeof( VertexXYZNT1 ) * mh.m_numVertices );
^^^^^^ here we crash!!!
RENDER->UnlockVb( vb );
Note, here IsBadWritePtr( dv, mh.m_numVertices*vertex_size ) will be TRUE (btw, is this correct to check vb memory with IsBadWritePtr()?). Here''s LockVbStreaming() implementation:
//

void* CDevice::LockVbStreaming( const VbHandle& id, int sz, int& ofs, int* discarded )
{
        if( !IsVbValid( id ) )
                return 0;

        CVertexBuffer&  vb = m_vbs[VbId( id )];
        int             n = vb.m_desc.Size / vb.m_vertSz;

        // promote pointer

        ofs = vb.m_curPos;
        vb.m_curPos += sz;
        if( vb.m_curPos >= n )
        {
                vb.m_curPos = sz;
                ofs = 0;
        }

        // lock verts

        void*   ptr;
        ptr = LockVb( id, sz, ofs, ofs ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD );

        //

        if( discarded )
                *discarded = (ofs == 0);

        return ptr;
}

//

void* CDevice::LockVb( const VbHandle& id, int sz, int ofs, unsigned flags )
{
        if( !IsVbValid( id ) )
                return 0;

        CVertexBuffer&  vb = m_vbs[VbId( id )];

        ASSERT_( !vb.m_locked );

        ASSERT_( sz >= 0 && sz <= (vb.m_desc.Size / vb.m_vertSz) );

        if( D3DPOOL_DEFAULT == vb.m_desc.Pool )
        {
                if( 0 == flags )
                        flags |= D3DLOCK_DISCARD;
        } else
        {
                flags &= ~(D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE);
        }

        flags |= D3DLOCK_NOSYSLOCK;

        if( sz == 0 )
        {
                ofs = 0;
                sz = vb.m_desc.Size / vb.m_vertSz;
        }

        void*   buff = 0;
        HRESULT hr = vb.m_vb->Lock( ofs*vb.m_vertSz, sz*vb.m_vertSz, &buff, flags );
        ASSERT_( hr == D3D_OK );
        if( FAILED( hr ) )
                return 0;

        //

        vb.m_locked = 1;

        return buff;
}
I have a number of streaming preallocated vbs (each contains 128K of vertex data of a differect FVFs) created with D3DPOOL_DEFAULT and D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC. We use them very often throughout our game. It seems that CDevice::LockVb() itself never returns bad data, only when used from CDevice::LockVbStreaming(). So far, this error occures ONLY on Geforce 4 MX cards (WinXP/Detonator 45.23). We had never come across it on other nVidia or ATI cards. PS. I''ve just installed latest Detonator 52.16 and it seems it doesn''t have such effect, everything goes fine so far...

Share this post


Link to post
Share on other sites
quote:
Original post by Plus
I have strange errors using streaming vertex buffer - sometimes vb->Lock()
returns pointer, correct one at first glance, but it turns out to reference smaller
amount of memory than I had requested...

VertexXYZNT1* dv = (VertexXYZNT1*)RENDER->LockVbStreaming( vb, mh.m_numVertices, vofs );



Hmmm... try this:


VertexXYZNT1* dv = (VertexXYZNT1*)RENDER->LockVbStreaming( vb, sizeof( VertexXYZNT1 ) * mh.m_numVertices, vofs );






"The Gods Made Heavy Metal And They Saw That It Was Good They Said To Play It Louder Than Hell We Promised That We Would
When Losers Say Its Over With You Know That It’s A Lie The Gods Made Heavy Metal And It’s Never Gonna Die"

THE GODS MADE HEAVY METAL/by
ManOwaR

Share this post


Link to post
Share on other sites