feat: 实现 D3D12CommandList 命令列表类

- 添加 D3D12CommandList.h 头文件,包含 Viewport、Rect、ResourceBarrierDesc 结构体
- 实现 ID3D12GraphicsCommandList 封装
- 实现所有渲染命令:TransitionBarrier、UAVBarrier、AliasBarrier
- 实现状态追踪和资源追踪
- 添加到 CMakeLists.txt 构建系统
- 修复 tests/D3D12/run.bat 路径问题
This commit is contained in:
2026-03-15 18:05:06 +08:00
parent 58341c9daf
commit bf37b1c00c
4 changed files with 447 additions and 3 deletions

View File

@@ -0,0 +1,116 @@
#pragma once
#include <d3d12.h>
#include <wrl/client.h>
#include <vector>
#include <unordered_map>
#include "../Enums.h"
#include "D3D12Enum.h"
using Microsoft::WRL::ComPtr;
namespace XCEngine {
namespace RHI {
struct Viewport {
float topLeftX;
float topLeftY;
float width;
float height;
float minDepth;
float maxDepth;
};
struct Rect {
int32_t left;
int32_t top;
int32_t right;
int32_t bottom;
};
struct ResourceBarrierDesc {
ID3D12Resource* resource;
ResourceStates stateBefore;
ResourceStates stateAfter;
uint32_t subresource;
};
class D3D12CommandList {
public:
D3D12CommandList();
~D3D12CommandList();
bool Initialize(ID3D12Device* device, CommandQueueType type = CommandQueueType::Direct);
void Shutdown();
void Reset(ID3D12CommandAllocator* allocator);
void Close();
ID3D12GraphicsCommandList* GetCommandList() const { return m_commandList.Get(); }
void TransitionBarrier(ID3D12Resource* resource, ResourceStates stateBefore, ResourceStates stateAfter, uint32_t subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES);
void UAVBarrier(ID3D12Resource* resource = nullptr);
void AliasBarrier(ID3D12Resource* beforeResource = nullptr, ID3D12Resource* afterResource = nullptr);
void SetPipelineState(ID3D12PipelineState* pso);
void SetRootSignature(ID3D12RootSignature* signature);
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 SetPrimitiveTopology(PrimitiveTopology topology);
void SetRenderTargets(uint32_t count, ID3D12Resource** renderTargets, ID3D12Resource* depthStencil = nullptr);
void SetVertexBuffer(uint32_t slot, ID3D12Resource* buffer, uint64_t offset, uint32_t stride);
void SetVertexBuffers(uint32_t startSlot, uint32_t count, const D3D12_VERTEX_BUFFER_VIEW* views);
void SetIndexBuffer(ID3D12Resource* buffer, uint64_t offset, Format indexFormat);
void SetDescriptorHeap(ID3D12DescriptorHeap* heap);
void SetGraphicsDescriptorTable(uint32_t rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE baseHandle);
void SetComputeDescriptorTable(uint32_t rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE baseHandle);
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(ID3D12Resource* argBuffer, uint64_t alignedByteOffset);
void DrawIndexedInstancedIndirect(ID3D12Resource* argBuffer, uint64_t alignedByteOffset);
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(D3D12_GPU_DESCRIPTOR_HANDLE viewHandle, D3D12_CPU_DESCRIPTOR_HANDLE resourceHandle, ID3D12Resource* unorderedAccess, const float values[4], uint32_t rectCount = 0, const D3D12_RECT* rects = nullptr);
void CopyResource(ID3D12Resource* dst, ID3D12Resource* 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 threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ);
void DispatchIndirect(ID3D12Resource* argBuffer, uint64_t alignedByteOffset);
void ExecuteBundle(ID3D12GraphicsCommandList* bundle);
ResourceStates GetResourceState(ID3D12Resource* resource) const;
void TrackResource(ID3D12Resource* resource);
private:
ComPtr<ID3D12GraphicsCommandList> m_commandList;
CommandQueueType m_type;
std::unordered_map<ID3D12Resource*, ResourceStates> m_resourceStateMap;
std::vector<ID3D12Resource*> m_trackedResources;
D3D12_PRIMITIVE_TOPOLOGY m_currentTopology;
ID3D12PipelineState* m_currentPipelineState;
ID3D12RootSignature* m_currentRootSignature;
ID3D12DescriptorHeap* m_currentDescriptorHeap;
};
} // namespace RHI
} // namespace XCEngine