Skip to content

Commit 567cd3b

Browse files
committed
Added a secondary set of image available Semaphores to double buffer them to avoid reuse while they are still being used.
1 parent c2fda5c commit 567cd3b

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

include/vsg/app/Window.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ namespace vsg
126126
};
127127

128128
using Frames = std::vector<Frame>;
129+
using Semaphores = std::vector<ref_ptr<Semaphore>>;
129130

130131
Frame& frame(size_t i) { return _frames[i]; }
131132
Frames& frames() { return _frames; }
@@ -174,10 +175,11 @@ namespace vsg
174175
ref_ptr<Image> _multisampleDepthImage;
175176
ref_ptr<ImageView> _multisampleDepthImageView;
176177

177-
ref_ptr<Semaphore> _availableSemaphore;
178-
179178
Frames _frames;
180179
std::vector<size_t> _indices;
180+
181+
Semaphores _availableSemaphores;
182+
size_t _availableSemaphoreIndex = 0;
181183
};
182184
VSG_type_name(vsg::Window);
183185

src/vsg/app/Window.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,6 @@ void Window::buildSwapchain()
370370
// set up framebuffer and associated resources
371371
auto& imageViews = _swapchain->getImageViews();
372372

373-
_availableSemaphore = vsg::Semaphore::create(_device, _traits->imageAvailableSemaphoreWaitFlag);
374-
375373
size_t initial_indexValue = imageViews.size();
376374
for (size_t i = 0; i < imageViews.size(); ++i)
377375
{
@@ -397,6 +395,12 @@ void Window::buildSwapchain()
397395
_indices.push_back(initial_indexValue);
398396
}
399397

398+
_availableSemaphoreIndex = 0;
399+
for (size_t i = 0; i < imageViews.size(); ++i)
400+
{
401+
_availableSemaphores.push_back(vsg::Semaphore::create(_device, _traits->imageAvailableSemaphoreWaitFlag));
402+
}
403+
400404
{
401405
// ensure image attachments are setup on GPU.
402406
auto commandPool = CommandPool::create(_device, graphicsFamily);
@@ -434,18 +438,19 @@ VkResult Window::acquireNextImage(uint64_t timeout)
434438
{
435439
if (!_swapchain) _initSwapchain();
436440

437-
if (!_availableSemaphore) _availableSemaphore = vsg::Semaphore::create(_device, _traits->imageAvailableSemaphoreWaitFlag);
441+
auto& availableSemaphore = _availableSemaphores[_availableSemaphoreIndex];
442+
_availableSemaphoreIndex = (_availableSemaphoreIndex + 1) % _availableSemaphores.size();
438443

439444
// check the dimensions of the swapchain and window extents are consistent, if not return a VK_ERROR_OUT_OF_DATE_KHR
440445
if (_swapchain->getExtent() != _extent2D) return VK_ERROR_OUT_OF_DATE_KHR;
441446

442447
uint32_t nextImageIndex;
443-
VkResult result = _swapchain->acquireNextImage(timeout, _availableSemaphore, {}, nextImageIndex);
448+
VkResult result = _swapchain->acquireNextImage(timeout, availableSemaphore, {}, nextImageIndex);
444449

445450
if (result == VK_SUCCESS)
446451
{
447452
// the acquired image's semaphore must be available now so make it the new _availableSemaphore and set its entry to the one to use for the next frame by swapping ref_ptr<>'s
448-
_availableSemaphore.swap(_frames[nextImageIndex].imageAvailableSemaphore);
453+
availableSemaphore.swap(_frames[nextImageIndex].imageAvailableSemaphore);
449454

450455
// shift up previous frame indices
451456
for (size_t i = _indices.size() - 1; i > 0; --i)

0 commit comments

Comments
 (0)