Files
XCEngine/docs/api/rhi/d3d12/d3d12-command-list.md

270 lines
8.8 KiB
Markdown
Raw Normal View History

# D3D12CommandList
DirectX 12 图形命令列表的 D3D12 实现,封装了 `ID3D12GraphicsCommandList`
## 头文件
```cpp
#include <XCEngine/RHI/D3D12/D3D12CommandList.h>
```
## 类概览
`D3D12CommandList` 继承自 `RHICommandList`,是 D3D12 渲染命令的录制和执行载体。它封装了 `ID3D12GraphicsCommandList`,并提供状态跟踪和资源管理功能。
## 公共成员函数
### 初始化与销毁
#### `bool Initialize(ID3D12Device* device, CommandQueueType type = CommandQueueType::Direct, ID3D12CommandAllocator* allocator = nullptr)`
初始化命令列表。
- `device`: D3D12 设备指针
- `type`: 命令队列类型 (Direct, Compute, Copy)
- `allocator`: 可选命令分配器
- 返回: 初始化是否成功
#### `void Shutdown()`
关闭并释放命令列表。
### 命令录制控制
#### `void Reset()`
重置命令列表,重新开始录制。
#### `void Close()`
关闭命令列表,停止录制。
#### `ID3D12GraphicsCommandList* GetCommandList() const`
获取底层 `ID3D12GraphicsCommandList` 指针。
### 资源状态转换
#### `void TransitionBarrier(void* resource, ResourceStates stateBefore, ResourceStates stateAfter)`
添加资源状态转换屏障。
#### `void UAVBarrier(void* resource = nullptr)`
添加无序访问视图屏障。
#### `void AliasBarrier(void* beforeResource = nullptr, void* afterResource = nullptr)`
添加别名化屏障。
### 管线状态设置
#### `void SetPipelineState(void* pso)`
设置图形管线状态对象。
#### `void SetRootSignature(ID3D12RootSignature* signature)`
设置根签名。
#### `void SetPrimitiveTopology(PrimitiveTopology topology)`
设置图元拓扑类型。
### 视口与裁剪矩形
#### `void SetViewport(const Viewport& viewport)`
设置单个视口。
#### `void SetViewports(uint32_t count, const Viewport* viewports)`
设置多个视口。
#### `void SetScissorRect(const Rect& rect)`
设置单个裁剪矩形。
#### `void SetScissorRects(uint32_t count, const Rect* rects)`
设置多个裁剪矩形。
### 渲染目标
#### `void SetRenderTargets(uint32_t count, void** renderTargets, void* depthStencil = nullptr)`
设置渲染目标视图。
#### `void SetRenderTargetsInternal(uint32_t count, ID3D12Resource** renderTargets, ID3D12Resource* depthStencil = nullptr)`
内部方法,直接使用 D3D12 资源指针。
#### `void SetRenderTargetsHandle(uint32_t count, const D3D12_CPU_DESCRIPTOR_HANDLE* renderTargetHandles, const D3D12_CPU_DESCRIPTOR_HANDLE* depthStencilHandle = nullptr)`
使用 CPU 描述符句柄设置渲染目标。
### 顶点缓冲区与索引缓冲区
#### `void SetVertexBuffer(uint32_t slot, void* buffer, uint64_t offset, uint32_t stride)`
设置单个顶点缓冲区。
#### `void SetVertexBuffers(uint32_t startSlot, uint32_t count, const uint64_t* buffers, const uint64_t* offsets, const uint32_t* strides)`
批量设置顶点缓冲区。
#### `void SetIndexBuffer(void* buffer, uint64_t offset, Format format)`
设置索引缓冲区。
### 描述符堆
#### `void SetDescriptorHeap(ID3D12DescriptorHeap* heap)`
设置描述符堆。
#### `void SetDescriptorHeaps(uint32_t count, ID3D12DescriptorHeap** heaps)`
设置多个描述符堆。
### 描述符表绑定
#### `void SetGraphicsDescriptorTable(uint32_t rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE baseHandle)`
设置图形渲染的描述符表。
#### `void SetComputeDescriptorTable(uint32_t rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE baseHandle)`
设置计算渲染的描述符表。
### 根参数绑定
#### `void SetGraphicsRootConstantBufferView(uint32_t rootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS bufferLocation)`
设置根常量缓冲区视图。
#### `void SetGraphicsRoot32BitConstants(uint32_t rootParameterIndex, uint32_t num32BitValuesToSet, const void* pSrcData, uint32_t destOffsetIn32BitValues)`
设置根参数 32 位常量。
#### `void SetGraphicsRootDescriptorTable(uint32_t rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor)`
设置根描述符表。
#### `void SetGraphicsRootShaderResourceView(uint32_t rootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS shaderResource)`
设置根着色器资源视图。
### 渲染状态
#### `void SetStencilRef(uint32_t stencilRef)`
设置模板参考值。
#### `void SetBlendFactor(const float blendFactor[4])`
设置混合因子。
#### `void SetDepthBias(float depthBias, float slopeScaledDepthBias, float depthBiasClamp)`
设置深度偏移。
### 绘制命令
#### `void Draw(uint32_t vertexCount, uint32_t instanceCount = 1, uint32_t startVertex = 0, uint32_t startInstance = 0)`
绘制非索引图元。
#### `void DrawIndexed(uint32_t indexCount, uint32_t instanceCount = 1, uint32_t startIndex = 0, int32_t baseVertex = 0, uint32_t startInstance = 0)`
绘制索引图元。
#### `void DrawInstancedIndirect(void* argBuffer, uint64_t alignedByteOffset)`
间接绘制实例化图元。
#### `void DrawIndexedInstancedIndirect(void* argBuffer, uint64_t alignedByteOffset)`
间接绘制索引实例化图元。
### 清除命令
#### `void Clear(float r, float g, float b, float a, uint32_t buffers)`
清除渲染目标和/或深度模板缓冲区。
#### `void ClearRenderTarget(void* renderTarget, const float color[4])`
清除渲染目标。
#### `void ClearDepthStencil(void* depthStencil, float depth, uint8_t stencil)`
清除深度模板缓冲区。
#### `void ClearRenderTargetView(ID3D12Resource* renderTarget, const float color[4], uint32_t rectCount = 0, const D3D12_RECT* rects = nullptr)`
使用资源指针清除渲染目标。
#### `void ClearDepthStencilView(ID3D12Resource* depthStencil, uint32_t clearFlags, float depth = 1.0f, uint8_t stencil = 0, uint32_t rectCount = 0, const D3D12_RECT* rects = nullptr)`
使用资源指针清除深度模板。
#### `void ClearUnorderedAccessView(...)`
清除无序访问视图。
### 资源复制
#### `void CopyResource(void* dst, void* src)`
复制整个资源。
#### `void CopyBuffer(ID3D12Resource* dst, uint64_t dstOffset, ID3D12Resource* src, uint64_t srcOffset, uint64_t size)`
复制缓冲区数据。
#### `void CopyTexture(ID3D12Resource* dst, const D3D12_TEXTURE_COPY_LOCATION& dstLocation, ID3D12Resource* src, const D3D12_TEXTURE_COPY_LOCATION& srcLocation)`
复制纹理数据。
### 查询
#### `void BeginQuery(ID3D12QueryHeap* queryHeap, QueryType type, uint32_t index)`
开始查询。
#### `void EndQuery(ID3D12QueryHeap* queryHeap, QueryType type, uint32_t index)`
结束查询。
#### `void ResolveQueryData(ID3D12QueryHeap* queryHeap, QueryType type, uint32_t startIndex, uint32_t count, ID3D12Resource* resultBuffer, uint64_t resultOffset)`
解析查询数据。
### 计算着色器
#### `void Dispatch(uint32_t x, uint32_t y, uint32_t z)`
分发计算着色器。
#### `void DispatchIndirect(void* argBuffer, uint64_t alignedByteOffset)`
间接分发计算着色器。
### Bundle
#### `void ExecuteBundle(ID3D12GraphicsCommandList* bundle)`
执行 Bundle 命令列表。
### 资源状态管理
#### `ResourceStates GetResourceState(ID3D12Resource* resource) const`
获取资源当前状态。
#### `void TrackResource(ID3D12Resource* resource)`
跟踪资源状态变化。
## 内部成员
| 成员 | 类型 | 描述 |
|------|------|------|
| `m_commandList` | `ComPtr<ID3D12GraphicsCommandList>` | D3D12 命令列表 |
| `m_type` | `CommandQueueType` | 命令队列类型 |
| `m_resourceStateMap` | `unordered_map<ID3D12Resource*, ResourceStates>` | 资源状态映射 |
| `m_trackedResources` | `vector<ID3D12Resource*>` | 跟踪的资源列表 |
| `m_currentTopology` | `D3D12_PRIMITIVE_TOPOLOGY` | 当前拓扑类型 |
| `m_currentPipelineState` | `ID3D12PipelineState*` | 当前 PSO |
| `m_currentRootSignature` | `ID3D12RootSignature*` | 当前根签名 |
| `m_currentDescriptorHeap` | `ID3D12DescriptorHeap*` | 当前描述符堆 |
## 使用示例
```cpp
D3D12Device device;
device.Initialize(desc);
// Create command queue and list
CommandQueueDesc queueDesc;
queueDesc.type = CommandQueueType::Direct;
D3D12CommandQueue* cmdQueue = device.CreateCommandQueueImpl(queueDesc);
CommandListDesc listDesc;
listDesc.type = CommandQueueType::Direct;
D3D12CommandList* cmdList = device.CreateCommandListImpl(listDesc);
// Begin recording
cmdList->Reset();
cmdList->SetPipelineState(pipelineState);
cmdList->SetRenderTargets(1, &rtvHandle, &dsvHandle);
cmdList->SetViewports(1, &viewport);
cmdList->SetScissorRect(scissorRect);
cmdList->SetVertexBuffers(0, 1, &vbv);
cmdList->DrawIndexed(indexCount, 1, 0, 0, 0);
cmdList->Close();
// Execute
cmdQueue->ExecuteCommandListsInternal(1, &cmdList);
```
## 继承关系
```
RHICommandList (interface)
└── D3D12CommandList (implementation)
```
## 备注
- D3D12CommandList 内部维护资源状态映射,自动处理资源状态转换
- 使用 `TrackResource` 可以将自定义资源添加到状态跟踪系统
- Bundle 是一种优化手段,可以复用频繁执行的命令序列