mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-23 14:25:37 +00:00
GPU/SW: Spin for 1ms rather than immediately sleeping
This commit is contained in:
parent
90e0ff33db
commit
e4d5d9f049
|
@ -2,6 +2,7 @@
|
||||||
#include "common/align.h"
|
#include "common/align.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "common/state_wrapper.h"
|
#include "common/state_wrapper.h"
|
||||||
|
#include "common/timer.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
Log_SetChannel(GPUBackend);
|
Log_SetChannel(GPUBackend);
|
||||||
|
|
||||||
|
@ -21,13 +22,13 @@ bool GPUBackend::Initialize()
|
||||||
|
|
||||||
void GPUBackend::Reset(bool clear_vram)
|
void GPUBackend::Reset(bool clear_vram)
|
||||||
{
|
{
|
||||||
Sync();
|
Sync(true);
|
||||||
m_drawing_area = {};
|
m_drawing_area = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUBackend::UpdateSettings()
|
void GPUBackend::UpdateSettings()
|
||||||
{
|
{
|
||||||
Sync();
|
Sync(true);
|
||||||
|
|
||||||
if (m_use_gpu_thread != g_settings.gpu_use_thread)
|
if (m_use_gpu_thread != g_settings.gpu_use_thread)
|
||||||
{
|
{
|
||||||
|
@ -188,13 +189,14 @@ void GPUBackend::StopGPUThread()
|
||||||
Log_InfoPrint("GPU thread stopped.");
|
Log_InfoPrint("GPU thread stopped.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUBackend::Sync()
|
void GPUBackend::Sync(bool allow_sleep)
|
||||||
{
|
{
|
||||||
if (!m_use_gpu_thread)
|
if (!m_use_gpu_thread)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GPUBackendSyncCommand* cmd =
|
GPUBackendSyncCommand* cmd =
|
||||||
static_cast<GPUBackendSyncCommand*>(AllocateCommand(GPUBackendCommandType::Sync, sizeof(GPUBackendSyncCommand)));
|
static_cast<GPUBackendSyncCommand*>(AllocateCommand(GPUBackendCommandType::Sync, sizeof(GPUBackendSyncCommand)));
|
||||||
|
cmd->allow_sleep = allow_sleep;
|
||||||
PushCommand(cmd);
|
PushCommand(cmd);
|
||||||
WakeGPUThread();
|
WakeGPUThread();
|
||||||
|
|
||||||
|
@ -204,12 +206,19 @@ void GPUBackend::Sync()
|
||||||
|
|
||||||
void GPUBackend::RunGPULoop()
|
void GPUBackend::RunGPULoop()
|
||||||
{
|
{
|
||||||
|
static constexpr double SPIN_TIME_NS = 1 * 1000000;
|
||||||
|
Common::Timer::Value last_command_time = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
u32 write_ptr = m_command_fifo_write_ptr.load();
|
u32 write_ptr = m_command_fifo_write_ptr.load();
|
||||||
u32 read_ptr = m_command_fifo_read_ptr.load();
|
u32 read_ptr = m_command_fifo_read_ptr.load();
|
||||||
if (read_ptr == write_ptr)
|
if (read_ptr == write_ptr)
|
||||||
{
|
{
|
||||||
|
const Common::Timer::Value current_time = Common::Timer::GetValue();
|
||||||
|
if (Common::Timer::ConvertValueToNanoseconds(current_time - last_command_time) < SPIN_TIME_NS)
|
||||||
|
continue;
|
||||||
|
|
||||||
std::unique_lock<std::mutex> lock(m_sync_mutex);
|
std::unique_lock<std::mutex> lock(m_sync_mutex);
|
||||||
m_gpu_thread_sleeping.store(true);
|
m_gpu_thread_sleeping.store(true);
|
||||||
m_wake_gpu_thread_cv.wait(lock, [this]() { return m_gpu_loop_done.load() || GetPendingCommandSize() > 0; });
|
m_wake_gpu_thread_cv.wait(lock, [this]() { return m_gpu_loop_done.load() || GetPendingCommandSize() > 0; });
|
||||||
|
@ -224,6 +233,7 @@ void GPUBackend::RunGPULoop()
|
||||||
if (write_ptr < read_ptr)
|
if (write_ptr < read_ptr)
|
||||||
write_ptr = COMMAND_QUEUE_SIZE;
|
write_ptr = COMMAND_QUEUE_SIZE;
|
||||||
|
|
||||||
|
bool allow_sleep = false;
|
||||||
while (read_ptr < write_ptr)
|
while (read_ptr < write_ptr)
|
||||||
{
|
{
|
||||||
const GPUBackendCommand* cmd = reinterpret_cast<const GPUBackendCommand*>(&m_command_fifo_data[read_ptr]);
|
const GPUBackendCommand* cmd = reinterpret_cast<const GPUBackendCommand*>(&m_command_fifo_data[read_ptr]);
|
||||||
|
@ -243,6 +253,7 @@ void GPUBackend::RunGPULoop()
|
||||||
{
|
{
|
||||||
DebugAssert(read_ptr == write_ptr);
|
DebugAssert(read_ptr == write_ptr);
|
||||||
m_sync_event.Signal();
|
m_sync_event.Signal();
|
||||||
|
allow_sleep = static_cast<const GPUBackendSyncCommand*>(cmd)->allow_sleep;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -252,6 +263,7 @@ void GPUBackend::RunGPULoop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
last_command_time = allow_sleep ? 0 : Common::Timer::GetValue();
|
||||||
m_command_fifo_read_ptr.store(read_ptr);
|
m_command_fifo_read_ptr.store(read_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
GPUBackendDrawLineCommand* NewDrawLineCommand(u32 num_vertices);
|
GPUBackendDrawLineCommand* NewDrawLineCommand(u32 num_vertices);
|
||||||
|
|
||||||
void PushCommand(GPUBackendCommand* cmd);
|
void PushCommand(GPUBackendCommand* cmd);
|
||||||
void Sync();
|
void Sync(bool allow_sleep);
|
||||||
|
|
||||||
/// Processes all pending GPU commands.
|
/// Processes all pending GPU commands.
|
||||||
void RunGPULoop();
|
void RunGPULoop();
|
||||||
|
|
|
@ -482,7 +482,7 @@ void GPU_SW::ClearDisplay()
|
||||||
void GPU_SW::UpdateDisplay()
|
void GPU_SW::UpdateDisplay()
|
||||||
{
|
{
|
||||||
// fill display texture
|
// fill display texture
|
||||||
m_backend.Sync();
|
m_backend.Sync(true);
|
||||||
|
|
||||||
if (!g_settings.debugging.show_vram)
|
if (!g_settings.debugging.show_vram)
|
||||||
{
|
{
|
||||||
|
@ -824,7 +824,7 @@ void GPU_SW::DispatchRenderCommand()
|
||||||
|
|
||||||
void GPU_SW::ReadVRAM(u32 x, u32 y, u32 width, u32 height)
|
void GPU_SW::ReadVRAM(u32 x, u32 y, u32 width, u32 height)
|
||||||
{
|
{
|
||||||
m_backend.Sync();
|
m_backend.Sync(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_SW::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
void GPU_SW::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
||||||
|
|
|
@ -277,6 +277,7 @@ struct GPUBackendCommand
|
||||||
|
|
||||||
struct GPUBackendSyncCommand : public GPUBackendCommand
|
struct GPUBackendSyncCommand : public GPUBackendCommand
|
||||||
{
|
{
|
||||||
|
bool allow_sleep;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GPUBackendFillVRAMCommand : public GPUBackendCommand
|
struct GPUBackendFillVRAMCommand : public GPUBackendCommand
|
||||||
|
|
Loading…
Reference in a new issue