Cogs.Core
SyncObjectsD3D12.cpp
1#include "Foundation/Logging/Logger.h"
2#include "SyncObjectsD3D12.h"
3#include "GraphicsDeviceD3D12.h"
4
5namespace {
6 Cogs::Logging::Log logger = Cogs::Logging::getLogger("SyncObjectsD3D12");
7}
8
9
10void Cogs::SyncObjectsD3D12::setDevice(ResourcePointer<ID3D12Device>& device)
11{
12 this->device = device;
13}
14
16{
17 FenceD3D12 fence{};
18 if (HRESULT hr = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(fence.fence.internalPointer())); SUCCEEDED(hr)) {
19 return fences.addResource(fence);
20 }
22}
23
25{
26 if (HandleIsValid(fenceHandle)) {
27 FenceD3D12& fence = fences[fenceHandle];
28 if (fence.event) {
29 CloseHandle(fence.event);
30 }
31 fences.removeResource(fenceHandle);
32 }
33}
34
36{
37 if (HandleIsValid(fenceHandle)) {
38 FenceD3D12& fence = fences[fenceHandle];
39 fence.value++;
40 }
41}
42
44{
45 if (!HandleIsValid(fenceHandle)) {
46 LOG_WARNING_ONCE(logger, "isFenceSignalled: fenceHandle is invalid.");
47 return false;
48 }
49
50 FenceD3D12& fence = fences[fenceHandle];
51 return fence.value == fence.fence->GetCompletedValue();
52}
53
54bool Cogs::SyncObjectsD3D12::waitFence(FenceHandle fenceHandle, uint32_t timeout_ms)
55{
56 if (!HandleIsValid(fenceHandle)) {
57 LOG_WARNING_ONCE(logger, "waitFence: fenceHandle is invalid.");
58 return false;
59 }
60
61 // First, try early exit by checking if fence is already signalled.
62 FenceD3D12& fence = fences[fenceHandle];
63 if (fence.value == fence.fence->GetCompletedValue()) {
64 return true;
65 }
66
67 // Make sure we have an unsignalled event and tie this to the fence
68 if (fence.event == nullptr) {
69 fence.event = CreateEvent(nullptr, TRUE, FALSE, nullptr);
70 assert(fence.event);
71 }
72 else if (ResetEvent(fence.event) == 0) {
73 LOG_WARNING(logger, "ResetEvent failed: 0x%x", GetLastError());
74 return false;
75 }
76 fence.fence->SetEventOnCompletion(fence.value, fence.event);
77
78 // Wait
79 DWORD result = WaitForSingleObject(fence.event, timeout_ms);
80 switch (result) {
81 case WAIT_OBJECT_0:
82 return true;
83
84 case WAIT_TIMEOUT:
85 return false;
86
87 default:
88 LOG_WARNING(logger, "WaitForSingleObject failed: 0x%x", GetLastError());
89 return false;
90 }
91}
Log implementation class.
Definition: LogManager.h:139
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180
Handle template class used to provide opaque, non-converting handles.
Definition: Common.h:22
static const Handle_t NoHandle
Represents a handle to nothing.
Definition: Common.h:77
void releaseFence(FenceHandle fenceHandle) override
Release an existing fence object.
void resetFence(FenceHandle fenceHandle) override
Explicitly set fence into unsignalled state unsignalled.
bool isFenceSignalled(FenceHandle fenceHandle) override
Poll to see if a fence has been signalled.
FenceHandle createFence() override
Create a new fence object.
bool waitFence(FenceHandle fenceHandle, uint32_t timeout_ms) override
Try to let CPU wait for a fence to be signalled.