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.
This commit is contained in:
ReinUsesLisp 2019-02-14 13:06:05 -03:00
parent 25c2fe1c6b
commit aa0b6babda
2 changed files with 68 additions and 0 deletions

View File

@ -3,6 +3,7 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <algorithm> #include <algorithm>
#include "common/assert.h"
#include "video_core/renderer_vulkan/declarations.h" #include "video_core/renderer_vulkan/declarations.h"
#include "video_core/renderer_vulkan/vk_device.h" #include "video_core/renderer_vulkan/vk_device.h"
#include "video_core/renderer_vulkan/vk_resource_manager.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 } // namespace Vulkan

View File

@ -86,4 +86,34 @@ private:
bool is_used = false; ///< The fence has been commited but it has not been checked to be free. 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 } // namespace Vulkan