270 lines
8.8 KiB
Markdown
270 lines
8.8 KiB
Markdown
|
|
# 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 是一种优化手段,可以复用频繁执行的命令序列
|