Files
XCEngine/docs/api/rhi/d3d12/d3d12-buffer.md

179 lines
4.5 KiB
Markdown

# D3D12Buffer
DirectX 12 缓冲区的 D3D12 实现,封装了 `ID3D12Resource` (buffer 类型)。
## 头文件
```cpp
#include <XCEngine/RHI/D3D12/D3D12Buffer.h>
```
## 继承关系
```
RHIBuffer (interface)
└── D3D12Buffer (implementation)
```
## 公共成员函数
### 构造函数与析构函数
#### `D3D12Buffer()`
默认构造函数。
#### `~D3D12Buffer() override`
析构函数,确保调用 `Shutdown()`
### 初始化
#### `bool Initialize(ID3D12Device* device, uint64_t size, D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_COMMON, D3D12_HEAP_TYPE heapType = D3D12_HEAP_TYPE_DEFAULT)`
创建新缓冲区。
- `device`: D3D12 设备
- `size`: 缓冲区大小(字节)
- `initialState`: 初始资源状态
- `heapType`: 堆类型 (DEFAULT, UPLOAD, READBACK)
- 返回: 初始化是否成功
#### `bool InitializeFromExisting(ID3D12Resource* resource)`
从现有 D3D12 资源初始化。
- `resource`: 已存在的 `ID3D12Resource` 指针
#### `bool InitializeWithData(ID3D12Device* device, ID3D12GraphicsCommandList* commandList, const void* data, uint64_t size, D3D12_RESOURCE_STATES finalState)`
创建缓冲区并从内存数据初始化内容。
- `device`: D3D12 设备
- `commandList`: 命令列表(用于复制数据)
- `data`: 初始数据指针
- `size`: 数据大小
- `finalState`: 数据复制完成后的目标状态
#### `void Shutdown() override`
释放缓冲区资源。
### 数据操作
#### `void UpdateData(const void* data, uint64_t size)`
更新缓冲区数据(需要 UPLOAD 堆类型)。
#### `void SetData(const void* data, size_t size, size_t offset = 0) override`
设置缓冲区数据。
#### `void* Map() override`
映射缓冲区内存到 CPU 可访问。
#### `void Unmap() override`
解除缓冲区内存映射。
### 资源信息
#### `ID3D12Resource* GetResource() const`
获取底层 `ID3D12Resource` 指针。
#### `D3D12_RESOURCE_DESC GetDesc() const`
获取资源描述。
#### `D3D12_GPU_VIRTUAL_ADDRESS GetGPUVirtualAddress() const`
获取 GPU 虚拟地址。
#### `uint64_t GetGPUAddress() const`
获取 GPU 地址(等同于 `GetGPUVirtualAddress`)。
#### `uint64_t GetSize() const override`
获取缓冲区大小。
#### `ResourceStates GetState() const`
获取当前资源状态。
#### `void SetState(ResourceStates state)`
设置资源状态。
### 接口实现
#### `void* GetNativeHandle() override { return m_resource.Get(); }`
返回原生句柄。
#### `const std::string& GetName() const override`
获取对象名称。
#### `void SetName(const std::string& name) override`
设置对象名称。
#### `uint32_t GetStride() const override`
获取顶点步长。
#### `BufferType GetBufferType() const override`
获取缓冲区类型。
#### `void SetStride(uint32_t stride) override`
设置顶点步长。
#### `void SetBufferType(BufferType type) override`
设置缓冲区类型。
## 内部成员
| 成员 | 类型 | 描述 |
|------|------|------|
| `m_resource` | `ComPtr<ID3D12Resource>` | D3D12 资源对象 |
| `m_state` | `ResourceStates` | 当前资源状态 |
| `m_name` | `std::string` | 对象名称 |
| `m_stride` | `uint32_t` | 顶点步长 |
| `m_bufferType` | `BufferType` | 缓冲区类型 |
## 使用示例
### 创建顶点缓冲区
```cpp
D3D12Buffer vertexBuffer;
struct Vertex { float pos[3]; float uv[2]; };
if (vertexBuffer.Initialize(
device->GetDevice(),
sizeof(Vertex) * vertexCount,
D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
D3D12_HEAP_TYPE_DEFAULT))
{
vertexBuffer.SetName(L"VertexBuffer");
vertexBuffer.SetStride(sizeof(Vertex));
vertexBuffer.SetBufferType(BufferType::Vertex);
}
```
### 创建并初始化索引缓冲区
```cpp
D3D12Buffer indexBuffer;
uint16_t indices[] = { 0, 1, 2, ... };
D3D12CommandList cmdList;
cmdList.Initialize(device->GetDevice());
indexBuffer.InitializeWithData(
device->GetDevice(),
cmdList.GetCommandList(),
indices,
sizeof(indices),
D3D12_RESOURCE_STATE_INDEX_BUFFER);
cmdList.Close();
```
### 更新 UPLOAD 缓冲区
```cpp
D3D12Buffer uploadBuffer;
uploadBuffer.Initialize(device, bufferSize, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_HEAP_TYPE_UPLOAD);
void* mapped = uploadBuffer.Map();
memcpy(mapped, data, dataSize);
uploadBuffer.Unmap();
```
## 备注
- `D3D12_HEAP_TYPE_DEFAULT`: GPU 专用显存,适合渲染使用
- `D3D12_HEAP_TYPE_UPLOAD`: CPU 可写 GPU 可读的堆,用于上传数据
- `D3D12_HEAP_TYPE_READBACK`: CPU 可读 GPU 回读数据的堆
- 创建后立即使用需注意资源状态转换