1
\$\begingroup\$

In my 2d game i want to use dynamic buffers to render sprites. My question is, when should i map unmap buffer? The 2 possibilities are:

#1
//game logic
map()
    fill buffer
unmap()
render()

#2
//game logic
fill buffer
unmap()
render()
map()

The second is different because the resource stays mapped for a longer time(all the game logic of the next frame), while in the first option is mapped and soon after unmapped. I want to use the second, it's a good idea or are there cons (performance wise or others)?

\$\endgroup\$
-1
\$\begingroup\$

Usually in DirectX you need 2 textures, one allocated on "dynamic" zone (hint during create resource). And one created in "static" zone, which you copy remotely using CopyResource from D3DContext. So you map/unmap the dynamic texture, then post a copy order, this way you limit the change of blocking the rendering.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks, I think i ve understand what are gli sayimg, but it isnt necessary for a simple vertex/index buffer maybe. With "blocking the render" yoi mean that in the second option when I call map() the resource can still be being render and so i get a block? \$\endgroup\$ – Liuka Jun 5 '15 at 5:09
  • \$\begingroup\$ Yes that's it, it is pretty hard to sync with GPU because the drivers pipelines a whole lot of things we don't expect, and in practice we get a 3 frames delay, between what the CPU is working on (ahead) and what the screen displays (current frame on the front buffer). The whole pipeline is made to protect that fact. So locking things can create a sync point which totally kills this pipeline. This is the same issue with any GPU readback, like pixel reads or occlusion queries. \$\endgroup\$ – v.oddou Jun 5 '15 at 5:15
  • \$\begingroup\$ I read that if I use d3d11 map discard there isn't the problem of synchronisation. So the first question is still valid, are there difference between the first and the second option? \$\endgroup\$ – Liuka Jun 5 '15 at 7:09
  • \$\begingroup\$ its true because you are forced into doing just what I said in the answer. simply because there is no way in D3D10+ to map a static texture. \$\endgroup\$ – v.oddou Jun 5 '15 at 8:05
  • \$\begingroup\$ But you can map a vertex buffer \$\endgroup\$ – Liuka Jun 5 '15 at 8:09
-1
\$\begingroup\$

If you have DYNAMIC buffer and map it with WRITE_DISCARD then both ways are pretty much identical.

As soon as you issue map call, DirectX will provide you with brand new buffer, so there will be no CPU-GPU sync, that is the point. You cannot read data in this provided buffer, first because it is a completely new memory and does not contain your data, second - because returned memory is a writecombine memory and reading from it will cause big penalty.

While in your case this will not be a problem, but mapping buffer with discard causes runtime to search available piece of memory, which sometimes may lead to hitches. More robust way would be to have several buffers (or just one bigger buffer) and map it with MAP_NO_OVERWRITE (only available for index/vertex buffers unless you are running Direct3D 11.1 on Win8), but you need to ensure that memory to which you are writing is not anymore used by GPU. One way to ensure it is to have as many buffers as you maximum frame latency, or issue queries and check that they are ready.

You can read more about it here

Hope this helps.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ If I use v-sync, am i sure I can use no_overwrite safely with just one buffer? \$\endgroup\$ – Liuka Jul 7 '15 at 7:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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