diff --git a/include/vsg/app/RecordAndSubmitTask.h b/include/vsg/app/RecordAndSubmitTask.h index abb419d88..c8b2c5a4b 100644 --- a/include/vsg/app/RecordAndSubmitTask.h +++ b/include/vsg/app/RecordAndSubmitTask.h @@ -37,10 +37,14 @@ namespace vsg ref_ptr device; Windows windows; Semaphores waitSemaphores; - CommandGraphs commandGraphs; // assign in application setup - Semaphores signalSemaphores; // connect to Presentation.waitSemaphores + CommandGraphs commandGraphs; // assign in application setup + Semaphores signalSemaphores; // connect to Presentation.waitSemaphores + ref_ptr earlyTransferTask; // data is updated prior to record traversal so can be transferred before/in parallel to record traversal - ref_ptr lateTransferTask; // data is updated during the record traversal so has to be transferred after record traversal + ref_ptr earlyTransferTaskConsumerCompletedSemaphore; + + ref_ptr lateTransferTask; // data is updated during the record traversal so has to be transferred after record traversal + ref_ptr lateTransferTaskConsumerCompletedSemaphore; /// advance the currentFrameIndex void advance(); diff --git a/include/vsg/app/TransferTask.h b/include/vsg/app/TransferTask.h index f9aa3b5df..7ff1637b4 100644 --- a/include/vsg/app/TransferTask.h +++ b/include/vsg/app/TransferTask.h @@ -42,12 +42,6 @@ namespace vsg /// advance the currentFrameIndex void advance(); - /// return the fence index value for relativeFrameIndex where 0 is current frame, 1 is previous frame etc. - size_t index(size_t relativeFrameIndex = 0) const; - - /// fence() and fence(0) return the Fence for the frame currently being rendered, fence(1) returns the previous frame's Fence etc. - Fence* fence(size_t relativeFrameIndex = 0); - void assign(const ResourceRequirements::DynamicData& dynamicData); void assign(const BufferInfoList& bufferInfoList); void assign(const ImageInfoList& imageInfoList); @@ -59,6 +53,8 @@ namespace vsg using OffsetBufferInfoMap = std::map>; using BufferMap = std::map, OffsetBufferInfoMap>; + size_t index(size_t relativeFrameIndex = 0) const; + VkDeviceSize _dynamicDataTotalRegions = 0; VkDeviceSize _dynamicDataTotalSize = 0; VkDeviceSize _dynamicImageTotalSize = 0; @@ -70,7 +66,6 @@ namespace vsg struct Frame { - ref_ptr fence; ref_ptr transferCommandBuffer; ref_ptr transferCompleteSemaphore; ref_ptr staging; diff --git a/include/vsg/io/AsciiOutput.h b/include/vsg/io/AsciiOutput.h index 0a259a75a..ddb146724 100644 --- a/include/vsg/io/AsciiOutput.h +++ b/include/vsg/io/AsciiOutput.h @@ -12,9 +12,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI */ +#include #include #include -#include #include #include @@ -126,8 +126,16 @@ namespace vsg void write(size_t num, const uint32_t* value) override { _write(num, value); } void write(size_t num, const int64_t* value) override { _write(num, value); } void write(size_t num, const uint64_t* value) override { _write(num, value); } - void write(size_t num, const float* value) override { _output.precision(float_precision); _write_real(num, value); } - void write(size_t num, const double* value) override { _output.precision(double_precision); _write_real(num, value); } + void write(size_t num, const float* value) override + { + _output.precision(float_precision); + _write_real(num, value); + } + void write(size_t num, const double* value) override + { + _output.precision(double_precision); + _write_real(num, value); + } void _write(const std::string& str) { diff --git a/include/vsg/text/Font.h b/include/vsg/text/Font.h index ff3f07480..eb02ca11b 100644 --- a/include/vsg/text/Font.h +++ b/include/vsg/text/Font.h @@ -46,6 +46,7 @@ namespace vsg return 0; } void createFontImages(); + protected: }; VSG_type_name(vsg::Font); diff --git a/include/vsg/vk/State.h b/include/vsg/vk/State.h index dad92ba02..a286722ab 100644 --- a/include/vsg/vk/State.h +++ b/include/vsg/vk/State.h @@ -302,8 +302,10 @@ namespace vsg inline void pushFrustum() { _frustumStack.push(Frustum(_frustumProjected, modelviewMatrixStack.top())); - if (inheritViewForLODScaling) _frustumStack.top().computeLodScale(inheritedProjectionMatrix, inheritedViewTransform * modelviewMatrixStack.top()); - else _frustumStack.top().computeLodScale(projectionMatrixStack.top(), modelviewMatrixStack.top()); + if (inheritViewForLODScaling) + _frustumStack.top().computeLodScale(inheritedProjectionMatrix, inheritedViewTransform * modelviewMatrixStack.top()); + else + _frustumStack.top().computeLodScale(projectionMatrixStack.top(), modelviewMatrixStack.top()); } inline void applyFrustum() diff --git a/src/vsg/app/RecordAndSubmitTask.cpp b/src/vsg/app/RecordAndSubmitTask.cpp index 039aaabbd..404188ae7 100644 --- a/src/vsg/app/RecordAndSubmitTask.cpp +++ b/src/vsg/app/RecordAndSubmitTask.cpp @@ -30,11 +30,14 @@ RecordAndSubmitTask::RecordAndSubmitTask(Device* in_device, uint32_t numBuffers) _fences.resize(numBuffers); for (uint32_t i = 0; i < numBuffers; ++i) { - _fences[i] = vsg::Fence::create(device); + _fences[i] = Fence::create(device); } - earlyTransferTask = vsg::TransferTask::create(in_device, numBuffers); - lateTransferTask = vsg::TransferTask::create(in_device, numBuffers); + earlyTransferTask = TransferTask::create(in_device, numBuffers); + earlyTransferTaskConsumerCompletedSemaphore = Semaphore::create(in_device); + + lateTransferTask = TransferTask::create(in_device, numBuffers); + lateTransferTaskConsumerCompletedSemaphore = Semaphore::create(in_device); } void RecordAndSubmitTask::advance() @@ -77,8 +80,6 @@ Fence* RecordAndSubmitTask::fence(size_t relativeFrameIndex) VkResult RecordAndSubmitTask::submit(ref_ptr frameStamp) { - auto recordedCommandBuffers = RecordedCommandBuffers::create(); - if (VkResult result = start(); result != VK_SUCCESS) return result; if (earlyTransferTask) @@ -86,6 +87,8 @@ VkResult RecordAndSubmitTask::submit(ref_ptr frameStamp) if (VkResult result = earlyTransferTask->transferDynamicData(); result != VK_SUCCESS) return result; } + auto recordedCommandBuffers = RecordedCommandBuffers::create(); + if (VkResult result = record(recordedCommandBuffers, frameStamp); result != VK_SUCCESS) return result; return finish(recordedCommandBuffers); @@ -154,12 +157,18 @@ VkResult RecordAndSubmitTask::finish(ref_ptr recordedCom { vk_waitSemaphores.emplace_back(*earlyTransferTask->currentTransferCompletedSemaphore); vk_waitStages.emplace_back(earlyTransferTask->currentTransferCompletedSemaphore->pipelineStageFlags()); + + earlyTransferTask->waitSemaphores.push_back(earlyTransferTaskConsumerCompletedSemaphore); + vk_signalSemaphores.emplace_back(*earlyTransferTaskConsumerCompletedSemaphore); } if (lateTransferTask && lateTransferTask->currentTransferCompletedSemaphore) { vk_waitSemaphores.emplace_back(*lateTransferTask->currentTransferCompletedSemaphore); vk_waitStages.emplace_back(lateTransferTask->currentTransferCompletedSemaphore->pipelineStageFlags()); + + lateTransferTask->waitSemaphores.push_back(lateTransferTaskConsumerCompletedSemaphore); + vk_signalSemaphores.emplace_back(*lateTransferTaskConsumerCompletedSemaphore); } for (auto& window : windows) @@ -234,7 +243,7 @@ void vsg::updateTasks(RecordAndSubmitTasks& tasks, ref_ptr compi // assign database pager if required if (compileResult.containsPagedLOD) { - vsg::ref_ptr databasePager; + ref_ptr databasePager; for (auto& task : tasks) { if (task->databasePager && !databasePager) databasePager = task->databasePager; @@ -242,7 +251,7 @@ void vsg::updateTasks(RecordAndSubmitTasks& tasks, ref_ptr compi if (!databasePager) { - databasePager = vsg::DatabasePager::create(); + databasePager = DatabasePager::create(); for (auto& task : tasks) { if (!task->databasePager) @@ -259,7 +268,7 @@ void vsg::updateTasks(RecordAndSubmitTasks& tasks, ref_ptr compi /// handle any new Bin needs for (auto& [const_view, binDetails] : compileResult.views) { - auto view = const_cast(const_view); + auto view = const_cast(const_view); for (auto& binNumber : binDetails.indices) { bool binNumberMatched = false; @@ -272,8 +281,8 @@ void vsg::updateTasks(RecordAndSubmitTasks& tasks, ref_ptr compi } if (!binNumberMatched) { - vsg::Bin::SortOrder sortOrder = (binNumber < 0) ? vsg::Bin::ASCENDING : ((binNumber == 0) ? vsg::Bin::NO_SORT : vsg::Bin::DESCENDING); - view->bins.push_back(vsg::Bin::create(binNumber, sortOrder)); + Bin::SortOrder sortOrder = (binNumber < 0) ? Bin::ASCENDING : ((binNumber == 0) ? Bin::NO_SORT : Bin::DESCENDING); + view->bins.push_back(Bin::create(binNumber, sortOrder)); } } } diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index a48544d07..d2b57af52 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -370,7 +370,6 @@ void RecordTraversal::apply(const Command& command) command.record(*(_state->_commandBuffer)); } - void RecordTraversal::apply(const View& view) { // note, View::accept() updates the RecordTraversal's traversalMask diff --git a/src/vsg/app/TransferTask.cpp b/src/vsg/app/TransferTask.cpp index 434889f9a..78ec3b0a4 100644 --- a/src/vsg/app/TransferTask.cpp +++ b/src/vsg/app/TransferTask.cpp @@ -28,10 +28,6 @@ TransferTask::TransferTask(Device* in_device, uint32_t numBuffers) : } _frames.resize(numBuffers); - for (uint32_t i = 0; i < numBuffers; ++i) - { - _frames[i].fence = vsg::Fence::create(device); - } } void TransferTask::advance() @@ -62,13 +58,6 @@ size_t TransferTask::index(size_t relativeFrameIndex) const return relativeFrameIndex < _indices.size() ? _indices[relativeFrameIndex] : _indices.size(); } -/// fence() and fence(0) return the Fence for the frame currently being rendered, fence(1) returns the previous frame's Fence etc. -Fence* TransferTask::fence(size_t relativeFrameIndex) -{ - size_t i = index(relativeFrameIndex); - return i < _frames.size() ? _frames[i].fence.get() : nullptr; -} - bool TransferTask::containsDataToTransfer() const { return !_dynamicDataMap.empty() || !_dynamicImageInfoSet.empty(); @@ -360,6 +349,7 @@ VkResult TransferTask::transferDynamicData() if (!semaphore) { + // signal transfer submission has completed semaphore = Semaphore::create(device, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); } @@ -402,18 +392,47 @@ VkResult TransferTask::transferDynamicData() VkSubmitInfo submitInfo = {}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.waitSemaphoreCount = 0; - submitInfo.pWaitSemaphores = nullptr; - submitInfo.pWaitDstStageMask = nullptr; + // set up the vulkan wait sempahore + std::vector vk_waitSemaphores; + std::vector vk_waitStages; + if (waitSemaphores.empty()) + { + submitInfo.waitSemaphoreCount = 0; + submitInfo.pWaitSemaphores = nullptr; + submitInfo.pWaitDstStageMask = nullptr; + // info("TransferTask::transferDynamicData() ", this, ", _currentFrameIndex = ", _currentFrameIndex); + } + else + { + for (auto& waitSemaphore : waitSemaphores) + { + vk_waitSemaphores.emplace_back(*(waitSemaphore)); + vk_waitStages.emplace_back(waitSemaphore->pipelineStageFlags()); + } + + submitInfo.waitSemaphoreCount = static_cast(vk_waitSemaphores.size()); + submitInfo.pWaitSemaphores = vk_waitSemaphores.data(); + submitInfo.pWaitDstStageMask = vk_waitStages.data(); + } + + // set up the vulkan signal sempahore + std::vector vk_signalSemaphores; + vk_signalSemaphores.push_back(*semaphore); + for (auto& ss : signalSemaphores) + { + vk_signalSemaphores.push_back(*ss); + } + + submitInfo.signalSemaphoreCount = static_cast(vk_signalSemaphores.size()); + submitInfo.pSignalSemaphores = vk_signalSemaphores.data(); submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &vk_commandBuffer; - submitInfo.signalSemaphoreCount = 1; - VkSemaphore vk_transferCompletedSemaphore = *semaphore; - submitInfo.pSignalSemaphores = &vk_transferCompletedSemaphore; - result = transferQueue->submit(submitInfo); + + waitSemaphores.clear(); + if (result != VK_SUCCESS) return result; currentTransferCompletedSemaphore = semaphore; @@ -421,6 +440,8 @@ VkResult TransferTask::transferDynamicData() else { log(level, "Nothing to submit"); + + waitSemaphores.clear(); } return VK_SUCCESS;