# D3D12CommandList DirectX 12 图形命令列表的 D3D12 实现,封装了 `ID3D12GraphicsCommandList`。 ## 头文件 ```cpp #include ``` ## 类概览 `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` | D3D12 命令列表 | | `m_type` | `CommandQueueType` | 命令队列类型 | | `m_resourceStateMap` | `unordered_map` | 资源状态映射 | | `m_trackedResources` | `vector` | 跟踪的资源列表 | | `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 是一种优化手段,可以复用频繁执行的命令序列