Просмотр исходного кода

vk_resource_manager: Implement VKFenceWatch move constructor

This allows us to put VKFenceWatch inside a std::vector without storing
it in heap. On move we have to signal the fences where the new protected
resource is, adding some overhead.
ReinUsesLisp 6 лет назад
Родитель
Сommit
6ddffa010a

+ 24 - 0
src/video_core/renderer_vulkan/vk_resource_manager.cpp

@@ -142,8 +142,32 @@ void VKFence::Unprotect(VKResource* resource) {
     protected_resources.erase(it);
 }
 
+void VKFence::RedirectProtection(VKResource* old_resource, VKResource* new_resource) noexcept {
+    std::replace(std::begin(protected_resources), std::end(protected_resources), old_resource,
+                 new_resource);
+}
+
 VKFenceWatch::VKFenceWatch() = default;
 
+VKFenceWatch::VKFenceWatch(VKFence& initial_fence) {
+    Watch(initial_fence);
+}
+
+VKFenceWatch::VKFenceWatch(VKFenceWatch&& rhs) noexcept {
+    fence = std::exchange(rhs.fence, nullptr);
+    if (fence) {
+        fence->RedirectProtection(&rhs, this);
+    }
+}
+
+VKFenceWatch& VKFenceWatch::operator=(VKFenceWatch&& rhs) noexcept {
+    fence = std::exchange(rhs.fence, nullptr);
+    if (fence) {
+        fence->RedirectProtection(&rhs, this);
+    }
+    return *this;
+}
+
 VKFenceWatch::~VKFenceWatch() {
     if (fence) {
         fence->Unprotect(this);

+ 8 - 0
src/video_core/renderer_vulkan/vk_resource_manager.h

@@ -65,6 +65,9 @@ public:
     /// Removes protection for a resource.
     void Unprotect(VKResource* resource);
 
+    /// Redirects one protected resource to a new address.
+    void RedirectProtection(VKResource* old_resource, VKResource* new_resource) noexcept;
+
     /// Retreives the fence.
     operator vk::Fence() const {
         return *handle;
@@ -97,8 +100,13 @@ private:
 class VKFenceWatch final : public VKResource {
 public:
     explicit VKFenceWatch();
+    VKFenceWatch(VKFence& initial_fence);
+    VKFenceWatch(VKFenceWatch&&) noexcept;
+    VKFenceWatch(const VKFenceWatch&) = delete;
     ~VKFenceWatch() override;
 
+    VKFenceWatch& operator=(VKFenceWatch&&) noexcept;
+
     /// Waits for the fence to be released.
     void Wait();