修复 D3D12 截图功能:修复 GPU 过载导致的设备移除问题
问题根因: 1. 渲染循环帧率过高导致 GPU 过载(TDR) 2. D3D12CommandList::Reset() 未正确调用底层 Reset() 修复内容: 1. 在 Present 后添加 Sleep(10) 延迟防止 GPU 过载 2. 修复 D3D12CommandList::Reset() 正确调用底层 m_commandList->Reset() 3. 在 D3D12CommandList 中存储 CommandAllocator 引用 4. 在 main_minimal.cpp 中添加截图调用逻辑(30帧后截图保存为 minimal.ppm) 修改文件: - engine/include/XCEngine/RHI/D3D12/D3D12CommandList.h - engine/src/RHI/D3D12/D3D12CommandList.cpp - tests/RHI/D3D12/integration/main_minimal.cpp (新增)
This commit is contained in:
@@ -64,7 +64,9 @@ public:
|
||||
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 SetStencilRef(uint8_t stencilRef) override;
|
||||
void SetDepthStencilState(const DepthStencilState& state) override;
|
||||
void SetBlendState(const BlendState& state) override;
|
||||
void SetBlendFactor(const float blendFactor[4]);
|
||||
void SetDepthBias(float depthBias, float slopeScaledDepthBias, float depthBiasClamp);
|
||||
|
||||
@@ -104,6 +106,7 @@ public:
|
||||
|
||||
private:
|
||||
ComPtr<ID3D12GraphicsCommandList> m_commandList;
|
||||
ComPtr<ID3D12CommandAllocator> m_commandAllocator;
|
||||
CommandQueueType m_type;
|
||||
|
||||
std::unordered_map<ID3D12Resource*, ResourceStates> m_resourceStateMap;
|
||||
|
||||
@@ -18,6 +18,8 @@ D3D12CommandList::~D3D12CommandList() {
|
||||
bool D3D12CommandList::Initialize(ID3D12Device* device, CommandQueueType type, ID3D12CommandAllocator* allocator) {
|
||||
D3D12_COMMAND_LIST_TYPE listType = ToD3D12(type);
|
||||
|
||||
m_commandAllocator = allocator;
|
||||
|
||||
HRESULT hResult = device->CreateCommandList(
|
||||
0,
|
||||
listType,
|
||||
@@ -42,10 +44,15 @@ void D3D12CommandList::Shutdown() {
|
||||
}
|
||||
|
||||
void D3D12CommandList::Reset() {
|
||||
if (m_commandList && m_commandAllocator) {
|
||||
m_commandList->Reset(m_commandAllocator.Get(), nullptr);
|
||||
}
|
||||
m_currentTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
m_currentPipelineState = nullptr;
|
||||
m_currentRootSignature = nullptr;
|
||||
m_currentDescriptorHeap = nullptr;
|
||||
m_resourceStateMap.clear();
|
||||
m_trackedResources.clear();
|
||||
}
|
||||
|
||||
void D3D12CommandList::Close() {
|
||||
@@ -106,6 +113,15 @@ void D3D12CommandList::SetPipelineStateInternal(ID3D12PipelineState* pso) {
|
||||
m_currentPipelineState = pso;
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetRootSignature(ID3D12RootSignature* signature) {
|
||||
m_commandList->SetGraphicsRootSignature(signature);
|
||||
m_currentRootSignature = signature;
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetBlendFactor(const float blendFactor[4]) {
|
||||
m_commandList->OMSetBlendFactor(blendFactor);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetViewport(const Viewport& viewport) {
|
||||
D3D12_VIEWPORT d3d12Viewport = {};
|
||||
d3d12Viewport.TopLeftX = viewport.topLeftX;
|
||||
@@ -179,6 +195,10 @@ void D3D12CommandList::SetRenderTargetsInternal(uint32_t count, ID3D12Resource**
|
||||
m_commandList->OMSetRenderTargets(count, count > 0 ? rtvHandles.data() : nullptr, FALSE, depthStencil ? &dsvHandle : nullptr);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetRenderTargetsHandle(uint32_t count, const D3D12_CPU_DESCRIPTOR_HANDLE* renderTargetHandles, const D3D12_CPU_DESCRIPTOR_HANDLE* depthStencilHandle) {
|
||||
m_commandList->OMSetRenderTargets(count, renderTargetHandles, FALSE, depthStencilHandle);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetVertexBuffer(uint32_t slot, void* buffer, uint64_t offset, uint32_t stride) {
|
||||
SetVertexBufferInternal(slot, static_cast<ID3D12Resource*>(buffer), offset, stride);
|
||||
}
|
||||
@@ -252,10 +272,18 @@ void D3D12CommandList::SetGraphicsRootShaderResourceView(uint32_t rootParameterI
|
||||
m_commandList->SetGraphicsRootShaderResourceView(rootParameterIndex, shaderResource);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetStencilRef(uint32_t stencilRef) {
|
||||
void D3D12CommandList::SetStencilRef(uint8_t stencilRef) {
|
||||
m_commandList->OMSetStencilRef(stencilRef);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetDepthStencilState(const DepthStencilState& state) {
|
||||
// TODO: Implement depth stencil state
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetBlendState(const BlendState& state) {
|
||||
// TODO: Implement blend state
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetDepthBias(float depthBias, float slopeScaledDepthBias, float depthBiasClamp) {
|
||||
}
|
||||
|
||||
@@ -292,6 +320,18 @@ void D3D12CommandList::ClearRenderTargetView(D3D12_CPU_DESCRIPTOR_HANDLE renderT
|
||||
m_commandList->ClearRenderTargetView(renderTargetHandle, color, rectCount, rects);
|
||||
}
|
||||
|
||||
void D3D12CommandList::Clear(float r, float g, float b, float a, uint32_t buffers) {
|
||||
// Not implemented - use ClearRenderTargetView and ClearDepthStencilView directly
|
||||
}
|
||||
|
||||
void D3D12CommandList::ClearRenderTarget(void* renderTarget, const float color[4]) {
|
||||
ClearRenderTargetView(static_cast<ID3D12Resource*>(renderTarget), color, 0, nullptr);
|
||||
}
|
||||
|
||||
void D3D12CommandList::ClearDepthStencil(void* depthStencil, float depth, uint8_t stencil) {
|
||||
ClearDepthStencilView(static_cast<ID3D12Resource*>(depthStencil), D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, depth, stencil, 0, nullptr);
|
||||
}
|
||||
|
||||
void D3D12CommandList::ClearDepthStencilView(ID3D12Resource* depthStencil, uint32_t clearFlags, float depth, uint8_t stencil, uint32_t rectCount, const D3D12_RECT* rects) {
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = {};
|
||||
m_commandList->ClearDepthStencilView(dsvHandle, static_cast<D3D12_CLEAR_FLAGS>(clearFlags), depth, stencil, rectCount, rects);
|
||||
|
||||
Reference in New Issue
Block a user