0
\$\begingroup\$

Previosuly in Direct3D 9 and 11, if I wanted to update a resource in a Default heap, for example, a Vertex Buffer, I would lock the memory of the buffer, copy the data to the returned pointer, and then unlock the buffer. It is my understanding that unlocking the buffer committed the data to VRAM, and I could be certain that the buffer would be ready to be used by any draw commands.

With Direct3D 12, we now have the concept of upload heaps, and instead of locking the buffer each time I want to modify it, I can just get a mapped pointer to the VRAM area with ID3DResource::Map(). This is pretty cool, because I understand that in most cases, the write is performed with write combining, so I don't have to wait until the entire data is committed to VRAM to keep on doing work on the CPU.

Now the question is, how can I ensure that when I execute a GPU command that references that memory, the memory is already committed, and the GPU can safely read it?

\$\endgroup\$
0
\$\begingroup\$

You can't render using the part of a resource with uncommitted memory. You create the GPU VRAM resource using CreateCommittedResource.

You should think of a D3D12_HEAP_TYPE_UPLOAD like the DirectX 11 STAGING resource. You can lock it because it's CPU accessible, and then use the GPU to copy data from the upload heap to your commited resource in the DEFAULT heap which may or may not be CPU accessible. You have to use a fence to make sure the GPU copy is complete before you can render with it, otherwise you risk changing the data while rendering it.

See DirectX Tool Kit for DX 12 and in particular the ResourceUploadBatch helper class.

\$\endgroup\$
  • \$\begingroup\$ Ok, that makes sense. So I copy from the source data to the upload heap resource with either Map and then memcpy, or just WriteToSubResource (I suppose this is immediately commited?), schedule a data copy to the default heap resource (with CopyResource), and then schedule a ResourceBarrier to transition the state of the default heap resource to VERTEX_AND_CONSTANT_BUFFER or whatever, when the copy is finished. It seems like UpdateSubresources does the first parts of this. Am I correct in this interpretation? \$\endgroup\$ – Panda Pajama Feb 28 '18 at 7:48
  • \$\begingroup\$ Most often I see fences in the command-list being used to tell when the upload is complete rather than resource barriers because you are usually loading a number of textures at once, but for the simple case resource barrier does work. See SimpleTexture for some sample code. \$\endgroup\$ – Chuck Walbourn Feb 28 '18 at 22:11

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.