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); } //=================================================================================