Skip to content

Commit 8b40b30

Browse files
committed
Improve VBlank timing
Some vblank wait methods can skip sleeping, if they are called inside or outside a vblank (according to their function).
1 parent 7cffacb commit 8b40b30

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

Source/iop/IopBios.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#define BIOS_THREAD_LINK_HEAD_BASE (CIopBios::CONTROL_BLOCK_START + 0x0000)
5252
#define BIOS_CURRENT_THREAD_ID_BASE (CIopBios::CONTROL_BLOCK_START + 0x0008)
5353
#define BIOS_CURRENT_TIME_BASE (CIopBios::CONTROL_BLOCK_START + 0x0010)
54+
#define BIOS_IN_VBLANK_BASE (CIopBios::CONTROL_BLOCK_START + 0x0014)
5455
#define BIOS_MODULESTARTREQUEST_HEAD_BASE (CIopBios::CONTROL_BLOCK_START + 0x0018)
5556
#define BIOS_MODULESTARTREQUEST_FREE_BASE (CIopBios::CONTROL_BLOCK_START + 0x0020)
5657
#define BIOS_HANDLERS_BASE (CIopBios::CONTROL_BLOCK_START + 0x0100)
@@ -116,6 +117,7 @@ CIopBios::CIopBios(CMIPS& cpu, uint8* ram, uint32 ramSize, uint8* spr)
116117
, m_vpls(reinterpret_cast<VPL*>(&m_ram[BIOS_VPL_BASE]), 1, MAX_VPL)
117118
, m_loadedModules(reinterpret_cast<LOADEDMODULE*>(&m_ram[BIOS_LOADEDMODULE_BASE]), 1, MAX_LOADEDMODULE)
118119
, m_currentThreadId(reinterpret_cast<uint32*>(m_ram + BIOS_CURRENT_THREAD_ID_BASE))
120+
, m_inVBlank(reinterpret_cast<bool*>(m_ram + BIOS_IN_VBLANK_BASE))
119121
{
120122
static_assert(BIOS_CALCULATED_END <= CIopBios::CONTROL_BLOCK_END, "Control block size is too small");
121123
static_assert(BIOS_SYSTEM_INTRHANDLER_TABLE_BASE > CIopBios::CONTROL_BLOCK_START, "Intr handler table is outside reserved block");
@@ -146,6 +148,7 @@ void CIopBios::Reset(const Iop::SifManPtr& sifMan)
146148
CurrentTime() = 0xBE00000;
147149
ThreadLinkHead() = 0;
148150
m_currentThreadId = -1;
151+
m_inVBlank = false;
149152

150153
m_cpu.m_State.nCOP0[CCOP_SCU::STATUS] |= CMIPS::STATUS_IE;
151154

@@ -1692,6 +1695,30 @@ void CIopBios::SleepThreadTillVBlankEnd()
16921695
m_rescheduleNeeded = true;
16931696
}
16941697

1698+
void CIopBios::SleepThreadTillVBlank()
1699+
{
1700+
if(m_inVBlank)
1701+
{
1702+
return;
1703+
}
1704+
THREAD* thread = GetThread(m_currentThreadId);
1705+
thread->status = THREAD_STATUS_WAIT_VBLANK_START;
1706+
UnlinkThread(thread->id);
1707+
m_rescheduleNeeded = true;
1708+
}
1709+
1710+
void CIopBios::SleepThreadTillNonVBlank()
1711+
{
1712+
if(!m_inVBlank)
1713+
{
1714+
return;
1715+
}
1716+
THREAD* thread = GetThread(m_currentThreadId);
1717+
thread->status = THREAD_STATUS_WAIT_VBLANK_END;
1718+
UnlinkThread(thread->id);
1719+
m_rescheduleNeeded = true;
1720+
}
1721+
16951722
void CIopBios::LoadThreadContext(uint32 threadId)
16961723
{
16971724
THREAD* thread = GetThread(threadId);
@@ -1849,6 +1876,7 @@ void CIopBios::CountTicks(uint32 ticks)
18491876

18501877
void CIopBios::NotifyVBlankStart()
18511878
{
1879+
m_inVBlank = true;
18521880
for(auto thread : m_threads)
18531881
{
18541882
if(!thread) continue;
@@ -1862,6 +1890,7 @@ void CIopBios::NotifyVBlankStart()
18621890

18631891
void CIopBios::NotifyVBlankEnd()
18641892
{
1893+
m_inVBlank = false;
18651894
for(auto thread : m_threads)
18661895
{
18671896
if(!thread) continue;

Source/iop/IopBios.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ class CIopBios : public Iop::CBiosBase
239239
int32 FindVblankHandlerByLineAndPtr(uint32 startEnd, uint32 handlerPtr);
240240
void SleepThreadTillVBlankStart();
241241
void SleepThreadTillVBlankEnd();
242+
void SleepThreadTillVBlank();
243+
void SleepThreadTillNonVBlank();
242244

243245
uint32 CreateSemaphore(uint32, uint32, uint32, uint32);
244246
uint32 DeleteSemaphore(uint32);
@@ -662,6 +664,7 @@ class CIopBios : public Iop::CBiosBase
662664
IopModuleMapType m_modules;
663665

664666
OsVariableWrapper<uint32> m_currentThreadId;
667+
OsVariableWrapper<bool> m_inVBlank;
665668

666669
#ifdef DEBUGGER_INCLUDED
667670
BiosDebugModuleInfoArray m_moduleTags;

Source/iop/Iop_Vblank.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,7 @@ int32 CVblank::WaitVblank()
108108
#ifdef _DEBUG
109109
CLog::GetInstance().Print(LOG_NAME, FUNCTION_WAITVBLANK "();\r\n");
110110
#endif
111-
//TODO: Skip waiting if we're already in Vblank
112-
m_bios.SleepThreadTillVBlankStart();
111+
m_bios.SleepThreadTillVBlank();
113112
return 0;
114113
}
115114

@@ -118,7 +117,7 @@ int32 CVblank::WaitNonVblank()
118117
#ifdef _DEBUG
119118
CLog::GetInstance().Print(LOG_NAME, FUNCTION_WAITNONVBLANK "();\r\n");
120119
#endif
121-
m_bios.SleepThreadTillVBlankEnd();
120+
m_bios.SleepThreadTillNonVBlank();
122121
return 0;
123122
}
124123

0 commit comments

Comments
 (0)