# D3D12Buffer DirectX 12 缓冲区的 D3D12 实现,封装了 `ID3D12Resource` (buffer 类型)。 ## 头文件 ```cpp #include ``` ## 继承关系 ``` 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` | 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 回读数据的堆 - 创建后立即使用需注意资源状态转换