From 17c8ea46c5287454f79942c39ae880cb4595a3e6 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Sun, 15 Mar 2026 03:23:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0D3D12Fence=E5=B0=81?= =?UTF-8?q?=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加D3D12Fence类封装ID3D12Fence - 包含Signal/Wait/GetCompletedValue等同步功能 - 更新测试项目使用新的封装类 --- engine/CMakeLists.txt | 2 + .../include/XCEngine/RHI/D3D12/D3D12Fence.h | 34 ++++++++++++ engine/src/RHI/D3D12Fence.cpp | 52 +++++++++++++++++++ tests/D3D12/main.cpp | 14 +++-- 4 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 engine/include/XCEngine/RHI/D3D12/D3D12Fence.h create mode 100644 engine/src/RHI/D3D12Fence.cpp diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index d8f9ec3e..2c07f6a6 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -87,9 +87,11 @@ add_library(XCEngine STATIC include/XCEngine/RHI/D3D12/D3D12Device.h include/XCEngine/RHI/D3D12/D3D12CommandQueue.h include/XCEngine/RHI/D3D12/D3D12CommandAllocator.h + include/XCEngine/RHI/D3D12/D3D12Fence.h src/RHI/D3D12Device.cpp src/RHI/D3D12CommandQueue.cpp src/RHI/D3D12CommandAllocator.cpp + src/RHI/D3D12Fence.cpp ) target_include_directories(XCEngine PUBLIC diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12Fence.h b/engine/include/XCEngine/RHI/D3D12/D3D12Fence.h new file mode 100644 index 00000000..956fb990 --- /dev/null +++ b/engine/include/XCEngine/RHI/D3D12/D3D12Fence.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +#include + +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 m_fence; + void* m_eventHandle; +}; + +} // namespace RHI +} // namespace XCEngine diff --git a/engine/src/RHI/D3D12Fence.cpp b/engine/src/RHI/D3D12Fence.cpp new file mode 100644 index 00000000..57465e81 --- /dev/null +++ b/engine/src/RHI/D3D12Fence.cpp @@ -0,0 +1,52 @@ +#include "XCEngine/RHI/D3D12/D3D12Fence.h" +#include + +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 diff --git a/tests/D3D12/main.cpp b/tests/D3D12/main.cpp index 248c08a0..03bb74c6 100644 --- a/tests/D3D12/main.cpp +++ b/tests/D3D12/main.cpp @@ -16,6 +16,7 @@ #include "XCEngine/RHI/D3D12/D3D12Device.h" #include "XCEngine/RHI/D3D12/D3D12CommandQueue.h" #include "XCEngine/RHI/D3D12/D3D12CommandAllocator.h" +#include "XCEngine/RHI/D3D12/D3D12Fence.h" using namespace XCEngine::RHI; @@ -47,8 +48,7 @@ XCEngine::RHI::D3D12CommandAllocator gCommandAllocator; ID3D12GraphicsCommandList* gCommandList = nullptr; // 同步对象 -ID3D12Fence* gFence = nullptr; -HANDLE gFenceEvent = nullptr; +XCEngine::RHI::D3D12Fence gFence; UINT64 gFenceValue = 0; //================================================================================= @@ -646,8 +646,7 @@ bool InitD3D12(HWND inHWND, int inWidth, int inHeight) { gCommandAllocator.Initialize(device, XCEngine::RHI::CommandQueueType::Direct); 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)); - gFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); + gFence.Initialize(device, 0); return true; } @@ -664,9 +663,8 @@ ID3D12GraphicsCommandList* GetCommandList() { } void WaitForCompletionOfCommandList() { - if (gFence->GetCompletedValue() < gFenceValue) { - gFence->SetEventOnCompletion(gFenceValue, gFenceEvent); - WaitForSingleObject(gFenceEvent, INFINITE); + if (gFence.GetCompletedValue() < gFenceValue) { + gFence.Wait(gFenceValue); } } @@ -679,7 +677,7 @@ void EndCommandList() { ID3D12CommandList* ppCommandLists[] = { gCommandList }; gCommandQueue.ExecuteCommandLists(1, ppCommandLists); gFenceValue += 1; - gCommandQueue.Signal(gFence, gFenceValue); + gCommandQueue.Signal(gFence.GetFence(), gFenceValue); } //=================================================================================