summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_vulkan/vk_resource_manager.cpp68
-rw-r--r--src/video_core/renderer_vulkan/vk_resource_manager.h63
2 files changed, 131 insertions, 0 deletions
diff --git a/src/video_core/renderer_vulkan/vk_resource_manager.cpp b/src/video_core/renderer_vulkan/vk_resource_manager.cpp
index 46563748e..1875bcf54 100644
--- a/src/video_core/renderer_vulkan/vk_resource_manager.cpp
+++ b/src/video_core/renderer_vulkan/vk_resource_manager.cpp
@@ -2,7 +2,9 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
5#include "video_core/renderer_vulkan/declarations.h" 6#include "video_core/renderer_vulkan/declarations.h"
7#include "video_core/renderer_vulkan/vk_device.h"
6#include "video_core/renderer_vulkan/vk_resource_manager.h" 8#include "video_core/renderer_vulkan/vk_resource_manager.h"
7 9
8namespace Vulkan { 10namespace Vulkan {
@@ -11,4 +13,70 @@ VKResource::VKResource() = default;
11 13
12VKResource::~VKResource() = default; 14VKResource::~VKResource() = default;
13 15
16VKFence::VKFence(const VKDevice& device, UniqueFence handle)
17 : device{device}, handle{std::move(handle)} {}
18
19VKFence::~VKFence() = default;
20
21void VKFence::Wait() {
22 const auto dev = device.GetLogical();
23 const auto& dld = device.GetDispatchLoader();
24 dev.waitForFences({*handle}, true, std::numeric_limits<u64>::max(), dld);
25}
26
27void VKFence::Release() {
28 is_owned = false;
29}
30
31void VKFence::Commit() {
32 is_owned = true;
33 is_used = true;
34}
35
36bool VKFence::Tick(bool gpu_wait, bool owner_wait) {
37 if (!is_used) {
38 // If a fence is not used it's always free.
39 return true;
40 }
41 if (is_owned && !owner_wait) {
42 // The fence is still being owned (Release has not been called) and ownership wait has
43 // not been asked.
44 return false;
45 }
46
47 const auto dev = device.GetLogical();
48 const auto& dld = device.GetDispatchLoader();
49 if (gpu_wait) {
50 // Wait for the fence if it has been requested.
51 dev.waitForFences({*handle}, true, std::numeric_limits<u64>::max(), dld);
52 } else {
53 if (dev.getFenceStatus(*handle, dld) != vk::Result::eSuccess) {
54 // Vulkan fence is not ready, not much it can do here
55 return false;
56 }
57 }
58
59 // Broadcast resources their free state.
60 for (auto* resource : protected_resources) {
61 resource->OnFenceRemoval(this);
62 }
63 protected_resources.clear();
64
65 // Prepare fence for reusage.
66 dev.resetFences({*handle}, dld);
67 is_used = false;
68 return true;
69}
70
71void VKFence::Protect(VKResource* resource) {
72 protected_resources.push_back(resource);
73}
74
75void VKFence::Unprotect(const VKResource* resource) {
76 const auto it = std::find(protected_resources.begin(), protected_resources.end(), resource);
77 if (it != protected_resources.end()) {
78 protected_resources.erase(it);
79 }
80}
81
14} // namespace Vulkan 82} // 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 21a53abcd..aa52007c8 100644
--- a/src/video_core/renderer_vulkan/vk_resource_manager.h
+++ b/src/video_core/renderer_vulkan/vk_resource_manager.h
@@ -4,11 +4,14 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <vector>
7#include "video_core/renderer_vulkan/declarations.h" 8#include "video_core/renderer_vulkan/declarations.h"
8 9
9namespace Vulkan { 10namespace Vulkan {
10 11
12class VKDevice;
11class VKFence; 13class VKFence;
14class VKResourceManager;
12 15
13/// Interface for a Vulkan resource 16/// Interface for a Vulkan resource
14class VKResource { 17class VKResource {
@@ -23,4 +26,64 @@ public:
23 virtual void OnFenceRemoval(VKFence* signaling_fence) = 0; 26 virtual void OnFenceRemoval(VKFence* signaling_fence) = 0;
24}; 27};
25 28
29/**
30 * Fences take ownership of objects, protecting them from GPU-side or driver-side concurrent access.
31 * They must be commited from the resource manager. Their usage flow is: commit the fence from the
32 * resource manager, protect resources with it and use them, send the fence to an execution queue
33 * and Wait for it if needed and then call Release. Used resources will automatically be signaled
34 * when they are free to be reused.
35 * @brief Protects resources for concurrent usage and signals its release.
36 */
37class VKFence {
38 friend class VKResourceManager;
39
40public:
41 explicit VKFence(const VKDevice& device, UniqueFence handle);
42 ~VKFence();
43
44 /**
45 * Waits for the fence to be signaled.
46 * @warning You must have ownership of the fence and it has to be previously sent to a queue to
47 * call this function.
48 */
49 void Wait();
50
51 /**
52 * Releases ownership of the fence. Pass after it has been sent to an execution queue.
53 * Unmanaged usage of the fence after the call will result in undefined behavior because it may
54 * be being used for something else.
55 */
56 void Release();
57
58 /// Protects a resource with this fence.
59 void Protect(VKResource* resource);
60
61 /// Removes protection for a resource.
62 void Unprotect(const VKResource* resource);
63
64 /// Retreives the fence.
65 operator vk::Fence() const {
66 return *handle;
67 }
68
69private:
70 /// Take ownership of the fence.
71 void Commit();
72
73 /**
74 * Updates the fence status.
75 * @warning Waiting for the owner might soft lock the execution.
76 * @param gpu_wait Wait for the fence to be signaled by the driver.
77 * @param owner_wait Wait for the owner to signal its freedom.
78 * @returns True if the fence is free. Waiting for gpu and owner will always return true.
79 */
80 bool Tick(bool gpu_wait, bool owner_wait);
81
82 const VKDevice& device; ///< Device handler
83 UniqueFence handle; ///< Vulkan fence
84 std::vector<VKResource*> protected_resources; ///< List of resources protected by this fence
85 bool is_owned = false; ///< The fence has been commited but not released yet.
86 bool is_used = false; ///< The fence has been commited but it has not been checked to be free.
87};
88
26} // namespace Vulkan 89} // namespace Vulkan