-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,9 @@ | |
#include "Core.h" | ||
#include "MemMap.h" | ||
#include "MIPS/MIPS.h" | ||
#ifdef _WIN32 | ||
#include "Windows/OpenGLBase.h" | ||
#endif | ||
|
||
#include "Host.h" | ||
|
||
|
@@ -64,7 +67,16 @@ bool Core_IsStepping() | |
|
||
void Core_RunLoop() | ||
{ | ||
currentMIPS->RunLoopUntil(0xFFFFFFFFFFFFFFFULL); | ||
while (!coreState) { | ||
currentMIPS->RunLoopUntil(0xFFFFFFFFFFFFFFFULL); | ||
if (coreState == CORE_NEXTFRAME) | ||
{ | ||
#ifdef _WIN32 | ||
GL_SwapBuffers(); | ||
#endif | ||
coreState = CORE_RUNNING; | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
hrydgard
Author
Owner
|
||
} | ||
} | ||
} | ||
|
||
void Core_DoSingleStep() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,6 +80,7 @@ static bool framebufIsLatched; | |
|
||
static int enterVblankEvent = -1; | ||
static int leaveVblankEvent = -1; | ||
static int afterFlipEvent = -1; | ||
|
||
static int hCount; | ||
static int hCountTotal; //unused | ||
|
@@ -107,6 +108,7 @@ enum { | |
|
||
void hleEnterVblank(u64 userdata, int cyclesLate); | ||
void hleLeaveVblank(u64 userdata, int cyclesLate); | ||
void hleAfterFlip(u64 userdata, int cyclesLate); | ||
|
||
void __DisplayInit() { | ||
gpuStats.reset(); | ||
|
@@ -118,6 +120,7 @@ void __DisplayInit() { | |
|
||
enterVblankEvent = CoreTiming::RegisterEvent("EnterVBlank", &hleEnterVblank); | ||
leaveVblankEvent = CoreTiming::RegisterEvent("LeaveVBlank", &hleLeaveVblank); | ||
afterFlipEvent = CoreTiming::RegisterEvent("AfterFlip", &hleAfterFlip); | ||
This comment has been minimized.
Sorry, something went wrong.
unknownbrackets
Collaborator
|
||
|
||
CoreTiming::ScheduleEvent(msToCycles(frameMs - vblankMs), enterVblankEvent, 0); | ||
isVblank = 0; | ||
|
@@ -202,6 +205,93 @@ float calculateFPS() | |
return fps; | ||
} | ||
|
||
void DebugStats() | ||
{ | ||
gpu->UpdateStats(); | ||
char stats[2048]; | ||
|
||
sprintf(stats, | ||
"Frames: %i\n" | ||
"DL processing time: %0.2f ms\n" | ||
"Kernel processing time: %0.2f ms\n" | ||
"Slowest syscall: %s : %0.2f ms\n" | ||
"Most active syscall: %s : %0.2f ms\n" | ||
"Draw calls: %i, flushes %i\n" | ||
"Cached Draw calls: %i\n" | ||
"Num Tracked Vertex Arrays: %i\n" | ||
"Vertices Submitted: %i\n" | ||
"Cached Vertices Drawn: %i\n" | ||
"Uncached Vertices Drawn: %i\n" | ||
"FBOs active: %i\n" | ||
"Textures active: %i, decoded: %i\n" | ||
"Texture invalidations: %i\n" | ||
"Vertex shaders loaded: %i\n" | ||
"Fragment shaders loaded: %i\n" | ||
"Combined shaders loaded: %i\n", | ||
gpuStats.numFrames, | ||
gpuStats.msProcessingDisplayLists * 1000.0f, | ||
kernelStats.msInSyscalls * 1000.0f, | ||
kernelStats.slowestSyscallName ? kernelStats.slowestSyscallName : "(none)", | ||
kernelStats.slowestSyscallTime * 1000.0f, | ||
kernelStats.summedSlowestSyscallName ? kernelStats.summedSlowestSyscallName : "(none)", | ||
kernelStats.summedSlowestSyscallTime * 1000.0f, | ||
gpuStats.numDrawCalls, | ||
gpuStats.numFlushes, | ||
gpuStats.numCachedDrawCalls, | ||
gpuStats.numTrackedVertexArrays, | ||
gpuStats.numVertsSubmitted, | ||
gpuStats.numCachedVertsDrawn, | ||
gpuStats.numUncachedVertsDrawn, | ||
gpuStats.numFBOs, | ||
gpuStats.numTextures, | ||
gpuStats.numTexturesDecoded, | ||
gpuStats.numTextureInvalidations, | ||
gpuStats.numVertexShaders, | ||
gpuStats.numFragmentShaders, | ||
gpuStats.numShaders | ||
); | ||
|
||
float zoom = 0.3f; /// g_Config.iWindowZoom; | ||
float soff = 0.3f; | ||
PPGeBegin(); | ||
PPGeDrawText(stats, soff, soff, 0, zoom, 0xCC000000); | ||
PPGeDrawText(stats, -soff, -soff, 0, zoom, 0xCC000000); | ||
PPGeDrawText(stats, 0, 0, 0, zoom, 0xFFFFFFFF); | ||
PPGeEnd(); | ||
|
||
gpuStats.resetFrame(); | ||
kernelStats.ResetFrame(); | ||
} | ||
|
||
// Let's collect all the throttling and frameskipping logic here. | ||
void DoFrameTiming(bool &throttle) { | ||
#ifdef _WIN32 | ||
throttle = !GetAsyncKeyState(VK_TAB); | ||
#else | ||
throttle = false; | ||
#endif | ||
if (PSP_CoreParameter().headLess) | ||
throttle = false; | ||
|
||
if (throttle) { | ||
// Best place to throttle the frame rate on non vsynced platforms is probably here. Let's try it. | ||
time_update(); | ||
if (lastFrameTime == 0.0) | ||
lastFrameTime = time_now_d(); | ||
|
||
// First, check if we are already behind. | ||
// Wait until it's time. | ||
while (time_now_d() < lastFrameTime + 1.0 / 60.0) { | ||
Common::SleepCurrentThread(1); | ||
time_update(); | ||
} | ||
// Advance lastFrameTime by a constant amount each frame, | ||
// but don't let it get too far behind. | ||
lastFrameTime = std::max(lastFrameTime + 1.0 / 60.0, time_now_d() - 1.5 / 60.0); | ||
} | ||
} | ||
|
||
|
||
void hleEnterVblank(u64 userdata, int cyclesLate) { | ||
int vbCount = userdata; | ||
|
||
|
@@ -223,7 +313,7 @@ void hleEnterVblank(u64 userdata, int cyclesLate) { | |
// Trigger VBlank interrupt handlers. | ||
__TriggerInterrupt(PSP_INTR_IMMEDIATE | PSP_INTR_ONLY_IF_ENABLED | PSP_INTR_ALWAYS_RESCHED, PSP_VBLANK_INTR, PSP_INTR_SUB_ALL); | ||
|
||
CoreTiming::ScheduleEvent(msToCycles(vblankMs) - cyclesLate, leaveVblankEvent, vbCount+1); | ||
CoreTiming::ScheduleEvent(msToCycles(vblankMs) - cyclesLate, leaveVblankEvent, vbCount + 1); | ||
|
||
// TODO: Should this be done here or in hleLeaveVblank? | ||
if (framebufIsLatched) { | ||
|
@@ -233,65 +323,11 @@ void hleEnterVblank(u64 userdata, int cyclesLate) { | |
gpu->SetDisplayFramebuffer(framebuf.topaddr, framebuf.pspFramebufLinesize, framebuf.pspFramebufFormat); | ||
} | ||
|
||
// Draw screen overlays before blitting. Saves and restores the Ge context. | ||
gpuStats.numFrames++; | ||
|
||
// Now we can subvert the Ge engine in order to draw custom overlays like stat counters etc. | ||
if (g_Config.bShowDebugStats && gpuStats.numDrawCalls) { | ||
gpu->UpdateStats(); | ||
char stats[2048]; | ||
|
||
sprintf(stats, | ||
"Frames: %i\n" | ||
"DL processing time: %0.2f ms\n" | ||
"Kernel processing time: %0.2f ms\n" | ||
"Slowest syscall: %s : %0.2f ms\n" | ||
"Most active syscall: %s : %0.2f ms\n" | ||
"Draw calls: %i, flushes %i\n" | ||
"Cached Draw calls: %i\n" | ||
"Num Tracked Vertex Arrays: %i\n" | ||
"Vertices Submitted: %i\n" | ||
"Cached Vertices Drawn: %i\n" | ||
"Uncached Vertices Drawn: %i\n" | ||
"FBOs active: %i\n" | ||
"Textures active: %i, decoded: %i\n" | ||
"Texture invalidations: %i\n" | ||
"Vertex shaders loaded: %i\n" | ||
"Fragment shaders loaded: %i\n" | ||
"Combined shaders loaded: %i\n", | ||
gpuStats.numFrames, | ||
gpuStats.msProcessingDisplayLists * 1000.0f, | ||
kernelStats.msInSyscalls * 1000.0f, | ||
kernelStats.slowestSyscallName ? kernelStats.slowestSyscallName : "(none)", | ||
kernelStats.slowestSyscallTime * 1000.0f, | ||
kernelStats.summedSlowestSyscallName ? kernelStats.summedSlowestSyscallName : "(none)", | ||
kernelStats.summedSlowestSyscallTime * 1000.0f, | ||
gpuStats.numDrawCalls, | ||
gpuStats.numFlushes, | ||
gpuStats.numCachedDrawCalls, | ||
gpuStats.numTrackedVertexArrays, | ||
gpuStats.numVertsSubmitted, | ||
gpuStats.numCachedVertsDrawn, | ||
gpuStats.numUncachedVertsDrawn, | ||
gpuStats.numFBOs, | ||
gpuStats.numTextures, | ||
gpuStats.numTexturesDecoded, | ||
gpuStats.numTextureInvalidations, | ||
gpuStats.numVertexShaders, | ||
gpuStats.numFragmentShaders, | ||
gpuStats.numShaders | ||
); | ||
|
||
float zoom = 0.3f; /// g_Config.iWindowZoom; | ||
float soff = 0.3f; | ||
PPGeBegin(); | ||
PPGeDrawText(stats, soff, soff, 0, zoom, 0xCC000000); | ||
PPGeDrawText(stats, -soff, -soff, 0, zoom, 0xCC000000); | ||
PPGeDrawText(stats, 0, 0, 0, zoom, 0xFFFFFFFF); | ||
PPGeEnd(); | ||
|
||
gpuStats.resetFrame(); | ||
kernelStats.ResetFrame(); | ||
DebugStats(); | ||
} | ||
|
||
if (g_Config.bShowFPSCounter) { | ||
|
@@ -313,41 +349,32 @@ void hleEnterVblank(u64 userdata, int cyclesLate) { | |
PPGeEnd(); | ||
} | ||
|
||
// Draw screen overlays before blitting. Saves and restores the Ge context. | ||
// Yeah, this has to be the right moment to end the frame. Give the graphics backend opportunity | ||
// to blit the framebuffer, in order to support half-framerate games that otherwise wouldn't have | ||
// anything to draw here. | ||
gpu->CopyDisplayToOutput(); | ||
|
||
host->EndFrame(); | ||
|
||
#ifdef _WIN32 | ||
// Best place to throttle the frame rate on non vsynced platforms is probably here. Let's try it. | ||
time_update(); | ||
if (lastFrameTime == 0.0) | ||
lastFrameTime = time_now_d(); | ||
if (!GetAsyncKeyState(VK_TAB) && !PSP_CoreParameter().headLess) { | ||
while (time_now_d() < lastFrameTime + 1.0 / 60.0) { | ||
Common::SleepCurrentThread(1); | ||
time_update(); | ||
} | ||
// Advance lastFrameTime by a constant amount each frame, | ||
// but don't let it get too far behind. | ||
lastFrameTime = std::max(lastFrameTime + 1.0 / 60.0, time_now_d() - 1.5 / 60.0); | ||
} | ||
bool throttle; | ||
|
||
DoFrameTiming(throttle); | ||
|
||
// We are going to have to do something about audio timing for platforms that | ||
// are vsynced to something that's not exactly 60fps.. | ||
// Setting CORE_NEXTFRAME causes a swap. | ||
coreState = CORE_NEXTFRAME; | ||
|
||
CoreTiming::ScheduleEvent(0 - cyclesLate, afterFlipEvent, 0); | ||
|
||
#endif | ||
// Returning here with coreState == CORE_NEXTFRAME causes a buffer flip to happen (next frame). | ||
// Right after, we regain control for a little bit in hleAfterFlip. I think that's a great | ||
// place to do housekeeping. | ||
} | ||
|
||
void hleAfterFlip(u64 userdata, int cyclesLate) | ||
{ | ||
// This checks input on PC. Fine to do even if not calling BeginFrame. | ||
host->BeginFrame(); | ||
gpu->BeginFrame(); | ||
|
||
// Tell the emu core that it's time to stop emulating | ||
// Win32 doesn't need this. | ||
#ifndef _WIN32 | ||
coreState = CORE_NEXTFRAME; | ||
#endif | ||
gpu->BeginFrame(); // doesn't really matter if begin or end of frame. | ||
} | ||
|
||
void hleLeaveVblank(u64 userdata, int cyclesLate) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,12 +4,13 @@ | |
|
||
#include <stdio.h> | ||
|
||
#include "../Core/Config.h" | ||
#include "../Core/Core.h" | ||
#include "../Core/CoreTiming.h" | ||
#include "../Core/System.h" | ||
#include "../Core/MIPS/MIPS.h" | ||
#include "../Core/Host.h" | ||
#include "Core/Config.h" | ||
#include "Core/Core.h" | ||
#include "Core/CoreTiming.h" | ||
#include "Core/System.h" | ||
#include "Core/MIPS/MIPS.h" | ||
#include "Core/Host.h" | ||
#include "Windows/OpenGLBase.h" | ||
#include "Log.h" | ||
#include "LogManager.h" | ||
|
||
|
@@ -46,6 +47,9 @@ class PrintfLogger : public LogListener | |
} | ||
}; | ||
|
||
// Temporary hack around annoying linking error. | ||
void GL_SwapBuffers() { } | ||
This comment has been minimized.
Sorry, something went wrong.
unknownbrackets
Collaborator
|
||
|
||
void printUsage(const char *progname, const char *reason) | ||
{ | ||
if (reason != NULL) | ||
|
@@ -192,8 +196,10 @@ int main(int argc, const char* argv[]) | |
mipsr4k.RunLoopUntil(nowTicks + frameTicks); | ||
|
||
// If we were rendering, this might be a nice time to do something about it. | ||
if (coreState == CORE_NEXTFRAME) | ||
if (coreState == CORE_NEXTFRAME) { | ||
headlessHost->SwapBuffers(); | ||
coreState = CORE_RUNNING; | ||
} | ||
} | ||
|
||
host->ShutdownGL(); | ||
|
I think this should be inside the ifdef, or it'll never exit. Made Qt not draw anything, at least.
-[Unknown]