diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 6c21affdc..5444abcfc 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -123,22 +123,23 @@ void CommandProcessor::WorkerMain() { while (worker_running_) { uint32_t write_ptr_index = write_ptr_index_.load(); - while (write_ptr_index == 0xBAADF00D || - read_ptr_index_ == write_ptr_index) { + if (write_ptr_index == 0xBAADF00D || read_ptr_index_ == write_ptr_index) { SCOPE_profile_cpu_i("gpu", "xe::gpu::gl4::CommandProcessor::Stall"); - // Check if the pointer has moved. - // We wait a short bit here to yield time. Since we are also running the - // main window display we don't want to pause too long, though. - // YieldProcessor(); - PrepareForWait(); - const int wait_time_ms = 5; - if (WaitForSingleObject(write_ptr_index_event_, wait_time_ms) == - WAIT_TIMEOUT) { - ReturnFromWait(); + // We've run out of commands to execute. + // We spin here waiting for new ones, as the overhead of waiting on our + // event is too high. + //PrepareForWait(); + do { + // TODO(benvanik): if we go longer than Nms, switch to waiting? + // It'll keep us from burning power. + // const int wait_time_ms = 5; + // WaitForSingleObject(write_ptr_index_event_, wait_time_ms); + SwitchToThread(); + MemoryBarrier(); write_ptr_index = write_ptr_index_.load(); - continue; - } - ReturnFromWait(); + } while (write_ptr_index == 0xBAADF00D || + read_ptr_index_ == write_ptr_index); + //ReturnFromWait(); } assert_true(read_ptr_index_ != write_ptr_index); @@ -925,7 +926,13 @@ bool CommandProcessor::ExecutePacketType3_WAIT_REG_MEM(RingbufferReader* reader, // Wait. if (wait >= 0x100) { PrepareForWait(); - Sleep(wait / 0x100); + if (!FLAGS_vsync) { + // User wants it fast and dangerous. + SwitchToThread(); + } else { + Sleep(wait / 0x100); + } + MemoryBarrier(); ReturnFromWait(); } else { SwitchToThread(); diff --git a/src/xenia/gpu/gl4/gl4_graphics_system.cc b/src/xenia/gpu/gl4/gl4_graphics_system.cc index 2edc4277d..dde643ce3 100644 --- a/src/xenia/gpu/gl4/gl4_graphics_system.cc +++ b/src/xenia/gpu/gl4/gl4_graphics_system.cc @@ -77,10 +77,15 @@ X_STATUS GL4GraphicsSystem::Setup() { reinterpret_cast(MMIOWriteRegisterThunk)); // 60hz vsync timer. + DWORD timer_period = 16; + if (!FLAGS_vsync) { + // DANGER a value too low here will lead to starvation! + timer_period = 4; + } timer_queue_ = CreateTimerQueue(); CreateTimerQueueTimer(&vsync_timer_, timer_queue_, - (WAITORTIMERCALLBACK)VsyncCallbackThunk, this, 16, 16, - WT_EXECUTEINTIMERTHREAD); + (WAITORTIMERCALLBACK)VsyncCallbackThunk, this, 16, + timer_period, WT_EXECUTEINPERSISTENTTHREAD); return X_STATUS_SUCCESS; } @@ -138,9 +143,6 @@ void GL4GraphicsSystem::SwapHandler(const SwapParameters& swap_params) { control_->width(), control_->height(), GL_COLOR_BUFFER_BIT, GL_LINEAR); }); - - // Roll over vblank. - MarkVblank(); } uint64_t GL4GraphicsSystem::ReadRegister(uint64_t addr) { diff --git a/src/xenia/gpu/gpu-private.h b/src/xenia/gpu/gpu-private.h index aafa820fd..4b9024447 100644 --- a/src/xenia/gpu/gpu-private.h +++ b/src/xenia/gpu/gpu-private.h @@ -17,4 +17,6 @@ DECLARE_string(gpu); DECLARE_bool(trace_ring_buffer); DECLARE_string(dump_shaders); +DECLARE_bool(vsync); + #endif // XENIA_GPU_PRIVATE_H_ diff --git a/src/xenia/gpu/gpu.cc b/src/xenia/gpu/gpu.cc index 92d0a9b94..47d773362 100644 --- a/src/xenia/gpu/gpu.cc +++ b/src/xenia/gpu/gpu.cc @@ -19,6 +19,8 @@ DEFINE_bool(trace_ring_buffer, false, "Trace GPU ring buffer packets."); DEFINE_string(dump_shaders, "", "Path to write GPU shaders to as they are compiled."); +DEFINE_bool(vsync, true, "Enable VSYNC."); + namespace xe { namespace gpu { diff --git a/src/xenia/profiling.cc b/src/xenia/profiling.cc index a143ff927..2602a1491 100644 --- a/src/xenia/profiling.cc +++ b/src/xenia/profiling.cc @@ -15,6 +15,7 @@ #define MICROPROFILEUI_IMPL 1 #define MICROPROFILE_PER_THREAD_BUFFER_SIZE (1024 * 1024 * 10) #define MICROPROFILE_USE_THREAD_NAME_CALLBACK 1 +#define MICROPROFILE_WEBSERVER_MAXFRAMES 10 #define MICROPROFILE_PRINTF PLOGI #define MICROPROFILE_WEBSERVER 1 #define MICROPROFILE_DEBUG 0