Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 20 additions & 16 deletions layers/state_tracker/submit_time_tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,6 @@ bool SubmitTimeTracker::ProcessBatch(std::vector<std::shared_ptr<CommandBuffer>>

bool SubmitTimeTracker::ProcessSignal(VkSemaphore timeline, uint64_t signal_value) {
bool skip = false;
auto semaphore = validator_.Get<Semaphore>(timeline);
if (!semaphore || semaphore->type != VK_SEMAPHORE_TYPE_TIMELINE) {
return skip;
}
const bool new_timeline_signal = UpdateTimelineValue(timeline, signal_value);
if (new_timeline_signal) {
skip |= PropagateTimelineSignals();
Expand All @@ -126,14 +122,12 @@ std::vector<VkSemaphoreSubmitInfo> SubmitTimeTracker::GetUnresolvedTimelineWaits
vvl::span<const VkSemaphoreSubmitInfo> wait_semaphores) {
std::vector<VkSemaphoreSubmitInfo> unresolved;
for (const auto& wait : wait_semaphores) {
auto semaphore = validator_.Get<Semaphore>(wait.semaphore);
if (!semaphore || semaphore->type != VK_SEMAPHORE_TYPE_TIMELINE || semaphore->Scope() != Semaphore::kInternal) {
// Only timeline semaphores can introduce pending waits.
// For external semaphores we cannot reliably track signals
const std::optional<uint64_t> current_value = GetTimelineValue(wait.semaphore);
if (!current_value.has_value()) {
// Invalid or external semaphores should not block this batch
continue;
}
const uint64_t current_value = GetTimelineValue(wait.semaphore);
if (wait.value > current_value) {
if (wait.value > *current_value) {
unresolved.emplace_back(wait);
}
}
Expand All @@ -143,10 +137,6 @@ std::vector<VkSemaphoreSubmitInfo> SubmitTimeTracker::GetUnresolvedTimelineWaits
bool SubmitTimeTracker::RegisterTimelineSignals(vvl::span<const VkSemaphoreSubmitInfo> signal_semaphores) {
bool new_timeline_signals = false;
for (const VkSemaphoreSubmitInfo& signal : signal_semaphores) {
auto semaphore = validator_.Get<Semaphore>(signal.semaphore);
if (!semaphore || semaphore->type != VK_SEMAPHORE_TYPE_TIMELINE) {
continue;
}
new_timeline_signals |= UpdateTimelineValue(signal.semaphore, signal.value);
}
return new_timeline_signals;
Expand Down Expand Up @@ -180,20 +170,34 @@ bool SubmitTimeTracker::PropagateTimelineSignals() {

bool SubmitTimeTracker::CanBeResolved(const UnresolvedBatch& batch) const {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so even if ALL unresolved_timeline_waits are invalid (GetTimelineValue returns null) we will still return true here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's the intention.
a) it means there are other error reported elsewhere (like semaphore delete while still in use).
b) then we allow to resolve batch (remove from list) otherwise the queue will grow forever beause of blocking batch.

for (const VkSemaphoreSubmitInfo& wait : batch.unresolved_timeline_waits) {
const uint64_t current_value = GetTimelineValue(wait.semaphore);
const std::optional<uint64_t> current_value = GetTimelineValue(wait.semaphore);
if (!current_value.has_value()) {
// Invalid or external semaphores should not block this batch
continue;
}
if (wait.value > current_value) {
return false;
}
}
return true;
}

uint64_t SubmitTimeTracker::GetTimelineValue(VkSemaphore timeline) const {
std::optional<uint64_t> SubmitTimeTracker::GetTimelineValue(VkSemaphore timeline) const {
auto semaphore_state = validator_.Get<Semaphore>(timeline);
if (!semaphore_state || semaphore_state->type != VK_SEMAPHORE_TYPE_TIMELINE ||
semaphore_state->Scope() != Semaphore::kInternal) {
// Used by the caller to detect invalid/non-timeline/external semaphores
return {};
}
const uint64_t current_value = vvl::FindExisting(timeline_signals_, timeline);
return current_value;
}

bool SubmitTimeTracker::UpdateTimelineValue(VkSemaphore timeline, uint64_t signal_value) {
auto semaphore_state = validator_.Get<Semaphore>(timeline);
if (!semaphore_state || semaphore_state->type != VK_SEMAPHORE_TYPE_TIMELINE) {
return false;
}
uint64_t& current_value = vvl::FindExisting(timeline_signals_, timeline);
if (signal_value <= current_value) {
return false; // non-increasing signal, the error should be reported elsewhere
Expand Down
5 changes: 3 additions & 2 deletions layers/state_tracker/submit_time_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <vulkan/vulkan.h>
#include <memory>
#include <mutex>
#include <optional>
#include <vector>

namespace vvl {
Expand Down Expand Up @@ -64,7 +65,7 @@ class SubmitTimeTracker {
bool ProcessPresent(const VkPresentInfoKHR& present_info, const Location& present_info_loc) const;

private:
bool ProcessBatch(std::vector<std::shared_ptr<vvl::CommandBuffer>>&& command_buffers,
bool ProcessBatch(std::vector<std::shared_ptr<CommandBuffer>>&& command_buffers,
vvl::span<const VkSemaphoreSubmitInfo> wait_semaphores,
vvl::span<const VkSemaphoreSubmitInfo> signal_semaphores, VkQueue queue, const Location& submit_loc);
bool ProcessSignal(VkSemaphore timeline, uint64_t signal_value);
Expand All @@ -73,7 +74,7 @@ class SubmitTimeTracker {
bool RegisterTimelineSignals(vvl::span<const VkSemaphoreSubmitInfo> signal_semaphores);
bool PropagateTimelineSignals();
bool CanBeResolved(const UnresolvedBatch& batch) const;
uint64_t GetTimelineValue(VkSemaphore timeline) const;
std::optional<uint64_t> GetTimelineValue(VkSemaphore timeline) const;
bool UpdateTimelineValue(VkSemaphore timeline, uint64_t signal_value);

private:
Expand Down
Loading