diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index b93ca87d44..ce166eebe6 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -150,6 +150,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { CheckSetting(iniFile, gameID, "ForceEnableGPUReadback", &flags_.ForceEnableGPUReadback); CheckSetting(iniFile, gameID, "UseFFMPEGFindStreamInfo", &flags_.UseFFMPEGFindStreamInfo); CheckSetting(iniFile, gameID, "SoftwareRasterDepth", &flags_.SoftwareRasterDepth); + CheckSetting(iniFile, gameID, "DepthRasterNoCallbackWait", &flags_.DepthRasterNoCallbackWait); CheckSetting(iniFile, gameID, "DisableHLESceFont", &flags_.DisableHLESceFont); CheckSetting(iniFile, gameID, "ForceHLEPsmf", &flags_.ForceHLEPsmf); CheckSetting(iniFile, gameID, "SaveStatesNotRecommended", &flags_.SaveStatesNotRecommended); diff --git a/Core/Compatibility.h b/Core/Compatibility.h index ba428d5884..647c41b9cb 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -116,6 +116,7 @@ struct CompatFlags { bool ForceEnableGPUReadback; bool UseFFMPEGFindStreamInfo; bool SoftwareRasterDepth; + bool DepthRasterNoCallbackWait; bool DisableHLESceFont; bool ForceHLEPsmf; bool SaveStatesNotRecommended; diff --git a/Core/HLE/sceGe.cpp b/Core/HLE/sceGe.cpp index 2c6cfb4cf3..f9abd35ed3 100644 --- a/Core/HLE/sceGe.cpp +++ b/Core/HLE/sceGe.cpp @@ -127,6 +127,11 @@ public: SubIntrHandler* handler = get(subintr); if (handler != NULL) { + // The callback may read the depth buffer on the CPU (light flares in Syphon Filter, Wipeout Pure + // and Resistance: Retribution), and on hardware the drawing is done by now. + if (!PSP_CoreParameter().compat.flags().DepthRasterNoCallbackWait) { + gpu->WaitForSubmittedDepth(); + } DEBUG_LOG(Log::CPU, "Entering GE interrupt handler %08x", handler->handlerAddress); currentMIPS->pc = handler->handlerAddress; u32 data = dl->subIntrToken; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 41cceebc34..a3d3d78ea3 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -942,18 +942,6 @@ inline void GPUCommon::UpdateState(GPURunState state) { // This is now called when coreState == CORE_RUNNING_GE, in addition to from the various sceGe commands. DLResult GPUCommon::ProcessDLQueue() { - const DLResult result = RunDLQueue(); - // Games read the depth buffer back on the CPU once a list has ended, without waiting for the GE - // (Syphon Filter's light flares). So the depth rasterizer has to be done by then. Not at a stall, - // though, which some games hit hundreds of times a frame. - if (listEndedSinceDepthWait_) { - listEndedSinceDepthWait_ = false; - drawEngineCommon_->WaitForSubmittedDepth(); - } - return result; -} - -DLResult GPUCommon::RunDLQueue() { if (!resumingFromDebugBreak_) { startingTicks = CoreTiming::GetTicks(currentMIPS); cyclesExecuted = 0; @@ -1259,7 +1247,6 @@ void GPUCommon::Execute_Ret(u32 op, u32 diff) { void GPUCommon::Execute_End(u32 op, u32 diff) { if (flushOnParams_) { drawEngineCommon_->SubmitQueuedDepth(); - listEndedSinceDepthWait_ = true; Flush(); } @@ -2110,6 +2097,10 @@ void GPUCommon::DoState(PointerWrap &p) { } } +void GPUCommon::WaitForSubmittedDepth() { + drawEngineCommon_->WaitForSubmittedDepth(); +} + void GPUCommon::InterruptStart(int listid) { interruptRunning = true; } diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index b8f71d7d51..4346bf1a0f 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -102,6 +102,7 @@ public: virtual void EndHostFrame(); void InterruptStart(int listid); + void WaitForSubmittedDepth(); void InterruptEnd(int listid); void SyncEnd(GPUSyncType waitType, int listid, bool wokeThreads); void EnableInterrupts(bool enable) { @@ -341,7 +342,6 @@ public: void NotifyFlush(); protected: - DLResult RunDLQueue(); // While debugging is active, these may block. void NotifyDisplay(u32 framebuf, u32 stride, int format); @@ -403,7 +403,6 @@ protected: TextureCacheCommon *textureCache_ = nullptr; bool flushOnParams_ = true; - bool listEndedSinceDepthWait_ = false; GraphicsContext *gfxCtx_; Draw::DrawContext *draw_ = nullptr; diff --git a/assets/compat.ini b/assets/compat.ini index b9b215d854..db1ae469c5 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -1794,6 +1794,15 @@ NPEH00047 = true ULES00554 = true ULUS10174 = true +[DepthRasterNoCallbackWait] +# Without this, the CPU waits for the depth rasterizer before a GE interrupt callback runs, for games that +# read the depth buffer back there (the light flares in Syphon Filter, Wipeout Pure and Resistance: +# Retribution). These only read it after a sceGeDrawSync or sceGeListSync, which waits anyway. + +# L.A. Rush (sun lens flare) +ULES00554 = true +ULUS10174 = true + [BlockTransferDepth] # Iron Man - see issue #16530 # Note that this option also requires IntraVRAMBlockTransferAllowCreateFB.