Skip to content

Commit

Permalink
fix bugged semaphore_wait_until_signaled impl
Browse files Browse the repository at this point in the history
change semaphore_wait/signal_info construction for timeline semaphores
  • Loading branch information
MoritzRoth committed Jul 5, 2023
1 parent 3f32679 commit 9c0f0b5
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 49 deletions.
9 changes: 5 additions & 4 deletions include/avk/avk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -975,10 +975,11 @@ namespace avk
#pragma region semaphore
static semaphore create_semaphore(vk::Device aDevice, const DISPATCH_LOADER_CORE_TYPE& aDispatchLoader, std::function<void(semaphore_t&)> aAlterConfigBeforeCreation = {});
semaphore create_semaphore(std::function<void(semaphore_t&)> aAlterConfigBeforeCreation = {});
/** @brief Creates a timeline semaphore
* @param aPayload (optional) The initial value of the payload. Defaults to 0.
* @param aAlterConfigBeforeCreation (optional) Use it to alter the timeline semaphore configuration before it is actually being created.
* @return The created semaphore.
/**
* @brief Creates a timeline semaphore
* @param aPayload (optional) The initial value of the payload. Defaults to 0.
* @param aAlterConfigBeforeCreation (optional) Use it to alter the timeline semaphore configuration before it is actually being created.
* @return The created semaphore.
*/
semaphore create_timeline_semaphore(uint64_t aPayload = 0, std::function<void(semaphore_t&)> aAlterConfigBeforeCreation = {});
#pragma endregion
Expand Down
34 changes: 10 additions & 24 deletions include/avk/commands.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1114,49 +1114,35 @@ namespace avk
avk::resource_argument<avk::semaphore_t> mWaitSemaphore;
avk::stage::pipeline_stage_flags mDstStage;
uint64_t mValue;

semaphore_wait_info& at_value(uint64_t aValue) {
mValue = aValue;
return *this;
}
};

inline semaphore_wait_info operator>> (avk::resource_argument<avk::semaphore_t> a, avk::stage::pipeline_stage_flags b)
{
return semaphore_wait_info{ std::move(a), b, 0 };
}

inline semaphore_wait_info&& operator| (uint64_t aValue, semaphore_wait_info&& aInfo)
{
aInfo.mValue = aValue;
return std::move(aInfo);
}

inline semaphore_wait_info& operator| (uint64_t aValue, semaphore_wait_info& aInfo)
{
aInfo.mValue = aValue;
return aInfo;
}

struct semaphore_signal_info
{
avk::stage::pipeline_stage_flags mSrcStage;
avk::resource_argument<avk::semaphore_t> mSignalSemaphore;
uint64_t mValue;

semaphore_signal_info& to_value(uint64_t aValue) {
mValue = aValue;
return *this;
}
};

inline semaphore_signal_info operator>> (avk::stage::pipeline_stage_flags a, avk::resource_argument<avk::semaphore_t> b)
{
return semaphore_signal_info{ a, std::move(b), 0 };
}

inline semaphore_signal_info&& operator| (semaphore_signal_info&& aInfo, uint64_t aValue)
{
aInfo.mValue = aValue;
return std::move(aInfo);
}

inline semaphore_signal_info& operator| (semaphore_signal_info& aInfo, uint64_t aValue)
{
aInfo.mValue = aValue;
return aInfo;
}


class recorded_command_buffer;

Expand Down
2 changes: 1 addition & 1 deletion include/avk/semaphore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ namespace avk
* @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(const std::vector<const semaphore_t*> &aSemaphores, const std::vector<uint64_t> &aTimestamps, bool aWaitOnAll = true, std::optional<uint64_t> aTimeout = {});
static vk::Result wait_until_signaled(const std::span<std::reference_wrapper<const semaphore_t>> aSemaphores, const std::span<uint64_t> &aTimestamps, bool aWaitOnAll = true, std::optional<uint64_t> aTimeout = {});

