Vulkan Schnee 0.0.1
High-performance rendering engine
Loading...
Searching...
No Matches
TimelineSynchronizer.cpp
Go to the documentation of this file.
3
4#include <stdexcept>
5#include <utility>
6
7namespace EngineCore
8{
9
11 : context_(context)
12 , framesInFlight_(framesInFlight)
13{
14 if (!context_)
15 {
16 throw std::runtime_error("TimelineSynchronizer requires a valid ApplicationContext");
17 }
18
19 VkSemaphoreTypeCreateInfo typeInfo{
20 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
21 .pNext = nullptr,
22 .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
23 .initialValue = 0,
24 };
25
26 VkSemaphoreCreateInfo createInfo{
27 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
28 .pNext = &typeInfo,
29 .flags = 0,
30 };
31
32 VkResult result = vkCreateSemaphore(context_->getVkDevice(), &createInfo, nullptr, &timelineSemaphore_);
33 if (result != VK_SUCCESS)
34 {
35 throw std::runtime_error("Failed to create timeline semaphore");
36 }
37}
38
40{
41 if (timelineSemaphore_ != VK_NULL_HANDLE && context_)
42 {
43 vkDestroySemaphore(context_->getVkDevice(), timelineSemaphore_, nullptr);
44 timelineSemaphore_ = VK_NULL_HANDLE;
45 }
46}
47
49 : context_(other.context_)
50 , timelineSemaphore_(other.timelineSemaphore_)
51 , framesInFlight_(other.framesInFlight_)
52{
53 other.context_ = nullptr;
54 other.timelineSemaphore_ = VK_NULL_HANDLE;
55 other.framesInFlight_ = 0;
56}
57
59{
60 if (this != &other)
61 {
62 // Clean up existing resources
63 if (timelineSemaphore_ != VK_NULL_HANDLE && context_)
64 {
65 vkDestroySemaphore(context_->getVkDevice(), timelineSemaphore_, nullptr);
66 }
67
68 // Move from other
69 context_ = other.context_;
70 timelineSemaphore_ = other.timelineSemaphore_;
71 framesInFlight_ = other.framesInFlight_;
72
73 // Clear other
74 other.context_ = nullptr;
75 other.timelineSemaphore_ = VK_NULL_HANDLE;
76 other.framesInFlight_ = 0;
77 }
78 return *this;
79}
80
82{
83 uint64_t value = 0;
84 vkGetSemaphoreCounterValue(context_->getVkDevice(), timelineSemaphore_, &value);
85 return value;
86}
87
88void TimelineSynchronizer::waitForValue(uint64_t value, uint64_t timeout) const
89{
90 VkSemaphoreWaitInfo waitInfo{
91 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
92 .pNext = nullptr,
93 .flags = 0,
94 .semaphoreCount = 1,
95 .pSemaphores = &timelineSemaphore_,
96 .pValues = &value,
97 };
98
99 VkResult result = vkWaitSemaphores(context_->getVkDevice(), &waitInfo, timeout);
100 if (result != VK_SUCCESS && result != VK_TIMEOUT)
101 {
102 throw std::runtime_error("Failed to wait on timeline semaphore");
103 }
104}
105
106void TimelineSynchronizer::signalValue(uint64_t value) const
107{
108 VkSemaphoreSignalInfo signalInfo{
109 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO,
110 .pNext = nullptr,
111 .semaphore = timelineSemaphore_,
112 .value = value,
113 };
114
115 VkResult result = vkSignalSemaphore(context_->getVkDevice(), &signalInfo);
116 if (result != VK_SUCCESS)
117 {
118 throw std::runtime_error("Failed to signal timeline semaphore from CPU");
119 }
120}
121
122} // namespace EngineCore
The application context is the core class which stores the basic openxr and vulkan objects.
void signalValue(uint64_t value) const
CPU-side signal of the timeline semaphore.
TimelineSynchronizer(ApplicationContext *context, uint32_t framesInFlight)
Constructs a timeline synchronizer.
TimelineSynchronizer & operator=(const TimelineSynchronizer &)=delete
uint64_t getCurrentValue() const
Gets the current GPU timeline semaphore value.
void waitForValue(uint64_t value, uint64_t timeout=UINT64_MAX) const
CPU-side wait for a specific timeline value.
Log category system implementation.