Jump to content
  • Advertisement
Sign in to follow this  

DX12 How to create a "dynamic" buffer?

Recommended Posts

I have a vertex buffer on a default heap. I need a CPU pointer to that buffer in order to loop through the vertices and change one value in some vertices (the color value). In the past this was possible by creating the buffer with the flag D3DUSAGE_DYNAMIC/D3D11_USAGE_DYNAMIC and using IDirect3DVertexBuffer9::Lock or ID3D11DeviceContext::Map to get a pointer.

What is the correct way to do the same in DX 12? As far as I understand, the method ID3D12Resource::Map cannot be used on a default heap because default heaps cannot be accessed directly from the CPU. The documentation says that upload heaps are intended for CPU-write-once, GPU-read-once usage, so I don't think these are equivalent to the "dynamic" buffers. Is the readback heap equivalent to what was called a dynamic buffer? Or should I create a custom heap?

I am thinking to do the following:

-Create a temporary readback heap.

-Copy the data from the default heap to the readback heap using UpdateSubresources.

-Get a CPU pointer to the readback heap using Map and edit the data.

-Copy the data back to the default heap using UpdateSubresources.

What do you think about this?

Share this post

Link to post
Share on other sites

There's some discussion on this very same topic going on in this thread, so you should check that out. Broadly speaking, there's two different ways of implementing dynamic buffers that can be updated by the CPU:

  1. Create the the buffer in an UPLOAD heap, and directly write to it from the CPU using the pointer that you get from Map. 
  2. Create the buffer in a DEFAULT heap, and update it by first having the CPU write the data to a temporary buffer in an UPLOAD heap, and then kick off a GPU Copy operation to copy from the UPLOAD resource to the DEFAULT resource.

The first one is easier to start with, since it's simpler. You just need to make sure that you don't write to a buffer that the GPU is currently reading from, which is most easily achieved by having N buffers where N is the number of frames in flight (usually 2). The second one is more useful for cases where the GPU is going to be reading the data multiple times, and/or the buffer is very big and will need maximum bandwidth.

You do not want to use READBACK for this, that's intended for having the CPU read data that was written to by the GPU (as in having the CPU "read back" the data from the GPU).

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!