Display: Wait for vblank when setting mode.
Some games call this even when not needed, and it turns out to have an important behavior.
This commit is contained in:
parent
9ed604f9c8
commit
d0dc03f359
1 changed files with 23 additions and 20 deletions
|
@ -729,16 +729,32 @@ static u32 sceDisplayIsVblank() {
|
|||
return hleLogSuccessI(SCEDISPLAY, isVblank);
|
||||
}
|
||||
|
||||
static int DisplayWaitForVblanks(const char *reason, int vblanks, bool callbacks = false) {
|
||||
const s64 ticksIntoFrame = CoreTiming::GetTicks() - frameStartTicks;
|
||||
const s64 cyclesToNextVblank = msToCycles(frameMs) - ticksIntoFrame;
|
||||
|
||||
// These syscalls take about 115 us, so if the next vblank is before then, we're waiting extra.
|
||||
// At least, on real firmware a wait >= 16500 into the frame will wait two.
|
||||
if (cyclesToNextVblank <= usToCycles(115)) {
|
||||
++vblanks;
|
||||
}
|
||||
|
||||
vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread(), vblanks));
|
||||
__KernelWaitCurThread(WAITTYPE_VBLANK, 1, 0, 0, callbacks, reason);
|
||||
|
||||
return hleLogSuccessVerboseI(SCEDISPLAY, 0, "waiting for %d vblanks", vblanks);
|
||||
}
|
||||
|
||||
static u32 sceDisplaySetMode(int displayMode, int displayWidth, int displayHeight) {
|
||||
if (displayMode != PSP_DISPLAY_MODE_LCD || displayWidth != 480 || displayHeight != 272) {
|
||||
WARN_LOG_REPORT(SCEDISPLAY, "Video out requested, not supported: mode=%d size=%d,%d", displayMode, displayWidth, displayHeight);
|
||||
}
|
||||
if (displayWidth != 480 || displayHeight != 272) {
|
||||
return hleLogWarning(SCEDISPLAY, SCE_KERNEL_ERROR_INVALID_SIZE, "invalid size");
|
||||
}
|
||||
if (displayMode != PSP_DISPLAY_MODE_LCD) {
|
||||
return hleLogWarning(SCEDISPLAY, SCE_KERNEL_ERROR_INVALID_MODE, "invalid mode");
|
||||
}
|
||||
if (displayWidth != 480 || displayHeight != 272) {
|
||||
return hleLogWarning(SCEDISPLAY, SCE_KERNEL_ERROR_INVALID_SIZE, "invalid size");
|
||||
}
|
||||
|
||||
if (!hasSetMode) {
|
||||
gpu->InitClear();
|
||||
|
@ -747,7 +763,10 @@ static u32 sceDisplaySetMode(int displayMode, int displayWidth, int displayHeigh
|
|||
mode = displayMode;
|
||||
width = displayWidth;
|
||||
height = displayHeight;
|
||||
return hleLogSuccessI(SCEDISPLAY, 0);
|
||||
|
||||
hleLogSuccessI(SCEDISPLAY, 0);
|
||||
// On success, this implicitly waits for a vblank start.
|
||||
return DisplayWaitForVblanks("display mode", 1);
|
||||
}
|
||||
|
||||
// Some games (GTA) never call this during gameplay, so bad place to put a framerate counter.
|
||||
|
@ -860,22 +879,6 @@ static u32 sceDisplayGetFramebuf(u32 topaddrPtr, u32 linesizePtr, u32 pixelForma
|
|||
return hleLogSuccessI(SCEDISPLAY, 0);
|
||||
}
|
||||
|
||||
static int DisplayWaitForVblanks(const char *reason, int vblanks, bool callbacks = false) {
|
||||
const s64 ticksIntoFrame = CoreTiming::GetTicks() - frameStartTicks;
|
||||
const s64 cyclesToNextVblank = msToCycles(frameMs) - ticksIntoFrame;
|
||||
|
||||
// These syscalls take about 115 us, so if the next vblank is before then, we're waiting extra.
|
||||
// At least, on real firmware a wait >= 16500 into the frame will wait two.
|
||||
if (cyclesToNextVblank <= usToCycles(115)) {
|
||||
++vblanks;
|
||||
}
|
||||
|
||||
vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread(), vblanks));
|
||||
__KernelWaitCurThread(WAITTYPE_VBLANK, 1, 0, 0, callbacks, reason);
|
||||
|
||||
return hleLogSuccessVerboseI(SCEDISPLAY, 0, "waiting for %d vblanks", vblanks);
|
||||
}
|
||||
|
||||
static int DisplayWaitForVblanksCB(const char *reason, int vblanks) {
|
||||
return DisplayWaitForVblanks(reason, vblanks, true);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue