From aa0b6babdad588d176fc67784f9905709845aa07 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 14 Feb 2019 13:06:05 -0300 Subject: [PATCH] vk_resource_manager: Implement VKFenceWatch A fence watch is used to keep track of the usage of a fence and protect a resource or set of resources without having to inherit from their handlers. --- .../renderer_vulkan/vk_resource_manager.cpp | 38 +++++++++++++++++++ .../renderer_vulkan/vk_resource_manager.h | 30 +++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/src/video_core/renderer_vulkan/vk_resource_manager.cpp b/src/video_core/renderer_vulkan/vk_resource_manager.cpp index 1875bcf54..2e9c6ef34 100644 --- a/src/video_core/renderer_vulkan/vk_resource_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_resource_manager.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/assert.h" #include "video_core/renderer_vulkan/declarations.h" #include "video_core/renderer_vulkan/vk_device.h" #include "video_core/renderer_vulkan/vk_resource_manager.h" @@ -79,4 +80,41 @@ void VKFence::Unprotect(const VKResource* resource) { } } +VKFenceWatch::VKFenceWatch() = default; + +VKFenceWatch::~VKFenceWatch() { + if (fence) { + fence->Unprotect(this); + } +} + +void VKFenceWatch::Wait() { + if (!fence) { + return; + } + fence->Wait(); + fence->Unprotect(this); + fence = nullptr; +} + +void VKFenceWatch::Watch(VKFence& new_fence) { + Wait(); + fence = &new_fence; + fence->Protect(this); +} + +bool VKFenceWatch::TryWatch(VKFence& new_fence) { + if (fence) { + return false; + } + fence = &new_fence; + fence->Protect(this); + return true; +} + +void VKFenceWatch::OnFenceRemoval(VKFence* signaling_fence) { + ASSERT_MSG(signaling_fence == fence, "Removing the wrong fence"); + fence = nullptr; +} + } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_resource_manager.h b/src/video_core/renderer_vulkan/vk_resource_manager.h index aa52007c8..5345ba46e 100644 --- a/src/video_core/renderer_vulkan/vk_resource_manager.h +++ b/src/video_core/renderer_vulkan/vk_resource_manager.h @@ -86,4 +86,34 @@ private: bool is_used = false; ///< The fence has been commited but it has not been checked to be free. }; +/** + * A fence watch is used to keep track of the usage of a fence and protect a resource or set of + * resources without having to inherit VKResource from their handlers. + */ +class VKFenceWatch final : public VKResource { +public: + explicit VKFenceWatch(); + ~VKFenceWatch(); + + /// Waits for the fence to be released. + void Wait(); + + /** + * Waits for a previous fence and watches a new one. + * @param new_fence New fence to wait to. + */ + void Watch(VKFence& new_fence); + + /** + * Checks if it's currently being watched and starts watching it if it's available. + * @returns True if a watch has started, false if it's being watched. + */ + bool TryWatch(VKFence& new_fence); + + void OnFenceRemoval(VKFence* signaling_fence) override; + +private: + VKFence* fence{}; ///< Fence watching this resource. nullptr when the watch is free. +}; + } // namespace Vulkan