# DirectX 12: Uploading multiple buffers to 1 default heap using the UpdateSubresources API without explicit copies

Consider a situation where there are 3 different buffers describing a particular mesh piece: vBuffer, nBuffer, iBuffer (vertices, normals, and indices) which equate to totalBufferSize in aggregate.

I want to save these 3 buffers to the same default heap (D3D12_HEAP_TYPE_DEFAULT). I know I still need to use an upload heap (D3D12_HEAP_TYPE_UPLOAD) as an intermediary but I can't figure out how to eliminate extra copies.

Currently my code (which works) does the following:

    const D3D12_HEAP_PROPERTIES defaultHeapProperties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);

...

const CD3DX12_RESOURCE_DESC resourceDescV = CD3DX12_RESOURCE_DESC::Buffer(totalBufferSize);
DX::ThrowIfFailed(device->CreateCommittedResource(
&defaultHeapProperties,
D3D12_HEAP_FLAG_NONE,
&resourceDescV,
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,

DX::ThrowIfFailed(device->CreateCommittedResource(
D3D12_HEAP_FLAG_NONE,
&resourceDescV,
nullptr,

uint8_t * bufferStart{};

// Can these be eliminated?
uint32_t offset{};
std::memcpy(bufferStart, vBuffer.data, vBuffer.totalSize);
offset += vBuffer.totalSize;
std::memcpy(bufferStart + offset, nBuffer.data, nBuffer.totalSize);
offset += nBuffer.totalSize;
std::memcpy(bufferStart + offset, iBuffer.data, iBuffer.totalSize);

D3D12_SUBRESOURCE_DATA bufferData{};
bufferData.pData = bufferStart;
bufferData.RowPitch = totalBufferSize;
bufferData.SlicePitch = totalBufferSize;

CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(meshPart.m_mainBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
commandList->ResourceBarrier(1, &barrier);


However, I'm trying to figure out if I can eliminate those std::memcpy calls. All examples of UpdateSubresources I've seen do not explicitly Map+memcpy into the upload buffer. They just set D3D12_SUBRESOURCE_DATA.pData directly.

I tried calling using UpdateSubresources<3> and passing in an array of D3D12_SUBRESOURCE_DATA, each pointing to the beginning of my mesh buffers, but the validation layer didn't like that and threw an exception.

Is it possible to upload all 3 buffers in one step here -- without the explicit Map and memcpy steps?

UpdateSubresources is a helper function. Inside it is another memcpy. I would recommend simply rewriting it - source is in d3dx12.h. Then you will be able to copy your data no more than necessary.
• Hmm, yeah... the helper function essentially amounts to the following in my case: commandList->CopyBufferRegion(meshPart.m_mainBuffer.Get(), 0, meshPart.m_uploadBuffer.Get(), 0, totalBufferSize); I'll keep my Map+memcpy and just call CopyBufferRegion myself without going through the helper. Thanks for the reality check. – deadpin May 11 '18 at 19:14