# Issue with dynamic VertexBuffer reuse in Direct3D9

directx c++

9 replies to this topic

### #1Snoob

Member

• Members
• 42 posts

Posted 06 January 2013 - 07:14 AM

In my application I create a simple dynamic vertex buffer :

// calculate the number of bytes of data
size = m_sizeVertex*m_numVertices;

HRESULT hr = d3ddev->CreateVertexBuffer(size,
D3DUSAGE_DYNAMIC,
0,   // DON'T pass the FVF code we using vertex decleration
D3DPOOL_DEFAULT,
&m_buffer,
NULL);


I add data to my buffer in this way:

writeData(unsigned int offset, unsigned int length, void* data)
{
// store the length of actual data length
m_length = length;

// determine required buffer size in bytes
unsigned int size = length*m_sizeVertex;

// lock v_buffer and load the vertices into it
void* vertices = 0;
HRESULT hr = m_buffer->Lock(offset, size, &vertices, D3DLOCK_DISCARD);
if (FAILED(hr)){
throw exception("Could not lock buffer!");
}

memcpy(vertices, data, size);

hr = m_buffer->Unlock();
if (FAILED(hr)){
throw exception("Could not unlock buffer!");
}
}


Everything is working fine until I try to reuse the buffer, which has rendered other data before. In that case I got fragments of the old render data as garbage between new render data. If I everytime create a new buffer on data switch anything is working fine. It looks to me that the discard flag is ignored.

Thanks for any help.

### #2Reedbeta

DevMaster Staff

• Administrators
• 5309 posts
• LocationSanta Clara, CA

Posted 06 January 2013 - 05:28 PM

Are your writes are contiguous? I.e. when you call writeData you pass in an offset and length, so I guess you are only overwriting a portion of the data each time; is it possible you're leaving unwritten space between sections of data?
reedbeta.com - developer blog, OpenGL demos, and other projects

### #3Chris Herold

New Member

• Members
• 10 posts

Posted 06 January 2013 - 05:32 PM

Reedbeta, on 06 January 2013 - 05:28 PM, said:

Are your writes are contiguous? I.e. when you call writeData you pass in an offset and length, so I guess you are only overwriting a portion of the data each time; is it possible you're leaving unwritten space between sections of data?

That was also my first thought.
When you want to discard the buffer contents, make sure you discard it completely.
Passing incoherent offset/length is most likely the problem here.

### #4Snoob

Member

• Members
• 42 posts

Posted 06 January 2013 - 06:38 PM

I pass first 6 Vertices, at 2nd also six (changed texture) and finally 12 Vertices using same texture as data from first pass. The issue occurs rendering the final content. Each pass has zero offset. I thought the discard flag ensures that the content of the buffer is discard completely.

### #5Chris Herold

New Member

• Members
• 10 posts

Posted 06 January 2013 - 07:18 PM

Snoob, on 06 January 2013 - 06:38 PM, said:

I pass first 6 Vertices, at 2nd also six (changed texture) and finally 12 Vertices using same texture as data from first pass. The issue occurs rendering the final content. Each pass has zero offset. I thought the discard flag ensures that the content of the buffer is discard completely.

You're right of course... Discard flag will drop the complete buffer. Sorry for the confusion.
I've got a feeling this thread contains your answer (JeffFs answer in particular):
http://www.gamedev.n...fer9lockmethod/

### #6Reedbeta

DevMaster Staff

• Administrators
• 5309 posts
• LocationSanta Clara, CA

Posted 06 January 2013 - 08:53 PM

Snoob, on 06 January 2013 - 06:38 PM, said:

I thought the discard flag ensures that the content of the buffer is discard completely.

That's not really what it does. The discard flag just tells D3D that you don't depend on the previous contents of the buffer still being there, and therefore allows the driver to make certain performance optimizations. It does NOT guarantee that the buffer is zero-filled or anything like that.

In fact, the driver is probably internally maintaining 2 or more instances of the buffer, so that the GPU can read from one while your application is filling another. In this case you may find that when you lock the buffer, it contains the vertices you rendered 2 or 3 frames ago.

By the way, to render multiple times from the same vertex buffer in the same frame, it may be better (faster) to make the buffer longer and use successive sections of it rather than re-using the same area (the beginning). For instance, your first draw would use vertices 0-5, the second 6-11, and the third 12-23. If you do this you should use D3DLOCK_DISCARD the first time you lock the buffer in each frame, and D3DLOCK_NOOVERWRITE each subsequent time until the next frame. This lets the driver know you're writing to disjoint sections of the buffer, so it can avoid doing extra memory allocations. For more information see this MSDN article.
reedbeta.com - developer blog, OpenGL demos, and other projects

### #7Snoob

Member

• Members
• 42 posts

Posted 06 January 2013 - 09:47 PM

Thanks for your detailed informations. If I can't follow your advise with the sections, what is the better way I should go? Should I zero fill the entire buffer before each write call or should I recreate a new one?

### #8Reedbeta

DevMaster Staff

• Administrators
• 5309 posts
• LocationSanta Clara, CA

Posted 06 January 2013 - 09:51 PM

Zero-filling would certainly be more efficient. However, you shouldn't need to zero-fill it at all assuming you draw only parts you have written to. I still suspect some issue with your offets and lengths being incorrect. One thing that bites people sometimes is getting confused between length in vertices and length in bytes, so you might want to double-check that your length is in the correct units at each D3D9 call.
reedbeta.com - developer blog, OpenGL demos, and other projects

### #9Snoob

Member

• Members
• 42 posts

Posted 06 January 2013 - 10:30 PM

I've checked my values multiple times, they should be correct (I use the same values as base on GL buffers where all is perfect). The offset is allways zero and I use length in bytes... I will try out the zero filling.

### #10Snoob

Member

• Members
• 42 posts

Posted 07 January 2013 - 08:42 PM

I checked my render data again, anything is correct. I also tried to lock the entire buffer with discard flag, but this solves not the problem.
Finally i've implemented a zero fill of the entire buffer before writing the data to the buffer, now it works. Thanks for your support.

#### 1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users