Can I append vertexes to a default buffer using UpdateSubresources?

71 views Asked by At

The documentation for UpdateSubresources is here. The parameter descriptions are so minimal that they aren't very helpful to someone using the function for the first time (like me).

UINT64 inline UpdateSubresources(
  _In_ ID3D12GraphicsCommandList *pCmdList,
  _In_ ID3D12Resource            *pDestinationResource,
  _In_ ID3D12Resource            *pIntermediate,
       UINT64                    IntermediateOffset,
  _In_ UINT                      FirstSubresource,
  _In_ UINT                      NumSubresources,
  _In_ D3D12_SUBRESOURCE_DATA    *pSrcData
);

I'm trying to follow these code examples from the book Introduction to 3D Game Programming with DirectX 12.

I created a vertex buffer and I want to "draw" on the touchscreen and add triangles to that buffer. The buffer creation is in these functions below, copied from the book code, basically. The size argument there is a big enough to hold say 10000 vertexes. Let's assume for now I'm not running out of space in the buffer. I'm just trying to update it with new Vertex data that comes in.

com_ptr<ID3D12Resource> create_default_buffer(ID3D12Device* device, uint64_t size) {
    com_ptr<ID3D12Resource> buffer;

    CD3DX12_HEAP_PROPERTIES heap_props(D3D12_HEAP_TYPE_DEFAULT);
    auto res_desc = CD3DX12_RESOURCE_DESC::Buffer(size);
    auto hr = device->CreateCommittedResource(&heap_props, D3D12_HEAP_FLAG_NONE, &res_desc, 
                                              D3D12_RESOURCE_STATE_COMMON,
                                              nullptr, __uuidof(buffer), buffer.put_void());
    check_hresult(hr);
    return buffer;
}

com_ptr<ID3D12Resource> create_upload_buffer(ID3D12Device* device, uint64_t size) {
    com_ptr<ID3D12Resource> buffer;

    CD3DX12_HEAP_PROPERTIES heap_props(D3D12_HEAP_TYPE_UPLOAD);
    auto res_desc = CD3DX12_RESOURCE_DESC::Buffer(size);
    auto hr = device->CreateCommittedResource(&heap_props, D3D12_HEAP_FLAG_NONE, &res_desc,
                                              D3D12_RESOURCE_STATE_GENERIC_READ, // ??
                                              nullptr, __uuidof(buffer), buffer.put_void());
    check_hresult(hr);
    return buffer;
}

Now lets say I have some new Vertex data in a std::vector<Vertex> that I want to append to the buffers? How do I use UpdateSubresources to do that? Is that possible, or does UpdateSubresources only overwrite the entire buffer?

1

There are 1 answers

0
wd357dui On BEST ANSWER

UpdateSubresources is an inline function, you can see its source code in d3dx12_resource_helpers.h.

You can see that for buffers, UpdateSubresources eventually calls CopyBufferRegion, with the DstOffset argument hard-coded to 0.

if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
{
    pCmdList->CopyBufferRegion(
        pDestinationResource, 0, pIntermediate,
        pLayouts[0].Offset, pLayouts[0].Footprint.Width);
}
else
{
    ...
}

So the answer is no, it's not possible to append data to the buffers using this function, it will always overwrite the entire buffer. But you can implement your own using CopyBufferRegion.