Readback Data through Buffers I am pretty new to the dx12 world. As a sample project I am trying to add 2 buffers and store the output in yet another output buffer. As apart of this debugging I am trying to see if the buffers that I am loading actually have the right values. 
Thus, once the buffer is loaded, I want to put in a fence and "read back the data uploaded" into the CPU and print out the contents of the buffer. 
After a lot of googling I thought i should use the map function in DXD12. 

But I am not entirely sure how I should go about doing this. Any thoughts?
Ok, so I made little example of how to do this.

Short version

You need to allocate additional buffer with heap type D3D12_HEAP_TYPE_READBACK and resource state set to D3D12_RESOURCE_STATE_COPY_DEST. Then create command list with type D3D12_COMMAND_LIST_TYPE_COPY. After dispatch compute shader use fence to check if buffer is ready, then copy from this buffer to buffer on D3D12_HEAP_TYPE_READBACK heap. Check again with fence if copying is finished and call Map on this buffer.

I would suggest that you stop reading here and try implement it from description above and check longer version if its still doesn't work. Copy/Past isn't the best way to learn :)

Longer version

First lets create new command list.

ID3D12CommandQueue* copyQueue;
ID3D12CommandAllocator* copyAllocator;
ID3D12GraphicsCommandList* copyList;

D3D12_COMMAND_QUEUE_DESC descCopyQueue = {};
descCopyQueue.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
descCopyQueue.Type = D3D12_COMMAND_LIST_TYPE_COPY;
device-&gt;CreateCommandQueue(&amp;descCopyQueue, IID_PPV_ARGS(&amp;copyQueue));
device-&gt;CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COPY, IID_PPV_ARGS(&amp;copyAllocator));
device-&gt;CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COPY, copyAllocator, nullptr, IID_PPV_ARGS(&amp;copyList));


Notice type D3D12_COMMAND_LIST_TYPE_COPY.

Next thing is new buffer.

D3D12_HEAP_PROPERTIES const heapPropertiesReadback =
{
    /*Type*/                    D3D12_HEAP_TYPE_READBACK
    /*CPUPageProperty*/         ,D3D12_CPU_PAGE_PROPERTY_UNKNOWN
    /*MemoryPoolPreference*/    ,D3D12_MEMORY_POOL_UNKNOWN
    /*CreationNodeMask*/        ,0
    /*VisibleNodeMask*/         ,0
};

D3D12_RESOURCE_DESC buffersDesc = {};
buffersDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
buffersDesc.Alignment = 0;
buffersDesc.Width = sizeof( unsigned int ) * 5;
buffersDesc.Height = 1;
buffersDesc.DepthOrArraySize = 1;
buffersDesc.MipLevels = 1;
buffersDesc.Format = DXGI_FORMAT_UNKNOWN;
buffersDesc.SampleDesc.Count = 1;
buffersDesc.SampleDesc.Quality = 0;
buffersDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
buffersDesc.Flags = D3D12_RESOURCE_FLAG_NONE;

ID3D12Resource* bufferReadback;

device-&gt;CreateCommittedResource(&amp;heapPropertiesReadback, D3D12_HEAP_FLAG_NONE, &amp;buffersDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&amp;bufferReadback));


Remember to set D3D12_RESOURCE_DESC ::Width to size of your buffers.

Then after you Dispatch compute list and call ExecuteCommandLists on compute queue you need to use fence, copy buffer and use fence again.

computeQueue-&gt;Signal(fence, fenceValue);
fence-&gt;SetEventOnCompletion(fenceValue, fenceEvent);
++fenceValue;
WaitForSingleObject(fenceEvent, INFINITE);

copyList-&gt;CopyResource(bufferReadback, bufferB);
copyList-&gt;Close();
copyQueue-&gt;ExecuteCommandLists(1, (ID3D12CommandList**)(&amp;copyList));

copyQueue-&gt;Signal(fence, fenceValue);
fence-&gt;SetEventOnCompletion(fenceValue, fenceEvent);
++fenceValue;
WaitForSingleObject(fenceEvent, INFINITE);


After this you can call Map on resource.

unsigned int* data;
bufferReadback-&gt;Map(0, nullptr, reinterpret_cast&lt;void**&gt;(&amp;data));


I hope this will help, let me know if you have any questions.