mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-20 01:39:07 +02:00
GPU: Finish the depth raster when a list ends, before the CPU runs again
Syphon Filter reads its depth buffer back on the CPU for the light flares as soon as a list has ended, without a DrawSync, and saw it before the worker had drawn the walls, so flares behind them flickered. Now returning to the CPU after an END waits for the batches already submitted. Returning at a stall doesn't wait, as Wipeout does that about 300 times a frame. Wipeout on a Galaxy S8: 11% less wall time than before the worker (16% without the wait). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
cd59a16d85
commit
a37e1f3660
6 files changed
+29
No files matched your search
@@ -752,6 +752,10 @@ void DepthRasterWorker::Submit() {
|
||||
|
||||
void DepthRasterWorker::Wait() {
|
||||
Submit();
|
||||
WaitForSubmitted();
|
||||
}
|
||||
|
||||
void DepthRasterWorker::WaitForSubmitted() {
|
||||
if (!busy_) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -93,6 +93,8 @@ public:
|
||||
void Submit();
|
||||
// Submits the current batch and waits until all are rasterized.
|
||||
void Wait();
|
||||
// Waits until the batches already submitted are rasterized.
|
||||
void WaitForSubmitted();
|
||||
// Waits only if a batch being rasterized may write to [addr, addr + size).
|
||||
void WaitIfWriting(u32 addr, u32 size);
|
||||
|
||||
|
||||
@@ -1365,6 +1365,12 @@ void DrawEngineCommon::FlushQueuedDepth() {
|
||||
depthWorker_->TakeTimes(&gpuStats.perFrame.msCullDepth, &gpuStats.perFrame.msRasterizeDepth);
|
||||
}
|
||||
|
||||
void DrawEngineCommon::WaitForSubmittedDepth() {
|
||||
if (depthWorker_) {
|
||||
depthWorker_->WaitForSubmitted();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawEngineCommon::WaitForDepthWrites(u32 addr, u32 size) {
|
||||
if (depthWorker_) {
|
||||
depthWorker_->WaitIfWriting(addr, size);
|
||||
|
||||
@@ -164,6 +164,8 @@ public:
|
||||
void FlushQueuedDepth();
|
||||
// Starts rasterizing the queued depth draws, without waiting.
|
||||
void SubmitQueuedDepth();
|
||||
// Waits for the depth draws already submitted, leaving the queued ones queued.
|
||||
void WaitForSubmittedDepth();
|
||||
// Waits if depth rasterization in progress may write to these bytes.
|
||||
void WaitForDepthWrites(u32 addr, u32 size);
|
||||
|
||||
|
||||
@@ -908,6 +908,18 @@ 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;
|
||||
@@ -1213,6 +1225,7 @@ void GPUCommon::Execute_Ret(u32 op, u32 diff) {
|
||||
void GPUCommon::Execute_End(u32 op, u32 diff) {
|
||||
if (flushOnParams_) {
|
||||
drawEngineCommon_->SubmitQueuedDepth();
|
||||
listEndedSinceDepthWait_ = true;
|
||||
Flush();
|
||||
}
|
||||
|
||||
|
||||
@@ -316,6 +316,7 @@ public:
|
||||
void NotifyFlush();
|
||||
|
||||
protected:
|
||||
DLResult RunDLQueue();
|
||||
// While debugging is active, these may block.
|
||||
void NotifyDisplay(u32 framebuf, u32 stride, int format);
|
||||
|
||||
@@ -377,6 +378,7 @@ protected:
|
||||
TextureCacheCommon *textureCache_ = nullptr;
|
||||
|
||||
bool flushOnParams_ = true;
|
||||
bool listEndedSinceDepthWait_ = false;
|
||||
|
||||
GraphicsContext *gfxCtx_;
|
||||
Draw::DrawContext *draw_ = nullptr;
|
||||
|
||||
Reference in new issue
Block a user