[GPU] Vsync timing requires far less cpu now to be accurate
This commit is contained in:
parent
294b968fdf
commit
cfecdcbeab
|
@ -104,22 +104,34 @@ X_STATUS GraphicsSystem::Setup(cpu::Processor* processor,
|
||||||
vsync_worker_running_ = true;
|
vsync_worker_running_ = true;
|
||||||
vsync_worker_thread_ = kernel::object_ref<kernel::XHostThread>(
|
vsync_worker_thread_ = kernel::object_ref<kernel::XHostThread>(
|
||||||
new kernel::XHostThread(kernel_state_, 128 * 1024, 0, [this]() {
|
new kernel::XHostThread(kernel_state_, 128 * 1024, 0, [this]() {
|
||||||
double vsync_duration_d =
|
const double vsync_duration_d =
|
||||||
cvars::vsync
|
cvars::vsync
|
||||||
? std::max<double>(
|
? std::max<double>(
|
||||||
5.0, 1000.0 / static_cast<double>(cvars::vsync_fps))
|
5.0, 1000.0 / static_cast<double>(cvars::vsync_fps))
|
||||||
: 1.0;
|
: 1.0;
|
||||||
uint64_t last_frame_time = Clock::QueryGuestTickCount();
|
uint64_t last_frame_time = Clock::QueryGuestTickCount();
|
||||||
while (vsync_worker_running_) {
|
// Sleep for 90% of the vblank duration, spin for 10%
|
||||||
uint64_t current_time = Clock::QueryGuestTickCount();
|
const double duration_scalar = 0.90;
|
||||||
|
|
||||||
uint64_t tick_freq = Clock::guest_tick_frequency();
|
while (vsync_worker_running_) {
|
||||||
uint64_t time_delta = current_time - last_frame_time;
|
const uint64_t current_time = Clock::QueryGuestTickCount();
|
||||||
double elapsed_d = static_cast<double>(time_delta) /
|
const uint64_t tick_freq = Clock::guest_tick_frequency();
|
||||||
|
const uint64_t time_delta = current_time - last_frame_time;
|
||||||
|
const double elapsed_d = static_cast<double>(time_delta) /
|
||||||
(static_cast<double>(tick_freq) / 1000.0);
|
(static_cast<double>(tick_freq) / 1000.0);
|
||||||
if (elapsed_d >= vsync_duration_d) {
|
if (elapsed_d >= vsync_duration_d) {
|
||||||
MarkVblank();
|
|
||||||
last_frame_time = current_time;
|
last_frame_time = current_time;
|
||||||
|
|
||||||
|
// TODO(disjtqz): should recalculate the remaining time to a vblank
|
||||||
|
// after MarkVblank, no idea how long the guest code normally takes
|
||||||
|
MarkVblank();
|
||||||
|
if (cvars::vsync) {
|
||||||
|
const uint64_t estimated_nanoseconds = static_cast<uint64_t>(
|
||||||
|
(vsync_duration_d * 1000000.0) *
|
||||||
|
duration_scalar); // 1000 microseconds = 1 ms
|
||||||
|
|
||||||
|
threading::NanoSleep(estimated_nanoseconds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!cvars::vsync) {
|
if (!cvars::vsync) {
|
||||||
xe::threading::Sleep(std::chrono::milliseconds(1));
|
xe::threading::Sleep(std::chrono::milliseconds(1));
|
||||||
|
@ -131,7 +143,8 @@ X_STATUS GraphicsSystem::Setup(cpu::Processor* processor,
|
||||||
vsync_worker_thread_->set_can_debugger_suspend(true);
|
vsync_worker_thread_->set_can_debugger_suspend(true);
|
||||||
vsync_worker_thread_->set_name("GPU VSync");
|
vsync_worker_thread_->set_name("GPU VSync");
|
||||||
vsync_worker_thread_->Create();
|
vsync_worker_thread_->Create();
|
||||||
vsync_worker_thread_->thread()->set_priority(threading::ThreadPriority::kLowest);
|
vsync_worker_thread_->thread()->set_priority(
|
||||||
|
threading::ThreadPriority::kLowest);
|
||||||
if (cvars::trace_gpu_stream) {
|
if (cvars::trace_gpu_stream) {
|
||||||
BeginTracing();
|
BeginTracing();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue