Threaded Queue submit with events and fences This cl does 3 main things: - It pushes the queue submit operation to its own thread - It implements events - It implements fences Some details: - Because we can have N async draw operations and we need to signal the fence only after all operations are completed, fences have a add/done mechanism to allow signaling the fence only when all draw operations are completed. - Device::waitForFences() detects large timeouts to avoid integer overflow if now+timeout is bigger than the remaining nanoseconds available in a long long. Bug b/117835459 Change-Id: I2f02c3b4bb9d9ac9037909b02b0601e1bae15d21 Tests: dEQP-VK.synchronization.* Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/29769 Presubmit-Ready: Alexis Hétu <sugoi@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Reviewed-by: Nicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Tested-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Vulkan/VkEvent.hpp b/src/Vulkan/VkEvent.hpp index 4735564..d56da28 100644 --- a/src/Vulkan/VkEvent.hpp +++ b/src/Vulkan/VkEvent.hpp
@@ -16,6 +16,8 @@ #define VK_EVENT_HPP_ #include "VkObject.hpp" +#include <condition_variable> +#include <mutex> namespace vk { @@ -34,37 +36,38 @@ return 0; } - bool signal() + void signal() { + std::unique_lock<std::mutex> lock(mutex); status = VK_EVENT_SET; - bool wasWaiting = waiting; - waiting = false; - return wasWaiting; + lock.unlock(); + condition.notify_all(); } void reset() { + std::unique_lock<std::mutex> lock(mutex); status = VK_EVENT_RESET; } - VkResult getStatus() const + VkResult getStatus() { - return status; + std::unique_lock<std::mutex> lock(mutex); + auto result = status; + lock.unlock(); + return result; } - bool wait() + void wait() { - if(status != VK_EVENT_SET) - { - waiting = true; - } - - return waiting; + std::unique_lock<std::mutex> lock(mutex); + condition.wait(lock, [this] { return status == VK_EVENT_SET; }); } private: - VkResult status = VK_EVENT_RESET; - bool waiting = false; + VkResult status = VK_EVENT_RESET; // guarded by mutex + std::mutex mutex; + std::condition_variable condition; }; static inline Event* Cast(VkEvent object)