Skip to content

Commit 1325653

Browse files
authored
Merge branch 'hrydgard:master' into master
2 parents 464028b + 9119942 commit 1325653

40 files changed

+953
-687
lines changed

Common/GPU/Vulkan/VulkanRenderManager.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,15 @@ bool VKRGraphicsPipeline::Create(VulkanContext *vulkan, VkRenderPass compatibleR
129129
double taken_ms_since_scheduling = (now - scheduleTime) * 1000.0;
130130
double taken_ms = (now - start) * 1000.0;
131131

132+
#ifndef _DEBUG
132133
if (taken_ms < 0.1) {
133134
DEBUG_LOG(Log::G3D, "Pipeline (x/%d) time on %s: %0.2f ms, %0.2f ms since scheduling (fast) rpType: %04x sampleBits: %d (%s)",
134135
countToCompile, GetCurrentThreadName(), taken_ms, taken_ms_since_scheduling, (u32)rpType, (u32)sampleCount, tag_.c_str());
135136
} else {
136137
INFO_LOG(Log::G3D, "Pipeline (x/%d) time on %s: %0.2f ms, %0.2f ms since scheduling rpType: %04x sampleBits: %d (%s)",
137138
countToCompile, GetCurrentThreadName(), taken_ms, taken_ms_since_scheduling, (u32)rpType, (u32)sampleCount, tag_.c_str());
138139
}
140+
#endif
139141

140142
bool success = true;
141143
if (result == VK_INCOMPLETE) {

Common/Log.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ enum class Log {
4848
HTTP,
4949
Printf,
5050
TexReplacement,
51+
GeDebugger,
5152

5253
sceAudio,
5354
sceCtrl,

Common/Log/LogManager.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -89,21 +89,21 @@ static const char * const g_logTypeNames[] = {
8989
"HTTP",
9090
"PRINTF",
9191
"TEXREPLACE",
92-
93-
"SCEAUDIO",
94-
"SCECTRL",
95-
"SCEDISP",
96-
"SCEFONT",
97-
"SCEGE",
98-
"SCEINTC",
99-
"SCEIO",
100-
"SCEKERNEL",
101-
"SCEMODULE",
102-
"SCENET",
103-
"SCERTC",
104-
"SCESAS",
105-
"SCEUTIL",
106-
"SCEMISC",
92+
"DEBUGGER",
93+
"SCEAUDIO",
94+
"SCECTRL",
95+
"SCEDISP",
96+
"SCEFONT",
97+
"SCEGE",
98+
"SCEINTC",
99+
"SCEIO",
100+
"SCEKERNEL",
101+
"SCEMODULE",
102+
"SCENET",
103+
"SCERTC",
104+
"SCESAS",
105+
"SCEUTIL",
106+
"SCEMISC",
107107
};
108108

109109
void LogManager::Init(bool *enabledSetting, bool headless) {

Core/Compatibility.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ void Compatibility::Load(const std::string &gameID) {
7474
void Compatibility::Clear() {
7575
memset(&flags_, 0, sizeof(flags_));
7676
memset(&vrCompat_, 0, sizeof(vrCompat_));
77+
activeList_.clear();
7778
}
7879

7980
void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) {
@@ -163,18 +164,26 @@ void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, co
163164
// Shortcut for debugging, sometimes useful to globally enable compat flags.
164165
bool all = false;
165166
iniFile.Get(option, "ALL", &all, false);
166-
*flag |= all;
167+
if (all) {
168+
*flag |= all;
169+
if (!activeList_.empty()) {
170+
activeList_ += "\n";
171+
}
172+
activeList_ += option;
173+
}
167174
}
168175
}
169176

170177
void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, float *flag) {
171178
std::string value;
172-
iniFile.Get(option, gameID.c_str(), &value, "0");
173-
*flag = stof(value);
179+
if (iniFile.Get(option, gameID.c_str(), &value, "0")) {
180+
*flag = stof(value);
181+
}
174182
}
175183

176184
void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, int *flag) {
177185
std::string value;
178-
iniFile.Get(option, gameID.c_str(), &value, "0");
179-
*flag = stof(value);
186+
if (iniFile.Get(option, gameID.c_str(), &value, "0")) {
187+
*flag = stof(value);
188+
}
180189
}

Core/Compatibility.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ class Compatibility {
139139

140140
void Load(const std::string &gameID);
141141

142+
const std::string &GetActiveFlagsString() const {
143+
return activeList_;
144+
}
145+
142146
private:
143147
void Clear();
144148
void CheckSettings(IniFile &iniFile, const std::string &gameID);
@@ -150,4 +154,5 @@ class Compatibility {
150154
CompatFlags flags_{};
151155
VRCompat vrCompat_{};
152156
std::set<std::string> ignored_;
157+
std::string activeList_;
153158
};

Core/Config.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,13 @@ struct Config {
7070
bool bFirstRun;
7171
bool bGameSpecific = false;
7272
bool bUpdatedInstanceCounter = false;
73+
bool bBrowse; // show a file browser on startup. TODO: Does anyone use this?
7374

7475
int iRunCount; // To be used to for example check for updates every 10 runs and things like that.
7576

77+
// Debugger
7678
bool bAutoRun; // start immediately
77-
bool bBrowse; // when opening the emulator, immediately show a file browser
79+
bool bBreakOnFrameTimeout; // not saved
7880

7981
// General
8082
bool bScreenshotsAsPNG;

Core/Core.cpp

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static bool g_breakAfterFrame = false;
9090
static MIPSExceptionInfo g_exceptionInfo;
9191

9292
// This is called on EmuThread before RunLoop.
93-
static void Core_ProcessStepping(MIPSDebugInterface *cpu);
93+
static bool Core_ProcessStepping(MIPSDebugInterface *cpu);
9494

9595
void Core_SetGraphicsContext(GraphicsContext *ctx) {
9696
PSP_CoreParameter().graphicsContext = ctx;
@@ -173,8 +173,10 @@ void Core_RunLoopUntil(u64 globalticks) {
173173
return;
174174
case CORE_STEPPING_CPU:
175175
case CORE_STEPPING_GE:
176-
Core_ProcessStepping(currentDebugMIPS);
177-
return;
176+
if (Core_ProcessStepping(currentDebugMIPS)) {
177+
return;
178+
}
179+
break;
178180
case CORE_RUNNING_CPU:
179181
mipsr4k.RunLoopUntil(globalticks);
180182
if (g_breakAfterFrame && coreState == CORE_NEXTFRAME) {
@@ -327,7 +329,7 @@ static void Core_PerformCPUStep(MIPSDebugInterface *cpu, CPUStepType stepType, i
327329
}
328330
}
329331

330-
static void Core_ProcessStepping(MIPSDebugInterface *cpu) {
332+
static bool Core_ProcessStepping(MIPSDebugInterface *cpu) {
331333
Core_StateProcessed();
332334

333335
// Check if there's any pending save state actions.
@@ -336,17 +338,23 @@ static void Core_ProcessStepping(MIPSDebugInterface *cpu) {
336338
switch (coreState) {
337339
case CORE_STEPPING_CPU:
338340
case CORE_STEPPING_GE:
341+
case CORE_RUNNING_GE:
339342
// All good
340343
break;
341344
default:
342345
// Nothing to do.
343-
return;
346+
return true;
344347
}
345348

346349
// Or any GPU actions.
347350
// Legacy stepping code.
348351
GPUStepping::ProcessStepping();
349352

353+
if (coreState == CORE_RUNNING_GE) {
354+
// Retry, to get it done this frame.
355+
return false;
356+
}
357+
350358
// We're not inside jit now, so it's safe to clear the breakpoints.
351359
static int lastSteppingCounter = -1;
352360
if (lastSteppingCounter != steppingCounter) {
@@ -360,7 +368,7 @@ static void Core_ProcessStepping(MIPSDebugInterface *cpu) {
360368
std::lock_guard<std::mutex> guard(g_stepMutex);
361369

362370
if (coreState != CORE_STEPPING_CPU || g_cpuStepCommand.empty()) {
363-
return;
371+
return true;
364372
}
365373

366374
Core_ResetException();
@@ -377,6 +385,7 @@ static void Core_ProcessStepping(MIPSDebugInterface *cpu) {
377385

378386
// Update disasm dialog.
379387
System_Notify(SystemNotification::MEM_VIEW);
388+
return true;
380389
}
381390

382391
// Free-threaded (hm, possibly except tracing).
@@ -415,7 +424,10 @@ void Core_Break(const char *reason, u32 relatedAddress) {
415424
// Free-threaded (or at least should be)
416425
void Core_Resume() {
417426
// If the current PC is on a breakpoint, the user doesn't want to do nothing.
418-
g_breakpoints.SetSkipFirst(currentMIPS->pc);
427+
if (currentMIPS) {
428+
g_breakpoints.SetSkipFirst(currentMIPS->pc);
429+
}
430+
419431
// Handle resuming from GE.
420432
if (coreState == CORE_STEPPING_GE) {
421433
coreState = CORE_RUNNING_GE;
@@ -430,12 +442,20 @@ void Core_Resume() {
430442

431443
// Should be called from the EmuThread.
432444
bool Core_NextFrame() {
445+
CoreState coreState = ::coreState;
446+
433447
_dbg_assert_(coreState != CORE_STEPPING_GE && coreState != CORE_RUNNING_GE);
434448

435449
if (coreState == CORE_RUNNING_CPU) {
436-
coreState = CORE_NEXTFRAME;
450+
::coreState = CORE_NEXTFRAME;
451+
return true;
452+
} else if (coreState == CORE_STEPPING_CPU) {
453+
// All good, just stepping through so no need to switch to the NextFrame coreState though, that'd
454+
// just lose our stepping state.
455+
INFO_LOG(Log::System, "Reached end-of-frame while stepping the CPU (this is ok)");
437456
return true;
438457
} else {
458+
ERROR_LOG(Log::System, "Core_NextFrame called with wrong core state %s", CoreStateToString(coreState));
439459
return false;
440460
}
441461
}

Core/Core.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
class GraphicsContext;
2828

29-
// For platforms that don't call Core_Run
29+
// For platforms that don't call Run
3030
void Core_SetGraphicsContext(GraphicsContext *ctx);
3131

3232
// Returns false when an UI exit state is detected.

Core/HLE/HLETables.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ const HLEFunction FakeSysCalls[] = {
9797
{NID_EXTENDRETURN, __KernelReturnFromExtendStack, "__KernelReturnFromExtendStack", 'x', ""},
9898
{NID_MODULERETURN, __KernelReturnFromModuleFunc, "__KernelReturnFromModuleFunc", 'x', ""},
9999
{NID_IDLE, __KernelIdle, "_sceKernelIdle", 'x', ""},
100-
{NID_GPUREPLAY, __KernelGPUReplay, "__KernelGPUReplay", 'x', ""},
100+
{NID_GPUREPLAY, &WrapI_V<__KernelGPUReplay>, "__KernelGPUReplay", 'x', ""},
101101
{NID_HLECALLRETURN, HLEReturnFromMipsCall, "HLEReturnFromMipsCall", 'x', ""},
102102
};
103103

Core/HLE/sceKernelModule.cpp

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,37 +1984,17 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str
19841984
bool __KernelLoadGEDump(const std::string &base_filename, std::string *error_string) {
19851985
__KernelLoadReset();
19861986

1987-
mipsr4k.pc = PSP_GetUserMemoryBase();
1988-
1989-
const static u32_le runDumpCode[] = {
1990-
// Save the filename.
1991-
MIPS_MAKE_ORI(MIPS_REG_S0, MIPS_REG_A0, 0),
1992-
MIPS_MAKE_ORI(MIPS_REG_S1, MIPS_REG_A1, 0),
1993-
// Call the actual render.
1994-
MIPS_MAKE_SYSCALL("FakeSysCalls", "__KernelGPUReplay"),
1995-
// Make sure we don't get out of sync.
1996-
MIPS_MAKE_LUI(MIPS_REG_A0, 0),
1997-
MIPS_MAKE_SYSCALL("sceGe_user", "sceGeDrawSync"),
1998-
// Set the return address after the entry which saved the filename.
1999-
MIPS_MAKE_LUI(MIPS_REG_RA, mipsr4k.pc >> 16),
2000-
MIPS_MAKE_ADDIU(MIPS_REG_RA, MIPS_REG_RA, 8),
2001-
// Wait for the next vblank to render again.
2002-
MIPS_MAKE_JR_RA(),
2003-
MIPS_MAKE_SYSCALL("sceDisplay", "sceDisplayWaitVblankStart"),
2004-
// This never gets reached, just here to be safe.
2005-
MIPS_MAKE_BREAK(0),
2006-
};
1987+
const u32 codeStartAddr = PSP_GetUserMemoryBase();
1988+
mipsr4k.pc = codeStartAddr;
20071989

2008-
for (size_t i = 0; i < ARRAY_SIZE(runDumpCode); ++i) {
2009-
Memory::WriteUnchecked_U32(runDumpCode[i], mipsr4k.pc + (u32)i * sizeof(u32_le));
2010-
}
1990+
GPURecord::WriteRunDumpCode(codeStartAddr);
20111991

20121992
PSPModule *module = new PSPModule();
20131993
kernelObjects.Create(module);
20141994
loadedModules.insert(module->GetUID());
20151995
memset(&module->nm, 0, sizeof(module->nm));
20161996
module->isFake = true;
2017-
module->nm.entry_addr = mipsr4k.pc;
1997+
module->nm.entry_addr = codeStartAddr;
20181998
module->nm.gp_value = -1;
20191999

20202000
SceUID threadID = __KernelSetupRootThread(module->GetUID(), (int)base_filename.size(), base_filename.data(), 0x20, 0x1000, 0);
@@ -2024,17 +2004,20 @@ bool __KernelLoadGEDump(const std::string &base_filename, std::string *error_str
20242004
return true;
20252005
}
20262006

2027-
void __KernelGPUReplay() {
2007+
int __KernelGPUReplay() {
20282008
// Special ABI: s0 and s1 are the "args". Not null terminated.
20292009
const char *filenamep = Memory::GetCharPointer(currentMIPS->r[MIPS_REG_S1]);
20302010
if (!filenamep) {
2031-
ERROR_LOG(Log::G3D, "Failed to load dump filename");
2011+
ERROR_LOG(Log::G3D, "__KernelGPUReplay: Failed to load dump filename");
20322012
Core_Stop();
2033-
return;
2013+
return 0;
20342014
}
20352015

20362016
std::string filename(filenamep, currentMIPS->r[MIPS_REG_S0]);
2037-
if (!GPURecord::RunMountedReplay(filename)) {
2017+
GPURecord::ReplayResult result = GPURecord::RunMountedReplay(filename);
2018+
2019+
if (result == GPURecord::ReplayResult::Error) {
2020+
ERROR_LOG(Log::G3D, "__KernelGPUReplay: Failed running replay.");
20382021
Core_Stop();
20392022
}
20402023

@@ -2045,6 +2028,9 @@ void __KernelGPUReplay() {
20452028
System_SendDebugScreenshot(std::string((const char *)&topaddr[0], linesize * 272), 272);
20462029
Core_Stop();
20472030
}
2031+
2032+
// Return 0 for normal looping, 1 for break.
2033+
return result == GPURecord::ReplayResult::Break ? 1 : 0;
20482034
}
20492035

20502036
int sceKernelLoadExec(const char *filename, u32 paramPtr)

0 commit comments

Comments
 (0)