softgpu: Explicitly flush on sync and output.

We could in theory skip flush on FinishDeferred, and allow some CPU/GPU
overlap.  If we did, we'd still want to flush at these times.
This commit is contained in:
Unknown W. Brackets 2022-09-17 16:28:15 -07:00
parent f740fcdbe7
commit 028a341cc8
4 changed files with 24 additions and 0 deletions

View File

@ -639,6 +639,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
}
void SoftGPU::CopyDisplayToOutput(bool reallyDirty) {
drawEngine_->transformUnit.Flush("output");
// The display always shows 480x272.
CopyToCurrentFboFromDisplayRam(FB_WIDTH, FB_HEIGHT);
MarkDirty(displayFramebuf_, displayStride_, 272, displayFormat_, SoftGPUVRAMDirty::CLEAR);
@ -1138,6 +1139,18 @@ void SoftGPU::FinishDeferred() {
drawEngine_->transformUnit.Flush("finish");
}
int SoftGPU::ListSync(int listid, int mode) {
// Take this as a cue that we need to finish drawing.
drawEngine_->transformUnit.Flush("listsync");
return GPUCommon::ListSync(listid, mode);
}
u32 SoftGPU::DrawSync(int mode) {
// Take this as a cue that we need to finish drawing.
drawEngine_->transformUnit.Flush("drawsync");
return GPUCommon::DrawSync(mode);
}
void SoftGPU::GetStats(char *buffer, size_t bufsize) {
drawEngine_->transformUnit.GetStats(buffer, bufsize);
}

View File

@ -131,6 +131,8 @@ public:
void InitClear() override {}
void ExecuteOp(u32 op, u32 diff) override;
void FinishDeferred() override;
int ListSync(int listid, int mode) override;
u32 DrawSync(int mode) override;
void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) override;
void CopyDisplayToOutput(bool reallyDirty) override;

View File

@ -484,6 +484,7 @@ void TransformUnit::SubmitPrimitive(const void* vertices, const void* indices, G
// then resolve the indices. This lets us avoid transforming shared vertices twice.
binner_->UpdateState(vreader.isThrough());
hasDraws_ = true;
static TransformState transformState;
if (binner_->HasDirty(SoftDirty::LIGHT_ALL | SoftDirty::TRANSFORM_ALL)) {
@ -826,8 +827,12 @@ void TransformUnit::SendTriangle(CullType cullType, const VertexData *verts, int
}
void TransformUnit::Flush(const char *reason) {
if (!hasDraws_)
return;
binner_->Flush(reason);
GPUDebug::NotifyDraw();
hasDraws_ = false;
}
void TransformUnit::GetStats(char *buffer, size_t bufsize) {
@ -836,6 +841,9 @@ void TransformUnit::GetStats(char *buffer, size_t bufsize) {
}
void TransformUnit::FlushIfOverlap(const char *reason, bool modifying, uint32_t addr, uint32_t stride, uint32_t w, uint32_t h) {
if (!hasDraws_)
return;
if (binner_->HasPendingWrite(addr, stride, w, h))
Flush(reason);
if (modifying && binner_->HasPendingRead(addr, stride, w, h))

View File

@ -149,6 +149,7 @@ private:
// This is the index of the next vert in data (or higher, may need modulus.)
int data_index_ = 0;
GEPrimitiveType prev_prim_ = GE_PRIM_POINTS;
bool hasDraws_ = false;
};
class SoftwareDrawEngine : public DrawEngineCommon {