Explorar o código

Merge pull request #2686 from ReinUsesLisp/vk-scheduler

vk_scheduler: Drop execution context in favor of views
bunnei %!s(int64=7) %!d(string=hai) anos
pai
achega
7fb7054bc8

+ 2 - 2
src/video_core/renderer_vulkan/vk_buffer_cache.cpp

@@ -109,8 +109,8 @@ void VKBufferCache::Reserve(std::size_t max_size) {
     }
 }
 
-VKExecutionContext VKBufferCache::Send(VKExecutionContext exctx) {
-    return stream_buffer->Send(exctx, buffer_offset - buffer_offset_base);
+void VKBufferCache::Send() {
+    stream_buffer->Send(buffer_offset - buffer_offset_base);
 }
 
 void VKBufferCache::AlignBuffer(std::size_t alignment) {

+ 1 - 1
src/video_core/renderer_vulkan/vk_buffer_cache.h

@@ -77,7 +77,7 @@ public:
     void Reserve(std::size_t max_size);
 
     /// Ensures that the set data is sent to the device.
-    [[nodiscard]] VKExecutionContext Send(VKExecutionContext exctx);
+    void Send();
 
     /// Returns the buffer cache handle.
     vk::Buffer GetBuffer() const {

+ 6 - 10
src/video_core/renderer_vulkan/vk_scheduler.cpp

@@ -19,23 +19,19 @@ VKScheduler::VKScheduler(const VKDevice& device, VKResourceManager& resource_man
 
 VKScheduler::~VKScheduler() = default;
 
-VKExecutionContext VKScheduler::GetExecutionContext() const {
-    return VKExecutionContext(current_fence, current_cmdbuf);
-}
-
-VKExecutionContext VKScheduler::Flush(vk::Semaphore semaphore) {
+void VKScheduler::Flush(bool release_fence, vk::Semaphore semaphore) {
     SubmitExecution(semaphore);
-    current_fence->Release();
+    if (release_fence)
+        current_fence->Release();
     AllocateNewContext();
-    return GetExecutionContext();
 }
 
-VKExecutionContext VKScheduler::Finish(vk::Semaphore semaphore) {
+void VKScheduler::Finish(bool release_fence, vk::Semaphore semaphore) {
     SubmitExecution(semaphore);
     current_fence->Wait();
-    current_fence->Release();
+    if (release_fence)
+        current_fence->Release();
     AllocateNewContext();
-    return GetExecutionContext();
 }
 
 void VKScheduler::SubmitExecution(vk::Semaphore semaphore) {

+ 47 - 31
src/video_core/renderer_vulkan/vk_scheduler.h

@@ -10,10 +10,43 @@
 namespace Vulkan {
 
 class VKDevice;
-class VKExecutionContext;
 class VKFence;
 class VKResourceManager;
 
+class VKFenceView {
+public:
+    VKFenceView() = default;
+    VKFenceView(VKFence* const& fence) : fence{fence} {}
+
+    VKFence* operator->() const noexcept {
+        return fence;
+    }
+
+    operator VKFence&() const noexcept {
+        return *fence;
+    }
+
+private:
+    VKFence* const& fence;
+};
+
+class VKCommandBufferView {
+public:
+    VKCommandBufferView() = default;
+    VKCommandBufferView(const vk::CommandBuffer& cmdbuf) : cmdbuf{cmdbuf} {}
+
+    const vk::CommandBuffer* operator->() const noexcept {
+        return &cmdbuf;
+    }
+
+    operator vk::CommandBuffer() const noexcept {
+        return cmdbuf;
+    }
+
+private:
+    const vk::CommandBuffer& cmdbuf;
+};
+
 /// The scheduler abstracts command buffer and fence management with an interface that's able to do
 /// OpenGL-like operations on Vulkan command buffers.
 class VKScheduler {
@@ -21,16 +54,21 @@ public:
     explicit VKScheduler(const VKDevice& device, VKResourceManager& resource_manager);
     ~VKScheduler();
 
-    /// Gets the current execution context.
-    [[nodiscard]] VKExecutionContext GetExecutionContext() const;
+    /// Gets a reference to the current fence.
+    VKFenceView GetFence() const {
+        return current_fence;
+    }
+
+    /// Gets a reference to the current command buffer.
+    VKCommandBufferView GetCommandBuffer() const {
+        return current_cmdbuf;
+    }
 
-    /// Sends the current execution context to the GPU. It invalidates the current execution context
-    /// and returns a new one.
-    VKExecutionContext Flush(vk::Semaphore semaphore = nullptr);
+    /// Sends the current execution context to the GPU.
+    void Flush(bool release_fence = true, vk::Semaphore semaphore = nullptr);
 
-    /// Sends the current execution context to the GPU and waits for it to complete. It invalidates
-    /// the current execution context and returns a new one.
-    VKExecutionContext Finish(vk::Semaphore semaphore = nullptr);
+    /// Sends the current execution context to the GPU and waits for it to complete.
+    void Finish(bool release_fence = true, vk::Semaphore semaphore = nullptr);
 
 private:
     void SubmitExecution(vk::Semaphore semaphore);
@@ -44,26 +82,4 @@ private:
     VKFence* next_fence = nullptr;
 };
 
-class VKExecutionContext {
-    friend class VKScheduler;
-
-public:
-    VKExecutionContext() = default;
-
-    VKFence& GetFence() const {
-        return *fence;
-    }
-
-    vk::CommandBuffer GetCommandBuffer() const {
-        return cmdbuf;
-    }
-
-private:
-    explicit VKExecutionContext(VKFence* fence, vk::CommandBuffer cmdbuf)
-        : fence{fence}, cmdbuf{cmdbuf} {}
-
-    VKFence* fence{};
-    vk::CommandBuffer cmdbuf;
-};
-
 } // namespace Vulkan

+ 3 - 5
src/video_core/renderer_vulkan/vk_stream_buffer.cpp

@@ -46,12 +46,12 @@ std::tuple<u8*, u64, bool> VKStreamBuffer::Reserve(u64 size) {
     return {mapped_pointer + offset, offset, invalidation_mark.has_value()};
 }
 
-VKExecutionContext VKStreamBuffer::Send(VKExecutionContext exctx, u64 size) {
+void VKStreamBuffer::Send(u64 size) {
     ASSERT_MSG(size <= mapped_size, "Reserved size is too small");
 
     if (invalidation_mark) {
         // TODO(Rodrigo): Find a better way to invalidate than waiting for all watches to finish.
-        exctx = scheduler.Flush();
+        scheduler.Flush();
         std::for_each(watches.begin(), watches.begin() + *invalidation_mark,
                       [&](auto& resource) { resource->Wait(); });
         invalidation_mark = std::nullopt;
@@ -62,11 +62,9 @@ VKExecutionContext VKStreamBuffer::Send(VKExecutionContext exctx, u64 size) {
         ReserveWatches(WATCHES_RESERVE_CHUNK);
     }
     // Add a watch for this allocation.
-    watches[used_watches++]->Watch(exctx.GetFence());
+    watches[used_watches++]->Watch(scheduler.GetFence());
 
     offset += size;
-
-    return exctx;
 }
 
 void VKStreamBuffer::CreateBuffers(VKMemoryManager& memory_manager, vk::BufferUsageFlags usage) {

+ 1 - 1
src/video_core/renderer_vulkan/vk_stream_buffer.h

@@ -37,7 +37,7 @@ public:
     std::tuple<u8*, u64, bool> Reserve(u64 size);
 
     /// Ensures that "size" bytes of memory are available to the GPU, potentially recording a copy.
-    [[nodiscard]] VKExecutionContext Send(VKExecutionContext exctx, u64 size);
+    void Send(u64 size);
 
     vk::Buffer GetBuffer() const {
         return *buffer;