/** @brief Waits on host until the condition specified with the parameters is met.
* @param aDevice The logical device owning all referenced timeline semaphores.
Expand Down
36 changes: 16 additions & 20 deletions src/avk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
#endif
#endif

#define _SILENCE_CXX20_CISCO646_REMOVED_WARNING

namespace avk
{
#pragma region root definitions
Expand Down Expand Up @@ -7133,14 +7131,12 @@ namespace avk

semaphore root::create_timeline_semaphore(uint64_t aPayload, std::function<void(semaphore_t&)> aAlterConfigBeforeCreation)
{
return create_semaphore(device(), dispatch_loader_core(), [otherAlterations = move(aAlterConfigBeforeCreation), aPayload](semaphore_t& aSem) {
auto typeInfo = std::make_unique<vk::SemaphoreTypeCreateInfo>();
typeInfo->semaphoreType = vk::SemaphoreType::eTimeline;
typeInfo->initialValue = aPayload;
auto typeInfo = std::make_unique<vk::SemaphoreTypeCreateInfo>();
typeInfo->semaphoreType = vk::SemaphoreType::eTimeline;
typeInfo->initialValue = aPayload;

return create_semaphore(device(), dispatch_loader_core(), [otherAlterations = move(aAlterConfigBeforeCreation), &typeInfo](semaphore_t& aSem) {
aSem.create_info().pNext = typeInfo.get();
aSem.set_custom_deleter([aTypeInfo = move(typeInfo)]() { /* Do nothing ... this lambda just keeps the typeInfo struct alive */ });
// maybe extend any_owning_resource_t and use handle_lifetime_of instead?

if (otherAlterations) {
otherAlterations(aSem);
Expand Down Expand Up @@ -7173,28 +7169,28 @@ namespace avk
}

vk::Result semaphore_t::wait_until_signaled(uint64_t aRequiredValue, std::optional<uint64_t> aTimeout) const {
return wait_until_signaled({ this }, {aRequiredValue} , true, aTimeout); // maybe avoid unnecessary vector construction by just creating SemaphoreWaitInfo in this function
std::vector<std::reference_wrapper<const semaphore_t>> semaphores{ *this };
return wait_until_signaled(semaphores, std::span<uint64_t>(&aRequiredValue, 1), true, aTimeout);
}

vk::Result semaphore_t::wait_until_signaled(const std::vector<const semaphore_t*>& aSemaphores, const std::vector<uint64_t>& aTimestamps, bool aWaitOnAll, std::optional<uint64_t> aTimeout) {
vk::Result semaphore_t::wait_until_signaled(const std::span<std::reference_wrapper<const semaphore_t>> aSemaphores, const std::span<uint64_t>& aTimestamps, bool aWaitOnAll, std::optional<uint64_t> aTimeout) {
assert(aSemaphores.size() == aTimestamps.size());
if (aSemaphores.size() == 0) {
return vk::Result::eSuccess;
}

std::vector<const vk::Semaphore*> semaphores;
std::transform(aSemaphores.begin(), aSemaphores.end(), std::back_inserter(semaphores), [](const semaphore_t* s) {return &s->mSemaphore.get(); });
std::vector<vk::Semaphore> semaphores;
std::transform(aSemaphores.begin(), aSemaphores.end(), std::back_inserter(semaphores), [](const semaphore_t& s) {return s.mSemaphore.get(); });

vk::SemaphoreWaitInfo info{};
info.sType = vk::StructureType::eSemaphoreWaitInfo;
info.pNext = NULL;
info.flags = aWaitOnAll ? vk::SemaphoreWaitFlags() : vk::SemaphoreWaitFlagBits::eAny;
info.semaphoreCount = uint32_t(semaphores.size());
info.pSemaphores = *(semaphores.data());
info.pValues = aTimestamps.data();
vk::SemaphoreWaitInfo info{
aWaitOnAll ? vk::SemaphoreWaitFlags() : vk::SemaphoreWaitFlagBits::eAny,
static_cast<uint32_t>(semaphores.size()),
semaphores.data(),
aTimestamps.data()
};

// assume all semapores use the same device
return wait_until_signaled(aSemaphores.front()->mSemaphore.getOwner(), info, aTimeout);
return wait_until_signaled(aSemaphores.front().get().mSemaphore.getOwner(), info, aTimeout);
}

vk::Result semaphore_t::wait_until_signaled(const vk::Device& aDevice, const vk::SemaphoreWaitInfo& aInfo, std::optional<uint64_t> aTimeout) {
Expand Down

0 comments on commit 9c0f0b5

Please sign in to comment.