UpdateSubresources
的文档位于这里。参数描述非常少,对于第一次使用该函数的人(比如我)来说没有太大帮助。
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
);
我正在尝试遵循书中的这些代码示例使用 DirectX 12 进行 3D 游戏编程简介。
我创建了一个顶点缓冲区,我想在触摸屏上“绘制”并向该缓冲区添加三角形。缓冲区的创建基本上是在下面的这些函数中,从书籍代码中复制的。
size
参数足够大,可以容纳 10000 个顶点。现在假设缓冲区空间没有用完。我只是想用新的 Vertex
数据来更新它。
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;
}
现在假设我在
Vertex
中有一些新的 std::vector<Vertex>
数据,我想将其附加到缓冲区?我如何使用 UpdateSubresources
来做到这一点?这可能吗,还是 UpdateSubresources
只覆盖整个缓冲区?
UpdateSubresources
是一个内联函数,您可以在d3dx12_resource_helpers.h
中查看其源代码。
您可以看到
UpdateSubresources
最终调用 CopyBufferRegion
,并将 DstOffset
参数硬编码为 0
。
if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
{
pCmdList->CopyBufferRegion(
pDestinationResource, 0, pIntermediate,
pLayouts[0].Offset, pLayouts[0].Footprint.Width);
}
else
{
...
}
所以答案是否定的,不可能使用此函数将数据“追加”到缓冲区,它总是会覆盖整个缓冲区。