Browse Source

[TEST] Adjustments on framepacing submit calls

temporary-branch
CamilleLaVey 5 days ago
parent
commit
0cd5dd1e70
  1. 2
      src/video_core/renderer_vulkan/vk_fence_manager.cpp
  2. 60
      src/video_core/renderer_vulkan/vk_scheduler.h
  3. 28
      src/video_core/renderer_vulkan/vk_swapchain.cpp

2
src/video_core/renderer_vulkan/vk_fence_manager.cpp

@ -37,7 +37,7 @@ void InnerFence::Wait() {
if (is_stubbed) { if (is_stubbed) {
return; return;
} }
scheduler.Wait(wait_tick);
scheduler.WaitSubmitted(wait_tick);
} }
FenceManager::FenceManager(VideoCore::RasterizerInterface& rasterizer_, Tegra::GPU& gpu_, FenceManager::FenceManager(VideoCore::RasterizerInterface& rasterizer_, Tegra::GPU& gpu_,

60
src/video_core/renderer_vulkan/vk_scheduler.h

@ -131,33 +131,16 @@ public:
} }
master_semaphore->Wait(tick); master_semaphore->Wait(tick);
} }
if (Settings::values.use_speed_limit.GetValue() && target_fps > 0.0) {
auto now = std::chrono::steady_clock::now();
if (last_target_fps != target_fps) {
frame_interval = std::chrono::duration_cast<std::chrono::steady_clock::duration>(std::chrono::duration<double>(1.0 / target_fps));
max_frame_count = static_cast<int>(0.1 * target_fps);
last_target_fps = target_fps;
frame_counter = 0;
start_time = now;
}
frame_counter++;
auto target_time = start_time + frame_interval * frame_counter;
if (target_time >= now) {
auto sleep_time = target_time - now;
if (sleep_time > std::chrono::milliseconds(15)) {
std::this_thread::sleep_for(sleep_time - std::chrono::milliseconds(1));
}
while (std::chrono::steady_clock::now() < target_time) {
std::this_thread::yield();
}
} else if (frame_counter > max_frame_count) {
frame_counter = 0;
start_time = now;
}
ApplyFramePacing(target_fps);
}
void WaitSubmitted(u64 tick, double target_fps = 0.0) {
if (tick > 0 && tick < master_semaphore->CurrentTick()) {
master_semaphore->Wait(tick);
} }
ApplyFramePacing(target_fps);
} }
/// Returns the master timeline semaphore.
[[nodiscard]] MasterSemaphore& GetMasterSemaphore() const noexcept { [[nodiscard]] MasterSemaphore& GetMasterSemaphore() const noexcept {
return *master_semaphore; return *master_semaphore;
} }
@ -165,6 +148,35 @@ public:
std::mutex submit_mutex; std::mutex submit_mutex;
private: private:
void ApplyFramePacing(double target_fps) {
if (!Settings::values.use_speed_limit.GetValue() || target_fps <= 0.0) {
return;
}
auto now = std::chrono::steady_clock::now();
if (last_target_fps != target_fps) {
frame_interval = std::chrono::duration_cast<std::chrono::steady_clock::duration>(
std::chrono::duration<double>(1.0 / target_fps));
max_frame_count = static_cast<int>(0.1 * target_fps);
last_target_fps = target_fps;
frame_counter = 0;
start_time = now;
}
frame_counter++;
auto target_time = start_time + frame_interval * frame_counter;
if (target_time >= now) {
auto sleep_time = target_time - now;
if (sleep_time > std::chrono::milliseconds(15)) {
std::this_thread::sleep_for(sleep_time - std::chrono::milliseconds(1));
}
while (std::chrono::steady_clock::now() < target_time) {
std::this_thread::yield();
}
} else if (frame_counter > max_frame_count) {
frame_counter = 0;
start_time = now;
}
}
class Command { class Command {
public: public:
virtual ~Command() = default; virtual ~Command() = default;

28
src/video_core/renderer_vulkan/vk_swapchain.cpp

@ -9,10 +9,6 @@
#include <limits> #include <limits>
#include <vector> #include <vector>
#ifdef __ANDROID__
#include <android/api-level.h>
#endif
#include "common/logging.h" #include "common/logging.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/settings_enums.h" #include "common/settings_enums.h"
@ -176,34 +172,26 @@ bool Swapchain::AcquireNextImage() {
break; break;
} }
const auto wait_with_frame_pacing = [this] {
#ifdef __ANDROID__
scheduler.WaitSubmitted(resource_ticks[image_index]);
#else
switch (Settings::values.frame_pacing_mode.GetValue()) { switch (Settings::values.frame_pacing_mode.GetValue()) {
case Settings::FramePacingMode::Target_Auto: case Settings::FramePacingMode::Target_Auto:
scheduler.Wait(resource_ticks[image_index]);
scheduler.WaitSubmitted(resource_ticks[image_index]);
break; break;
case Settings::FramePacingMode::Target_30: case Settings::FramePacingMode::Target_30:
scheduler.Wait(resource_ticks[image_index], 30.0);
scheduler.WaitSubmitted(resource_ticks[image_index], 30.0);
break; break;
case Settings::FramePacingMode::Target_60: case Settings::FramePacingMode::Target_60:
scheduler.Wait(resource_ticks[image_index], 60.0);
scheduler.WaitSubmitted(resource_ticks[image_index], 60.0);
break; break;
case Settings::FramePacingMode::Target_90: case Settings::FramePacingMode::Target_90:
scheduler.Wait(resource_ticks[image_index], 90.0);
scheduler.WaitSubmitted(resource_ticks[image_index], 90.0);
break; break;
case Settings::FramePacingMode::Target_120: case Settings::FramePacingMode::Target_120:
scheduler.Wait(resource_ticks[image_index], 120.0);
scheduler.WaitSubmitted(resource_ticks[image_index], 120.0);
break; break;
} }
};
#ifdef __ANDROID__
if (android_get_device_api_level() >= 30) {
scheduler.Wait(resource_ticks[image_index]);
} else {
wait_with_frame_pacing();
}
#else
wait_with_frame_pacing();
#endif #endif
resource_ticks[image_index] = scheduler.CurrentTick(); resource_ticks[image_index] = scheduler.CurrentTick();

Loading…
Cancel
Save