diff --git a/include/avk/avk.hpp b/include/avk/avk.hpp index 4e207aa..8cfa0f1 100644 --- a/include/avk/avk.hpp +++ b/include/avk/avk.hpp @@ -983,6 +983,15 @@ namespace avk * @return The created semaphore. */ semaphore create_timeline_semaphore(uint64_t aPayload = 0, std::function aAlterConfigBeforeCreation = {}); + + /** + * @brief Waits on host until the condition specified with the parameters is met. + * @param aSemaphoreValueInfos Span of semaphore_value_info structs, each containing a semaphore and a payload value to wait on. All semaphores are required to be owned by the same logical device. + * @param aWaitOnAll (optional) If true, waits until ALL semaphores have reached their target timestamps. If false, waits until ANY semaphore has reached its target timestamp. + * @param aTimeout (optional) Defines a timeout (in nanoseconds) after which the function returns regardless of the semaphore state. + * @return Value of type vk::Result containing information about whether the wait operation succeeded, or the timeout has been triggered. + */ + static vk::Result wait_until_signaled(std::span aSemaphoreValueInfos, bool aWaitOnAll = true, std::optional aTimeout = {}); #pragma endregion #pragma region shader diff --git a/include/avk/semaphore.hpp b/include/avk/semaphore.hpp index f000dc3..c52aa95 100644 --- a/include/avk/semaphore.hpp +++ b/include/avk/semaphore.hpp @@ -61,22 +61,6 @@ namespace avk */ void wait_until_signaled(uint64_t aSignalValue, std::optional aTimeout = {}) const; - ///** @brief Waits on host until the condition specified with the parameters is met. - //* @param aSemaphores Vector of timeline semaphores that should be waited on. All semaphores are required to be owned by the same logical device. - //* @param aTimestamps Vector of payload values to wait on. Is required to have the same size as aSemaphores. The n-th value in aTimestamps corresponds to the n-th entry in aSemaphores. - //* @param aWaitOnAll (optional) If true, waits until ALL semaphores have reached their target timestamps. If false, waits until ANY semaphore has reached its target timestamp. - //* @param aTimeout (optional) Defines a timeout (in nanoseconds) after which the function returns regardless of the semaphore state. - //* @return Value of type vk::Result containing information about whether the wait operation succeeded, or the timeout has been triggered. - //*/ - //static vk::Result wait_until_signaled(std::span aSignalInfos, bool aWaitOnAll, std::optional aTimeout, bool aWaitOnAll = true, std::optional aTimeout = {}); - - /** @brief Waits on host until the condition specified with the parameters is met. - * @param aInfo Struct containing all relevant information about the wait operation. - * @param aTimeout (optional) Defines a timeout (in nanoseconds) after which the function returns regardless of the semaphore state. - * @return Value of type vk::Result containing information about whether the wait operation succeeded, or the timeout has been triggered. - */ - void wait_until_signaled(const vk::SemaphoreWaitInfo& aInfo, std::optional aTimeout = {}) const; - private: // The semaphore config struct: vk::SemaphoreCreateInfo mCreateInfo; diff --git a/src/avk.cpp b/src/avk.cpp index 29cd9ce..c8de163 100644 --- a/src/avk.cpp +++ b/src/avk.cpp @@ -7144,6 +7144,30 @@ namespace avk }); } + vk::Result root::wait_until_signaled(std::span aSemaphoreValueInfos, bool aWaitOnAll, std::optional aTimeout) { + if (aSemaphoreValueInfos.empty()) { + return vk::Result::eSuccess; + } + + const vk::Device& device = aSemaphoreValueInfos.front().mSignalSemaphore->mSemaphore.getOwner(); + std::vector semHandles; + std::vector timestampValues; + for (const auto& svi : aSemaphoreValueInfos) { + assert(device == svi.mSignalSemaphore->mSemaphore.getOwner()); + semHandles.push_back(svi.mSignalSemaphore->handle()); + timestampValues.push_back(svi.mValue); + } + + vk::SemaphoreWaitInfo info( + aWaitOnAll ? vk::SemaphoreWaitFlags{} : vk::SemaphoreWaitFlagBits::eAny, + static_cast(semHandles.size()), + semHandles.data(), + timestampValues.data() + ); + + return device.waitSemaphores(info, aTimeout.value_or(UINT64_MAX)); + } + semaphore_t& semaphore_t::handle_lifetime_of(any_owning_resource_t aResource) { mLifetimeHandledResources.push_back(std::move(aResource)); @@ -7171,34 +7195,7 @@ namespace avk handle_addr(), &aSignalValue }; - wait_until_signaled(info, aTimeout); - } - - //vk::Result semaphore_t::wait_until_signaled(std::span aSignalInfos, bool aWaitOnAll, std::optional aTimeout) { - // if (aSemaphores.size() == 0) { - // return vk::Result::eSuccess; - // } - - // std::vector semHandles; - // std::vector timestampValues; - // for (const auto& ssi : aSignalInfos) { - // semHandles.push_back(ssi.mSignalSemaphore->handle()); - // timestampValues.push_back(ssi.mValue); - // } - - // vk::SemaphoreWaitInfo info{ - // aWaitOnAll ? vk::SemaphoreWaitFlags{} : vk::SemaphoreWaitFlagBits::eAny, - // static_cast(semHandles.size()), - // semHandles.data(), - // timestampValues.data() - // }; - - // // assume all semapores use the same device - // return wait_until_signaled(aSemaphores.front().get().mSemaphore.getOwner(), info, aTimeout); - //} - - void semaphore_t::wait_until_signaled(const vk::SemaphoreWaitInfo& aInfo, std::optional aTimeout) const { - mSemaphore.getOwner().waitSemaphores(aInfo, aTimeout.value_or(UINT64_MAX)); + mSemaphore.getOwner().waitSemaphores(info, aTimeout.value_or(UINT64_MAX)); } #pragma endregion