@ -16,8 +16,8 @@
# include "common/alignment.h"
# include "common/alignment.h"
# include "common/common_types.h"
# include "common/common_types.h"
# include "common/settings.h"
# include "common/polyfill_thread.h"
# include "common/polyfill_thread.h"
# include "common/settings.h"
# include "video_core/renderer_vulkan/vk_master_semaphore.h"
# include "video_core/renderer_vulkan/vk_master_semaphore.h"
# include "video_core/vulkan_common/vulkan_wrapper.h"
# include "video_core/vulkan_common/vulkan_wrapper.h"
@ -114,29 +114,36 @@ public:
/ / / Waits for the given GPU tick , optionally pacing frames .
/ / / Waits for the given GPU tick , optionally pacing frames .
void Wait ( u64 tick , double target_fps = 0.0 ) {
void Wait ( u64 tick , double target_fps = 0.0 ) {
if ( tick > 0 ) {
if ( tick > = master_semaphore - > CurrentTick ( ) ) {
Flush ( ) ;
}
master_semaphore - > Wait ( tick ) ;
}
if ( Settings : : values . use_speed_limit . GetValue ( ) & & target_fps > 0.0 ) {
if ( Settings : : values . use_speed_limit . GetValue ( ) & & target_fps > 0.0 ) {
const auto now = std : : chrono : : steady_clock : : now ( ) ;
if ( start_time = = std : : chrono : : steady_clock : : time_point { } | | current_target_fps ! = target_fps ) {
start_time = now ;
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 ;
frame_counter = 0 ;
current_target_fps = target_fps ;
start_time = now ;
}
}
frame_counter + + ;
frame_counter + + ;
std : : chrono : : duration < double > frame_interval ( 1.0 / current_target_fps ) ;
auto target_time = start_time + frame_interval * frame_counter ;
auto target_time = start_time + frame_interval * frame_counter ;
if ( target_time > now ) {
std : : this_thread : : sleep_until ( target_time ) ;
} else {
start_time = now ;
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 ;
frame_counter = 0 ;
start_time = now ;
}
}
}
}
if ( tick > 0 ) {
if ( tick > = master_semaphore - > CurrentTick ( ) ) {
Flush ( ) ;
}
master_semaphore - > Wait ( tick ) ;
}
}
}
/ / / Returns the master timeline semaphore .
/ / / Returns the master timeline semaphore .
@ -281,9 +288,11 @@ private:
std : : condition_variable_any event_cv ;
std : : condition_variable_any event_cv ;
std : : jthread worker_thread ;
std : : jthread worker_thread ;
std : : chrono : : steady_clock : : duration frame_interval { } ;
std : : chrono : : steady_clock : : time_point start_time { } ;
std : : chrono : : steady_clock : : time_point start_time { } ;
double last_target_fps { } ;
u64 max_frame_count { } ;
u64 frame_counter { } ;
u64 frame_counter { } ;
double current_target_fps { } ;
} ;
} ;
} / / namespace Vulkan
} / / namespace Vulkan