Browse Source

[video_core] optimized fence management

Co-authored-by: Pavel Barabanov <pavelbarabanov94@gmail.com>
Signed-off-by: crueter <crueter@eden-emu.dev>
pull/190/head
crueter 7 months ago
parent
commit
ed6f7bd14f
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 96
      src/video_core/fence_manager.h

96
src/video_core/fence_manager.h

@ -11,14 +11,11 @@
#include <cstring> #include <cstring>
#include <deque> #include <deque>
#include <functional> #include <functional>
#include <memory>
#include <mutex> #include <mutex>
#include <thread> #include <thread>
#include <queue> #include <queue>
#include "common/common_types.h" #include "common/common_types.h"
#include "common/microprofile.h"
#include "common/scope_exit.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/thread.h" #include "common/thread.h"
#include "video_core/delayed_destruction_ring.h" #include "video_core/delayed_destruction_ring.h"
@ -75,18 +72,41 @@ public:
} }
void SignalFence(std::function<void()>&& func) { void SignalFence(std::function<void()>&& func) {
bool delay_fence = Settings::IsGPULevelHigh();
HandleAndroidPreFenceOperations(delay_fence);
const bool delay_fence = Settings::IsGPULevelHigh();
#ifdef __ANDROID__
const bool use_optimized = Settings::values.early_release_fences.GetValue();
#else
constexpr bool use_optimized = false;
#endif
const bool should_flush = ShouldFlush(); const bool should_flush = ShouldFlush();
CommitAsyncFlushes(); CommitAsyncFlushes();
TFence new_fence = CreateFence(!should_flush); TFence new_fence = CreateFence(!should_flush);
LockGuardIfNeeded(delay_fence);
if (use_optimized) {
if (!delay_fence) {
TryReleasePendingFences<false>();
}
if (delay_fence) {
uncommitted_operations.emplace_back(std::move(func));
if (delay_fence) {
guard.lock();
uncommitted_operations.emplace_back(std::move(func));
}
} else {
if constexpr (!can_async_check) {
TryReleasePendingFences<false>();
}
if constexpr (can_async_check) {
guard.lock();
}
if (delay_fence) {
uncommitted_operations.emplace_back(std::move(func));
}
} }
pending_operations.emplace_back(std::move(uncommitted_operations)); pending_operations.emplace_back(std::move(uncommitted_operations));
QueueFence(new_fence); QueueFence(new_fence);
@ -100,7 +120,18 @@ public:
rasterizer.FlushCommands(); rasterizer.FlushCommands();
} }
UnlockGuardAndNotifyIfNeeded(delay_fence);
if (use_optimized) {
if (delay_fence) {
guard.unlock();
cv.notify_all();
}
} else {
if constexpr (can_async_check) {
guard.unlock();
cv.notify_all();
}
}
rasterizer.InvalidateGPUCache(); rasterizer.InvalidateGPUCache();
} }
@ -197,14 +228,6 @@ private:
void ReleaseThreadFunc(std::stop_token stop_token) { void ReleaseThreadFunc(std::stop_token stop_token) {
std::string name = "GPUFencingThread"; std::string name = "GPUFencingThread";
MicroProfileOnThreadCreate(name.c_str());
// Cleanup
#if MICROPROFILE_ENABLED
SCOPE_EXIT {
MicroProfileOnThreadExit();
};
#endif
Common::SetCurrentThreadName(name.c_str()); Common::SetCurrentThreadName(name.c_str());
Common::SetCurrentThreadPriority(Common::ThreadPriority::High); Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
@ -266,46 +289,7 @@ private:
} }
query_cache.CommitAsyncFlushes(); query_cache.CommitAsyncFlushes();
} }
void HandleAndroidPreFenceOperations(bool delay_fence)
{
#ifdef __ANDROID__
if (!delay_fence && Settings::values.early_release_fences.GetValue()) {
TryReleasePendingFences<false>();
}
#else
if constexpr (!can_async_check) {
TryReleasePendingFences<false>();
}
#endif
}
void LockGuardIfNeeded(bool delay_fence)
{
#ifdef __ANDROID__
if (delay_fence && Settings::values.early_release_fences.GetValue()) {
guard.lock();
}
#else
if constexpr (can_async_check) {
guard.lock();
}
#endif
}
void UnlockGuardAndNotifyIfNeeded(bool delay_fence)
{
#ifdef __ANDROID__
if (delay_fence && Settings::values.early_release_fences.GetValue()) {
guard.unlock();
cv.notify_all();
}
#else
if constexpr (can_async_check) {
guard.unlock();
cv.notify_all();
}
#endif
}
std::queue<TFence> fences; std::queue<TFence> fences;
std::deque<std::function<void()>> uncommitted_operations; std::deque<std::function<void()>> uncommitted_operations;
std::deque<std::deque<std::function<void()>>> pending_operations; std::deque<std::deque<std::function<void()>>> pending_operations;

Loading…
Cancel
Save