feat: 实现D3D12Fence封装

- 添加D3D12Fence类封装ID3D12Fence
- 包含Signal/Wait/GetCompletedValue等同步功能
- 更新测试项目使用新的封装类
This commit is contained in:
2026-03-15 03:23:39 +08:00
parent 8fb11dc650
commit 17c8ea46c5
4 changed files with 94 additions and 8 deletions

View File

@@ -87,9 +87,11 @@ add_library(XCEngine STATIC
include/XCEngine/RHI/D3D12/D3D12Device.h include/XCEngine/RHI/D3D12/D3D12Device.h
include/XCEngine/RHI/D3D12/D3D12CommandQueue.h include/XCEngine/RHI/D3D12/D3D12CommandQueue.h
include/XCEngine/RHI/D3D12/D3D12CommandAllocator.h include/XCEngine/RHI/D3D12/D3D12CommandAllocator.h
include/XCEngine/RHI/D3D12/D3D12Fence.h
src/RHI/D3D12Device.cpp src/RHI/D3D12Device.cpp
src/RHI/D3D12CommandQueue.cpp src/RHI/D3D12CommandQueue.cpp
src/RHI/D3D12CommandAllocator.cpp src/RHI/D3D12CommandAllocator.cpp
src/RHI/D3D12Fence.cpp
) )
target_include_directories(XCEngine PUBLIC target_include_directories(XCEngine PUBLIC

View File

@@ -0,0 +1,34 @@
#pragma once
#include <d3d12.h>
#include <wrl/client.h>
#include <cstdint>
using Microsoft::WRL::ComPtr;
namespace XCEngine {
namespace RHI {
class D3D12Fence {
public:
D3D12Fence();
~D3D12Fence();
bool Initialize(ID3D12Device* device, uint64_t initialValue = 0);
void Shutdown();
void Signal(uint64_t value);
void Wait(uint64_t value);
uint64_t GetCompletedValue();
void* GetEventHandle() { return m_eventHandle; }
ID3D12Fence* GetFence() const { return m_fence.Get(); }
private:
ComPtr<ID3D12Fence> m_fence;
void* m_eventHandle;
};
} // namespace RHI
} // namespace XCEngine

View File

@@ -0,0 +1,52 @@
#include "XCEngine/RHI/D3D12/D3D12Fence.h"
#include <Windows.h>
namespace XCEngine {
namespace RHI {
D3D12Fence::D3D12Fence()
: m_eventHandle(nullptr) {
}
D3D12Fence::~D3D12Fence() {
Shutdown();
}
bool D3D12Fence::Initialize(ID3D12Device* device, uint64_t initialValue) {
HRESULT hResult = device->CreateFence(
initialValue,
D3D12_FENCE_FLAG_NONE,
IID_PPV_ARGS(&m_fence));
if (FAILED(hResult)) {
return false;
}
m_eventHandle = CreateEvent(nullptr, FALSE, FALSE, nullptr);
return m_eventHandle != nullptr;
}
void D3D12Fence::Shutdown() {
if (m_eventHandle) {
CloseHandle(m_eventHandle);
m_eventHandle = nullptr;
}
m_fence.Reset();
}
void D3D12Fence::Signal(uint64_t value) {
m_fence->Signal(value);
}
void D3D12Fence::Wait(uint64_t value) {
if (m_fence->GetCompletedValue() < value) {
m_fence->SetEventOnCompletion(value, m_eventHandle);
WaitForSingleObject(m_eventHandle, INFINITE);
}
}
uint64_t D3D12Fence::GetCompletedValue() {
return m_fence->GetCompletedValue();
}
} // namespace RHI
} // namespace XCEngine

View File

@@ -16,6 +16,7 @@
#include "XCEngine/RHI/D3D12/D3D12Device.h" #include "XCEngine/RHI/D3D12/D3D12Device.h"
#include "XCEngine/RHI/D3D12/D3D12CommandQueue.h" #include "XCEngine/RHI/D3D12/D3D12CommandQueue.h"
#include "XCEngine/RHI/D3D12/D3D12CommandAllocator.h" #include "XCEngine/RHI/D3D12/D3D12CommandAllocator.h"
#include "XCEngine/RHI/D3D12/D3D12Fence.h"
using namespace XCEngine::RHI; using namespace XCEngine::RHI;
@@ -47,8 +48,7 @@ XCEngine::RHI::D3D12CommandAllocator gCommandAllocator;
ID3D12GraphicsCommandList* gCommandList = nullptr; ID3D12GraphicsCommandList* gCommandList = nullptr;
// 同步对象 // 同步对象
ID3D12Fence* gFence = nullptr; XCEngine::RHI::D3D12Fence gFence;
HANDLE gFenceEvent = nullptr;
UINT64 gFenceValue = 0; UINT64 gFenceValue = 0;
//================================================================================= //=================================================================================
@@ -646,8 +646,7 @@ bool InitD3D12(HWND inHWND, int inWidth, int inHeight) {
gCommandAllocator.Initialize(device, XCEngine::RHI::CommandQueueType::Direct); gCommandAllocator.Initialize(device, XCEngine::RHI::CommandQueueType::Direct);
device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, gCommandAllocator.GetCommandAllocator(), nullptr, IID_PPV_ARGS(&gCommandList)); device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, gCommandAllocator.GetCommandAllocator(), nullptr, IID_PPV_ARGS(&gCommandList));
device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&gFence)); gFence.Initialize(device, 0);
gFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
return true; return true;
} }
@@ -664,9 +663,8 @@ ID3D12GraphicsCommandList* GetCommandList() {
} }
void WaitForCompletionOfCommandList() { void WaitForCompletionOfCommandList() {
if (gFence->GetCompletedValue() < gFenceValue) { if (gFence.GetCompletedValue() < gFenceValue) {
gFence->SetEventOnCompletion(gFenceValue, gFenceEvent); gFence.Wait(gFenceValue);
WaitForSingleObject(gFenceEvent, INFINITE);
} }
} }
@@ -679,7 +677,7 @@ void EndCommandList() {
ID3D12CommandList* ppCommandLists[] = { gCommandList }; ID3D12CommandList* ppCommandLists[] = { gCommandList };
gCommandQueue.ExecuteCommandLists(1, ppCommandLists); gCommandQueue.ExecuteCommandLists(1, ppCommandLists);
gFenceValue += 1; gFenceValue += 1;
gCommandQueue.Signal(gFence, gFenceValue); gCommandQueue.Signal(gFence.GetFence(), gFenceValue);
} }
//================================================================================= //=================================================================================