diff --git a/include/vsg/app/Window.h b/include/vsg/app/Window.h index d1b475d25..8d84920c1 100644 --- a/include/vsg/app/Window.h +++ b/include/vsg/app/Window.h @@ -122,9 +122,11 @@ namespace vsg ref_ptr imageView; ref_ptr framebuffer; ref_ptr imageAvailableSemaphore; + ref_ptr renderFinishedSemaphore; }; using Frames = std::vector; + using Semaphores = std::vector>; Frame& frame(size_t i) { return _frames[i]; } Frames& frames() { return _frames; } @@ -173,10 +175,11 @@ namespace vsg ref_ptr _multisampleDepthImage; ref_ptr _multisampleDepthImageView; - ref_ptr _availableSemaphore; - Frames _frames; std::vector _indices; + + Semaphores _availableSemaphores; + size_t _availableSemaphoreIndex = 0; }; VSG_type_name(vsg::Window); diff --git a/src/vsg/app/Presentation.cpp b/src/vsg/app/Presentation.cpp index 87512249b..2143e512a 100644 --- a/src/vsg/app/Presentation.cpp +++ b/src/vsg/app/Presentation.cpp @@ -34,6 +34,9 @@ VkResult Presentation::present() { vk_swapchains.emplace_back(*(window->getOrCreateSwapchain())); indices.emplace_back(static_cast(imageIndex)); + + auto& renderFinishedSemaphore = window->frame(imageIndex).renderFinishedSemaphore; + vk_semaphores.push_back(renderFinishedSemaphore->vk()); } } diff --git a/src/vsg/app/RecordAndSubmitTask.cpp b/src/vsg/app/RecordAndSubmitTask.cpp index 5306579f2..39fc66f13 100644 --- a/src/vsg/app/RecordAndSubmitTask.cpp +++ b/src/vsg/app/RecordAndSubmitTask.cpp @@ -215,27 +215,33 @@ VkResult RecordAndSubmitTask::finish(ref_ptr recordedCom if (earlyDataTransferredSemaphore) transferTask->assignTransferConsumedCompletedSemaphore(TransferTask::TRANSFER_BEFORE_RECORD_TRAVERSAL, earlyTransferConsumerCompletedSemaphore); if (lateDataTransferredSemaphore) transferTask->assignTransferConsumedCompletedSemaphore(TransferTask::TRANSFER_AFTER_RECORD_TRAVERSAL, lateTransferConsumerCompletedSemaphore); + current_fence->dependentSemaphores().clear(); + for (auto& window : windows) { auto imageIndex = window->imageIndex(); if (imageIndex >= window->numFrames()) continue; - auto& semaphore = window->frame(imageIndex).imageAvailableSemaphore; + auto& frame = window->frame(imageIndex); - vk_waitSemaphores.emplace_back(*semaphore); - vk_waitStages.emplace_back(semaphore->pipelineStageFlags()); + vk_waitSemaphores.emplace_back(frame.imageAvailableSemaphore->vk()); + vk_waitStages.emplace_back(frame.imageAvailableSemaphore->pipelineStageFlags()); + + vk_signalSemaphores.emplace_back(frame.renderFinishedSemaphore->vk()); + current_fence->dependentSemaphores().push_back(frame.renderFinishedSemaphore); } for (auto& semaphore : waitSemaphores) { - vk_waitSemaphores.emplace_back(*(semaphore)); + vk_waitSemaphores.emplace_back(semaphore->vk()); vk_waitStages.emplace_back(semaphore->pipelineStageFlags()); } current_fence->dependentSemaphores() = signalSemaphores; for (auto& semaphore : signalSemaphores) { - vk_signalSemaphores.emplace_back(*(semaphore)); + vk_signalSemaphores.emplace_back(semaphore->vk()); + current_fence->dependentSemaphores().push_back(semaphore); } if (earlyDataTransferredSemaphore) diff --git a/src/vsg/app/Viewer.cpp b/src/vsg/app/Viewer.cpp index bb3206c64..9d8374e92 100644 --- a/src/vsg/app/Viewer.cpp +++ b/src/vsg/app/Viewer.cpp @@ -524,13 +524,10 @@ void Viewer::assignRecordAndSubmitTaskAndPresentation(CommandGraphs in_commandGr Windows activeWindows(findWindows.windows.begin(), findWindows.windows.end()); - auto renderFinishedSemaphore = vsg::Semaphore::create(device); - // set up Submission with CommandBuffer and signals auto recordAndSubmitTask = vsg::RecordAndSubmitTask::create(device, numBuffers); recordAndSubmitTask->commandGraphs = commandGraphs; recordAndSubmitTask->databasePager = databasePager; - recordAndSubmitTask->signalSemaphores.emplace_back(renderFinishedSemaphore); recordAndSubmitTask->windows = activeWindows; recordAndSubmitTask->queue = mainQueue; recordAndSubmitTasks.emplace_back(recordAndSubmitTask); @@ -541,7 +538,6 @@ void Viewer::assignRecordAndSubmitTaskAndPresentation(CommandGraphs in_commandGr if (instrumentation) recordAndSubmitTask->assignInstrumentation(instrumentation); auto presentation = vsg::Presentation::create(); - presentation->waitSemaphores.emplace_back(renderFinishedSemaphore); presentation->windows = activeWindows; presentation->queue = device->getQueue(deviceQueueFamily.presentFamily); presentations.emplace_back(presentation); diff --git a/src/vsg/app/Window.cpp b/src/vsg/app/Window.cpp index 979e6b47e..932236e7e 100644 --- a/src/vsg/app/Window.cpp +++ b/src/vsg/app/Window.cpp @@ -370,8 +370,6 @@ void Window::buildSwapchain() // set up framebuffer and associated resources auto& imageViews = _swapchain->getImageViews(); - _availableSemaphore = vsg::Semaphore::create(_device, _traits->imageAvailableSemaphoreWaitFlag); - size_t initial_indexValue = imageViews.size(); for (size_t i = 0; i < imageViews.size(); ++i) { @@ -391,12 +389,18 @@ void Window::buildSwapchain() ref_ptr fb = Framebuffer::create(_renderPass, attachments, _extent2D.width, _extent2D.height, 1); ref_ptr ias = vsg::Semaphore::create(_device, _traits->imageAvailableSemaphoreWaitFlag); + ref_ptr rfs = vsg::Semaphore::create(_device); - //_frames.push_back({multisampling ? _multisampleImageView : imageViews[i], fb, ias}); - _frames.push_back({imageViews[i], fb, ias}); + _frames.push_back({imageViews[i], fb, ias, rfs}); _indices.push_back(initial_indexValue); } + _availableSemaphoreIndex = 0; + for (size_t i = 0; i < imageViews.size(); ++i) + { + _availableSemaphores.push_back(vsg::Semaphore::create(_device, _traits->imageAvailableSemaphoreWaitFlag)); + } + { // ensure image attachments are setup on GPU. auto commandPool = CommandPool::create(_device, graphicsFamily); @@ -434,18 +438,19 @@ VkResult Window::acquireNextImage(uint64_t timeout) { if (!_swapchain) _initSwapchain(); - if (!_availableSemaphore) _availableSemaphore = vsg::Semaphore::create(_device, _traits->imageAvailableSemaphoreWaitFlag); + auto& availableSemaphore = _availableSemaphores[_availableSemaphoreIndex]; + _availableSemaphoreIndex = (_availableSemaphoreIndex + 1) % _availableSemaphores.size(); // check the dimensions of the swapchain and window extents are consistent, if not return a VK_ERROR_OUT_OF_DATE_KHR if (_swapchain->getExtent() != _extent2D) return VK_ERROR_OUT_OF_DATE_KHR; uint32_t nextImageIndex; - VkResult result = _swapchain->acquireNextImage(timeout, _availableSemaphore, {}, nextImageIndex); + VkResult result = _swapchain->acquireNextImage(timeout, availableSemaphore, {}, nextImageIndex); if (result == VK_SUCCESS) { // 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 - _availableSemaphore.swap(_frames[nextImageIndex].imageAvailableSemaphore); + availableSemaphore.swap(_frames[nextImageIndex].imageAvailableSemaphore); // shift up previous frame indices for (size_t i = _indices.size() - 1; i > 0; --i)