diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index ae7f6e70a6..e4e6c844b5 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -287,7 +287,7 @@ void GetFramebufferHeuristicInputs(FramebufferHeuristicParams *params, const GPU } VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const FramebufferHeuristicParams ¶ms, u32 skipDrawReason) { - gstate_c.framebufChanged = false; + gstate_c.Clean(DIRTY_FRAMEBUF); // Collect all parameters. This whole function has really become a cesspool of heuristics... // but it appears that's what it takes, unless we emulate VRAM layout more accurately somehow. diff --git a/GPU/Common/ShaderCommon.h b/GPU/Common/ShaderCommon.h index 1e709affaa..fb513c6455 100644 --- a/GPU/Common/ShaderCommon.h +++ b/GPU/Common/ShaderCommon.h @@ -87,6 +87,9 @@ enum : uint64_t { DIRTY_ALL_UNIFORMS = 0x1FFFFFFFFFULL, + // Other dirty elements that aren't uniforms! + DIRTY_FRAMEBUF = 1ULL << 40, + // Now we can add further dirty flags that are not uniforms. DIRTY_ALL = 0xFFFFFFFFFFFFFFFF diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index 94caae8ba1..180dc9c5ff 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -1303,7 +1303,7 @@ namespace DX9 { // TODO: It's really bad that we are calling SetRenderFramebuffer here with // all the irrelevant state checking it'll use to decide what to do. Should // do something more focused here. - SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason); + SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); transformDraw_->Flush(); } diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 6fb81eab10..322eb147c3 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -754,7 +754,7 @@ void GPU_DX9::Execute_Prim(u32 op, u32 diff) { } // This also make skipping drawing very effective. - framebufferManagerDX9_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason); + framebufferManagerDX9_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { drawEngine_.SetupVertexDecoder(gstate.vertType); // Rough estimate, not sure what's correct. @@ -801,7 +801,7 @@ void GPU_DX9::Execute_Prim(u32 op, u32 diff) { void GPU_DX9::Execute_Bezier(u32 op, u32 diff) { // This also make skipping drawing very effective. - framebufferManagerDX9_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason); + framebufferManagerDX9_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { // TODO: Should this eat some cycles? Probably yes. Not sure if important. return; @@ -844,7 +844,7 @@ void GPU_DX9::Execute_Bezier(u32 op, u32 diff) { void GPU_DX9::Execute_Spline(u32 op, u32 diff) { // This also make skipping drawing very effective. - framebufferManagerDX9_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason); + framebufferManagerDX9_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { // TODO: Should this eat some cycles? Probably yes. Not sure if important. return; @@ -889,7 +889,7 @@ void GPU_DX9::Execute_Spline(u32 op, u32 diff) { } void GPU_DX9::Execute_ViewportType(u32 op, u32 diff) { - gstate_c.framebufChanged = true; + gstate_c.Dirty(DIRTY_FRAMEBUF); gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; switch (op >> 24) { case GE_CMD_VIEWPORTZSCALE: @@ -900,17 +900,17 @@ void GPU_DX9::Execute_ViewportType(u32 op, u32 diff) { } void GPU_DX9::Execute_Region(u32 op, u32 diff) { - gstate_c.framebufChanged = true; + gstate_c.Dirty(DIRTY_FRAMEBUF); gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; } void GPU_DX9::Execute_Scissor(u32 op, u32 diff) { - gstate_c.framebufChanged = true; + gstate_c.Dirty(DIRTY_FRAMEBUF); gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; } void GPU_DX9::Execute_FramebufType(u32 op, u32 diff) { - gstate_c.framebufChanged = true; + gstate_c.Dirty(DIRTY_FRAMEBUF); gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; } diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 11d36e7a7c..120f403e12 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -1962,7 +1962,7 @@ void FramebufferManagerGLES::FlushBeforeCopy() { // TODO: It's really bad that we are calling SetRenderFramebuffer here with // all the irrelevant state checking it'll use to decide what to do. Should // do something more focused here. - SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason); + SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); transformDraw_->Flush(); } diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index f8ee52b7aa..05f28f6551 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -921,7 +921,7 @@ void GPU_GLES::Execute_Prim(u32 op, u32 diff) { } // This also makes skipping drawing very effective. - framebufferManagerGL_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason); + framebufferManagerGL_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { drawEngine_.SetupVertexDecoder(gstate.vertType); // Rough estimate, not sure what's correct. @@ -989,7 +989,7 @@ void GPU_GLES::Execute_VertexTypeSkinning(u32 op, u32 diff) { void GPU_GLES::Execute_Bezier(u32 op, u32 diff) { // This also make skipping drawing very effective. - framebufferManagerGL_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason); + framebufferManagerGL_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { // TODO: Should this eat some cycles? Probably yes. Not sure if important. return; @@ -1043,7 +1043,7 @@ void GPU_GLES::Execute_Bezier(u32 op, u32 diff) { void GPU_GLES::Execute_Spline(u32 op, u32 diff) { // This also make skipping drawing very effective. - framebufferManagerGL_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason); + framebufferManagerGL_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { // TODO: Should this eat some cycles? Probably yes. Not sure if important. return; @@ -1111,27 +1111,27 @@ void GPU_GLES::Execute_Spline(u32 op, u32 diff) { } void GPU_GLES::Execute_Region(u32 op, u32 diff) { - gstate_c.framebufChanged = true; + gstate_c.Dirty(DIRTY_FRAMEBUF); gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; } void GPU_GLES::Execute_Scissor(u32 op, u32 diff) { - gstate_c.framebufChanged = true; + gstate_c.Dirty(DIRTY_FRAMEBUF); gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; } void GPU_GLES::Execute_FramebufType(u32 op, u32 diff) { - gstate_c.framebufChanged = true; + gstate_c.Dirty(DIRTY_FRAMEBUF); gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; } void GPU_GLES::Execute_ViewportType(u32 op, u32 diff) { - gstate_c.framebufChanged = true; + gstate_c.Dirty(DIRTY_FRAMEBUF); gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; } void GPU_GLES::Execute_ViewportZType(u32 op, u32 diff) { - gstate_c.framebufChanged = true; + gstate_c.Dirty(DIRTY_FRAMEBUF); gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; gstate_c.DirtyUniform(DIRTY_DEPTHRANGE); } diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 6c05dc0fa2..76b6fdcdf0 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1071,7 +1071,7 @@ void GPUCommon::Execute_End(u32 op, u32 diff) { void GPUCommon::Execute_Bezier(u32 op, u32 diff) { // This also make skipping drawing very effective. - framebufferManager_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason); + framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { // TODO: Should this eat some cycles? Probably yes. Not sure if important. return; @@ -1114,7 +1114,7 @@ void GPUCommon::Execute_Bezier(u32 op, u32 diff) { void GPUCommon::Execute_Spline(u32 op, u32 diff) { // This also make skipping drawing very effective. - framebufferManager_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason); + framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { // TODO: Should this eat some cycles? Probably yes. Not sure if important. return; diff --git a/GPU/GPUState.cpp b/GPU/GPUState.cpp index f63eac714c..78b2687936 100644 --- a/GPU/GPUState.cpp +++ b/GPU/GPUState.cpp @@ -219,7 +219,6 @@ void GPUStateCache::DoState(PointerWrap &p) { textureChanged = TEXCHANGE_UPDATED; textureFullAlpha = old.textureFullAlpha; vertexFullAlpha = old.vertexFullAlpha; - framebufChanged = old.framebufChanged; skipDrawReason = old.skipDrawReason; uv = old.uv; } else { @@ -230,6 +229,7 @@ void GPUStateCache::DoState(PointerWrap &p) { p.Do(textureChanged); p.Do(textureFullAlpha); p.Do(vertexFullAlpha); + bool framebufChanged; // legacy p.Do(framebufChanged); p.Do(skipDrawReason); diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 53b69ff0bb..8e99b6c31e 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -492,9 +492,18 @@ struct GPUStateCache { void DirtyUniform(u64 what) { dirty |= what; } + void Dirty(u64 what) { + dirty |= what; + } void CleanUniforms() { dirty &= ~DIRTY_ALL_UNIFORMS; } + void Clean(u64 what) { + dirty &= ~what; + } + bool IsDirty(u64 what) const { + return (dirty & what) != 0ULL; + } u32 featureFlags; @@ -508,7 +517,6 @@ struct GPUStateCache { bool textureFullAlpha; bool textureSimpleAlpha; bool vertexFullAlpha; - bool framebufChanged; int skipDrawReason; diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index c858adfed2..217e1a0dc2 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -1628,7 +1628,7 @@ void FramebufferManagerVulkan::FlushBeforeCopy() { // TODO: It's really bad that we are calling SetRenderFramebuffer here with // all the irrelevant state checking it'll use to decide what to do. Should // do something more focused here. - SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason); + SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); drawEngine_->Flush(curCmd_); } diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 6aa99d18d0..4eab1a2447 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -778,7 +778,7 @@ void GPU_Vulkan::Execute_Prim(u32 op, u32 diff) { } // This also makes skipping drawing very effective. - framebufferManager_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason); + framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { drawEngine_.SetupVertexDecoder(gstate.vertType); @@ -829,7 +829,7 @@ void GPU_Vulkan::Execute_VertexType(u32 op, u32 diff) { void GPU_Vulkan::Execute_Bezier(u32 op, u32 diff) { // This also make skipping drawing very effective. - framebufferManager_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason); + framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { // TODO: Should this eat some cycles? Probably yes. Not sure if important. return; @@ -872,7 +872,7 @@ void GPU_Vulkan::Execute_Bezier(u32 op, u32 diff) { void GPU_Vulkan::Execute_Spline(u32 op, u32 diff) { // This also make skipping drawing very effective. - framebufferManager_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason); + framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) { // TODO: Should this eat some cycles? Probably yes. Not sure if important. return; @@ -917,27 +917,27 @@ void GPU_Vulkan::Execute_Spline(u32 op, u32 diff) { } void GPU_Vulkan::Execute_Region(u32 op, u32 diff) { - gstate_c.framebufChanged = true; + gstate_c.Dirty(DIRTY_FRAMEBUF); gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; } void GPU_Vulkan::Execute_Scissor(u32 op, u32 diff) { - gstate_c.framebufChanged = true; + gstate_c.Dirty(DIRTY_FRAMEBUF); gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; } void GPU_Vulkan::Execute_FramebufType(u32 op, u32 diff) { - gstate_c.framebufChanged = true; + gstate_c.Dirty(DIRTY_FRAMEBUF); gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; } void GPU_Vulkan::Execute_ViewportType(u32 op, u32 diff) { - gstate_c.framebufChanged = true; + gstate_c.Dirty(DIRTY_FRAMEBUF); gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; } void GPU_Vulkan::Execute_ViewportZType(u32 op, u32 diff) { - gstate_c.framebufChanged = true; + gstate_c.Dirty(DIRTY_FRAMEBUF); gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY; gstate_c.DirtyUniform(DIRTY_DEPTHRANGE); }