I'm trying to learn graphics programming and DirectX11.

I'm trying to learn how to minimize CPU-GPU transfer and graphics programming in general.
I have a question that I have been unable to answer myself from online resources:

Which of the D3D methods actually sends the data to the GPU(and, equivalently, for a static mesh does ALL the vertex data get passed to the GPU every frame, or only once)?

Code follows:
(simplified for stackexchange)

In my "mesh" class, I have a vertex buffer:

ID3D11Buffer *m_pVBuffer;

In my mesh's constructor, I set some vertices to the vertex buffer:

devcon->Map(m_pVBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms);
memcpy(ms.pData, &vertices[0], sizeof(VERTEX) * vertices.size());
devcon->Unmap(m_pVBuffer, NULL);

Then in my mesh's "render" method, I do this:

UINT stride = sizeof(VERTEX);
UINT offset = 0;
devcon->IASetVertexBuffers(0, 1, &m_pVBuffer, &stride, &offset);
devcon->IASetIndexBuffer(m_pIBuffer, DXGI_FORMAT_R32_UINT, 0);
devcon->DrawIndexed(m_num_indices, 0, 0);

To repeat: Is the data uploaded to the GPU when I Map, memcpy and Unmap the vertex buffer, or is it uploaded every frame, when I call IASetVertexBuffers?


3 Answers 3


This is a tricky question because you don't have complete control over whether a vertex buffer is stored in VRAM or main RAM. The driver makes that decision for you based on the usage and CPU access flags specified when you create the vertex buffer.

Generally speaking, buffers with default and immutable usage will be stored in VRAM; those with staging usage will be stored in main RAM; and those with dynamic usage could be in either place. However, if insufficient VRAM is available the driver will store resources in main RAM as a fallback.

If a buffer ends up in VRAM, data goes across the system bus (that connects the CPU and GPU) whenever the CPU updates the buffer (that is, when you do a Map/Unmap pair). If it's in main RAM, the GPU will read the data across the system bus every time you use that buffer for rendering.

So, typically, for static meshes you would use immutable usage and the buffer would be stored in VRAM, so there is no additional system bus transfer after the initial setup. For a dynamic vertex buffer (for particles or similar) you'd use dynamic usage, and the data would go across the bus once each frame - if it's in VRAM, the bus will be used for the CPU to write to it, and if it's in main RAM, the bus will be used for the GPU to read it.

  • \$\begingroup\$ The tests I ran confirm this answer. When I render a lot of objects, there's an initial slowdown for the first couple of seconds but then the framerate goes up. Given that I do the same thing every frame, this must be because at least some part of the buffers is "cached" in VRAM. So the answer is "It will be uploaded only once. Probably. You shouldn't count on it though.". \$\endgroup\$
    – x10
    Commented Jan 10, 2012 at 15:30

The answer will be dependent on what any particular generation of highly optimized hardware driver feels like doing, which is to say that there is no general answer for you.

Add to that complication the fact that drivers are rendering 1-N frames behind of what you're currently telling them to render because 3D cards are both highly serialized and parallel and cached and work asynchronously to get things done.

If you're just learning then the important information to know is the sequence points to preparing a render: describe the data, copy in the data, tell the driver what data to use, then fire off the render. And not what happens when, that is a very deep rabbit hole indeed.


My understanding, mostly based on reading this is that the driver generally won't send any resources across to video memory, until the resource is used in a draw call.

That would mean the constructor probably won't touch the GPU hardware at all, and the render method will. However even the DrawIndexed() call probably won't make it to the hardware immediately because it's more CPU efficient to buffer up large lists of GPU commands.

The driver can also unload data from GPU memory when it runs out (assuming it has a copy of it in main RAM). In extreme cases this can happen more than once per frame.

Of course all of this is hidden from the programmer by the driver, so you can't rely on it being like that - drivers change all the time.

  • \$\begingroup\$ It's highly possible that it won't even go on a draw call - the draw call just goes to a driver-managed command buffer, and that gets flushed in the drivers own sweet time, which may be any arbitrary amount of time afterwards. \$\endgroup\$ Commented Jun 26, 2012 at 21:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .