mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-29 04:08:55 +00:00
My first commit :D
Dual Core sync fix. When the FIFO is processing data we must not advance the cpu cycles in CoreTiming because in this way the VI will be desynchronized. So, We are waiting until the FIFO finish and while we process only the events required by the FIFO. This should fix Issue 2072 . This affect to all games in dual core mode. Please, You can test all games with VPS limiter auto, 60, 50 depending of the game and compare with prev revision. For example now NSMB in the video Intro has 60 fps (prev 30 fps) :D or SMG does't need anymore FPS Limitter Hack to get 55-60 fps Beside the slowdowns now are more softly and the fps more stables because the VI sync is almost perfect. The Core Timing and Fifo modifications are delicated. Please report if this hang any game. Don't forget check with prev revision. Enjoy it! Thanks to Rodolfo for teach me all about dolphin. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5777 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
2faae384b3
commit
10b5d2371c
15 changed files with 112 additions and 22 deletions
|
@ -22,6 +22,7 @@
|
|||
#include "CoreTiming.h"
|
||||
#include "Core.h"
|
||||
#include "StringUtil.h"
|
||||
#include "PluginManager.h"
|
||||
|
||||
#define MAX_SLICE_LENGTH 20000
|
||||
|
||||
|
@ -41,6 +42,7 @@ struct BaseEvent
|
|||
s64 time;
|
||||
u64 userdata;
|
||||
int type;
|
||||
bool fifoWait;
|
||||
// Event *next;
|
||||
};
|
||||
|
||||
|
@ -208,7 +210,7 @@ u64 GetIdleTicks()
|
|||
|
||||
// This is to be called when outside threads, such as the graphics thread, wants to
|
||||
// schedule things to be executed on the main thread.
|
||||
void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata)
|
||||
void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata, bool fifoWait)
|
||||
{
|
||||
externalEventSection.Enter();
|
||||
Event *ne = GetNewTsEvent();
|
||||
|
@ -216,6 +218,7 @@ void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata
|
|||
ne->type = event_type;
|
||||
ne->next = 0;
|
||||
ne->userdata = userdata;
|
||||
ne->fifoWait = fifoWait;
|
||||
if(!tsFirst)
|
||||
tsFirst = ne;
|
||||
if(tsLast)
|
||||
|
@ -235,7 +238,7 @@ void ScheduleEvent_Threadsafe_Immediate(int event_type, u64 userdata)
|
|||
externalEventSection.Leave();
|
||||
}
|
||||
else
|
||||
ScheduleEvent_Threadsafe(0, event_type, userdata);
|
||||
ScheduleEvent_Threadsafe(0, event_type, userdata, false);
|
||||
}
|
||||
|
||||
void ClearPendingEvents()
|
||||
|
@ -275,7 +278,7 @@ void ScheduleEvent(int cyclesIntoFuture, int event_type, u64 userdata)
|
|||
ne->userdata = userdata;
|
||||
ne->type = event_type;
|
||||
ne->time = globalTimer + cyclesIntoFuture;
|
||||
|
||||
ne->fifoWait = false;
|
||||
AddEventToQueue(ne);
|
||||
}
|
||||
|
||||
|
@ -337,8 +340,33 @@ void ResetSliceLength()
|
|||
maxSliceLength = MAX_SLICE_LENGTH;
|
||||
}
|
||||
|
||||
void Advance()
|
||||
{
|
||||
|
||||
//This raise only the events required while the fifo is processing data
|
||||
void ProcessFifoWaitEvents()
|
||||
{
|
||||
MoveEvents();
|
||||
|
||||
while (first)
|
||||
{
|
||||
if ((first->time <= globalTimer) && first->fifoWait)
|
||||
{
|
||||
|
||||
Event* evt = first;
|
||||
first = first->next;
|
||||
event_types[evt->type].callback(evt->userdata, (int)(globalTimer - evt->time));
|
||||
FreeEvent(evt);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MoveEvents()
|
||||
{
|
||||
|
||||
externalEventSection.Enter();
|
||||
// Move events from async queue into main queue
|
||||
while (tsFirst)
|
||||
|
@ -360,6 +388,13 @@ void Advance()
|
|||
}
|
||||
externalEventSection.Leave();
|
||||
|
||||
}
|
||||
|
||||
void Advance()
|
||||
{
|
||||
|
||||
MoveEvents();
|
||||
|
||||
int cyclesExecuted = slicelength - downcount;
|
||||
globalTimer += cyclesExecuted;
|
||||
downcount = slicelength;
|
||||
|
@ -410,6 +445,15 @@ void Idle()
|
|||
{
|
||||
//DEBUG_LOG(POWERPC, "Idle");
|
||||
|
||||
//When the FIFO is processing data we must not advance because in this way
|
||||
//the VI will be desynchronized. So, We are waiting until the FIFO finish and
|
||||
//while we process only the events required by the FIFO.
|
||||
while (CPluginManager::GetInstance().GetVideo()->Video_IsFifoBusy())
|
||||
{
|
||||
ProcessFifoWaitEvents();
|
||||
Common::YieldCPU();
|
||||
}
|
||||
|
||||
idledCycles += downcount;
|
||||
downcount = 0;
|
||||
|
||||
|
|
|
@ -57,13 +57,15 @@ void UnregisterAllEvents();
|
|||
// userdata MAY NOT CONTAIN POINTERS. userdata might get written and reloaded from disk,
|
||||
// when we implement state saves.
|
||||
void ScheduleEvent(int cyclesIntoFuture, int event_type, u64 userdata=0);
|
||||
void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata=0);
|
||||
void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata=0, bool fifoWait=false);
|
||||
void ScheduleEvent_Threadsafe_Immediate(int event_type, u64 userdata=0);
|
||||
|
||||
// We only permit one event of each type in the queue at a time.
|
||||
void RemoveEvent(int event_type);
|
||||
bool IsScheduled(int event_type);
|
||||
void Advance();
|
||||
void MoveEvents();
|
||||
void ProcessFifoWaitEvents();
|
||||
|
||||
// Pretend that the main CPU has executed enough cycles to reach the next event.
|
||||
void Idle();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue