Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

From the book Introduction to 3D Game Programming with DirectX10:

 // Update the vertex buffer with the new solution. Vertex* v = 0;
 HR(mVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&v ));

 for(DWORD i = 0; i < mNumVertices; ++i) {
     v[i].pos = mCurrSolution[i];
     v[i].color = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f); }

 mVB->Unmap();

The ID3D10Buffer::Unmap function must be called when you are done updating the buffer. The argument D3D10_MAP_WRITE_DISCARD passed into the first parameter of the Map function instructs the hardware to discard the buffer and return a pointer to a newly allocated buffer; this prevents the hardware from stalling by allowing the hardware to continue rendering from the discarded buffer while we write to the newly allocated buffer.

The bold text says that it's supposed to render while we are writing to the buffer. Doesn't that mean that the Draw() call should happen right after we called the Map() function?

If not, why not?

EDIT:

A second question about dynamic vbuffers: When we don't only want to change the vertices inside the buffer, but we also want to create additional vertices, would it be more performance-friendly to just create a static buffer and recreate the buffer?

share|improve this question
    
It doesn't say it's supposed to render while writing to the buffer. It's telling you that the hardware can still render from the previous buffer while you're writing the new one. Additionally, putting the draw call after map would mean: Map->Render->Fill->Unmap. It doesn't mean rendering and filling would happen at the same time. Think about the order these are called and how program control flow actually works. –  Byte56 May 1 '12 at 17:17
    
@Byte56 So basically you're saying that I'd have to implement that using MT? –  xcrypt May 1 '12 at 17:27
1  
Dynamic vertex buffers are discarded and filled every frame, if you change to a static vertex buffer that is destroyed and recreated every frame, I really can't tell you if that will make a performance difference. Try it. If you don't have to update your buffer every frame though, then you might indeed gain some performance when no updates are being performed. –  melak47 May 1 '12 at 17:41
    
@xcrypt I'm saying the anti-stall protection they're providing applies to multi-threading. It doesn't mean you need to utilize it. If a car advertises it has air bags, that doesn't mean you need to find a way to use that feature. –  Byte56 May 1 '12 at 17:54
1  
That's something you'll have to test out and see if it meets your requirements. It's pretty difficult to answer subtle performance questions when there are so many factors that go into performance. –  Byte56 May 1 '12 at 17:56

1 Answer 1

up vote 1 down vote accepted

The key here is that the CPU and GPU are running simultaneously, not sequentially. Typically, while the GPU is rendering frame n, the CPU (your application code) is already preparing frame n+1. When the GPU starts working on frame n+1, the CPU can start on n+2, etc.

Therefore, with dynamic resources such as vertex buffers, you really need (at least) two copies of the buffer: one copy for the GPU to render, and another for the CPU to write data into for the next frame. The CPU can't write into the same buffer the GPU is currently reading, without spoiling the concurrency between the two. At the end of each frame the two copies swap roles, so the GPU gets the buffer the CPU just finished writing, and the CPU gets back the buffer the GPU just finished rendering from.

In D3D, double-buffering of dynamic resources is hidden under the hood. The way you let D3D know it can do this is by using MAP_WRITE_DISCARD, which says you don't care about the previous contents of the buffer. Actually, what happens is that when you use MAP_WRITE_DISCARD you get the other buffer - the one the GPU is not currently reading. Although the book claims it's a "newly allocated" buffer, that's not really true - typically there will just be two buffers swapping roles. The "newly allocated" language really just means you can't depend on any of your old data still being in the buffer (though it might be there anyway).

share|improve this answer
    
Could you also tell me (or point me to a resource) that tells me exactly what parts of the rendering code the CPU is working on, and what part the GPU is working on? The stuff under the hood :) –  xcrypt May 1 '12 at 20:29
1  
@xcrypt, what the GPU does is exactly what your applications tells it to do - it just does it a bit later. When you issue draw commands, state changes etc. from C++, the D3D API is just making a list of all your commands in an internal buffer. When you call Present() it sends those commands to the GPU to be executed, and then lets the app forge ahead with building the command list for the next frame. –  Nathan Reed May 1 '12 at 20:36
1  
@xcrypt BTW, the best way I know about to learn about the stuff "under the hood" is to work at a company that makes games on a console platform. :) On consoles you have much less API and more direct hardware access, so you have to understand more of the internals just to make things work. But the second-best way is to read this. :) –  Nathan Reed May 1 '12 at 20:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.