diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index df2e09514c..7c2159146c 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -317,7 +317,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame } break; } else if (v->fb_stride == params.fb_stride && v->format == params.fmt) { - u32 v_fb_first_line_end_ptr = v->fb_address + v->fb_stride * 4; // This should be * bpp, but leaving like this until after 1.13 to be safe. The God of War games use this for shadows. + u32 v_fb_first_line_end_ptr = v->fb_address + v->fb_stride * bpp; u32 v_fb_end_ptr = v->fb_address + v->fb_stride * v->height * bpp; if (params.fb_address > v->fb_address && params.fb_address < v_fb_first_line_end_ptr) { diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index 13a1fd57d8..3acff211dd 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -343,12 +343,6 @@ public: int GetTargetStride() const { return currentRenderVfb_ ? currentRenderVfb_->fb_stride : 512; } GEBufferFormat GetTargetFormat() const { return currentRenderVfb_ ? currentRenderVfb_->format : displayFormat_; } - void SetDepthUpdated() { - if (currentRenderVfb_) { - currentRenderVfb_->last_frame_depth_render = gpuStats.numFlips; - currentRenderVfb_->last_frame_depth_updated = gpuStats.numFlips; - } - } void SetColorUpdated(int skipDrawReason) { if (currentRenderVfb_) { SetColorUpdated(currentRenderVfb_, skipDrawReason); diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 6bc808ef6a..91a4dda0d3 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -693,9 +693,6 @@ rotateVBO: if (gstate.isClearModeAlphaMask()) clearFlag |= Draw::FBChannel::FB_STENCIL_BIT; if (gstate.isClearModeDepthMask()) clearFlag |= Draw::FBChannel::FB_DEPTH_BIT; - if (clearFlag & Draw::FBChannel::FB_DEPTH_BIT) { - framebufferManager_->SetDepthUpdated(); - } if (clearFlag & Draw::FBChannel::FB_COLOR_BIT) { framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); } diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index da9ec068e6..0cbc600ebc 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -298,9 +298,6 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { keys_.depthStencil.depthTestEnable = true; keys_.depthStencil.depthCompareOp = D3D11_COMPARISON_ALWAYS; keys_.depthStencil.depthWriteEnable = gstate.isClearModeDepthMask(); - if (gstate.isClearModeDepthMask()) { - framebufferManager_->SetDepthUpdated(); - } // Stencil Test bool alphaMask = gstate.isClearModeAlphaMask(); @@ -329,9 +326,6 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { keys_.depthStencil.depthTestEnable = true; keys_.depthStencil.depthCompareOp = compareOps[gstate.getDepthTestFunction()]; keys_.depthStencil.depthWriteEnable = gstate.isDepthWriteEnabled(); - if (gstate.isDepthWriteEnabled()) { - framebufferManager_->SetDepthUpdated(); - } } else { keys_.depthStencil.depthTestEnable = false; keys_.depthStencil.depthWriteEnable = false; diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index ffad2bd469..889e08387c 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -640,9 +640,6 @@ rotateVBO: if (gstate.isClearModeAlphaMask()) mask |= D3DCLEAR_STENCIL; if (gstate.isClearModeDepthMask()) mask |= D3DCLEAR_ZBUFFER; - if (mask & D3DCLEAR_ZBUFFER) { - framebufferManager_->SetDepthUpdated(); - } if (mask & D3DCLEAR_TARGET) { framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); } diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index 3d06b380e0..828f9d4b4d 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -216,9 +216,6 @@ void DrawEngineDX9::ApplyDrawState(int prim) { dxstate.depthTest.enable(); dxstate.depthFunc.set(D3DCMP_ALWAYS); dxstate.depthWrite.set(gstate.isClearModeDepthMask()); - if (gstate.isClearModeDepthMask()) { - framebufferManager_->SetDepthUpdated(); - } // Stencil Test bool alphaMask = gstate.isClearModeAlphaMask(); @@ -239,9 +236,6 @@ void DrawEngineDX9::ApplyDrawState(int prim) { dxstate.depthTest.enable(); dxstate.depthFunc.set(ztests[gstate.getDepthTestFunction()]); dxstate.depthWrite.set(gstate.isDepthWriteEnabled()); - if (gstate.isDepthWriteEnabled()) { - framebufferManager_->SetDepthUpdated(); - } } else { dxstate.depthTest.disable(); } diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index ab0960abd5..6610fcde6a 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -423,9 +423,6 @@ void DrawEngineGLES::DoFlush() { bool colorMask = gstate.isClearModeColorMask(); bool alphaMask = gstate.isClearModeAlphaMask(); bool depthMask = gstate.isClearModeDepthMask(); - if (depthMask) { - framebufferManager_->SetDepthUpdated(); - } GLbitfield target = 0; // Without this, we will clear RGB when clearing stencil, which breaks games. diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index 6e498875f1..35f9329629 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -253,18 +253,12 @@ void DrawEngineGLES::ApplyDrawState(int prim) { if (gstate.isModeClear()) { // Depth Test - if (gstate.isClearModeDepthMask()) { - framebufferManager_->SetDepthUpdated(); - } renderManager->SetStencilFunc(gstate.isClearModeAlphaMask(), GL_ALWAYS, 0xFF, 0xFF); renderManager->SetStencilOp(stencilState.writeMask, GL_REPLACE, GL_REPLACE, GL_REPLACE); renderManager->SetDepth(true, gstate.isClearModeDepthMask() ? true : false, GL_ALWAYS); } else { // Depth Test renderManager->SetDepth(gstate.isDepthTestEnabled(), gstate.isDepthWriteEnabled(), compareOps[gstate.getDepthTestFunction()]); - if (gstate.isDepthTestEnabled() && gstate.isDepthWriteEnabled()) { - framebufferManager_->SetDepthUpdated(); - } // Stencil Test if (stencilState.enabled) { diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index d751291a9b..14c4cf1f5e 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1624,6 +1624,21 @@ void GPUCommon::Execute_VertexTypeSkinning(u32 op, u32 diff) { gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_FRAGMENTSHADER_STATE | DIRTY_CULLRANGE); } +void GPUCommon::CheckDepthUsage(VirtualFramebuffer *vfb) { + if (!gstate_c.usingDepth) { + bool isClearingDepth = gstate.isModeClear() && gstate.isClearModeDepthMask(); + + if ((gstate.isDepthTestEnabled() || isClearingDepth)) { + gstate_c.usingDepth = true; + gstate_c.clearingDepth = isClearingDepth; + vfb->last_frame_depth_render = gpuStats.numFlips; + if (isClearingDepth || gstate.isDepthWriteEnabled()) { + vfb->last_frame_depth_updated = gpuStats.numFlips; + } + framebufferManager_->SetDepthFrameBuffer(); + } + } +} void GPUCommon::Execute_Prim(u32 op, u32 diff) { // This drives all drawing. All other state we just buffer up, then we apply it only @@ -1685,15 +1700,7 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { return; } - if (!gstate_c.usingDepth) { - bool isClearingDepth = gstate.isModeClear() && gstate.isClearModeDepthMask();; - - if ((gstate.isDepthTestEnabled() || isClearingDepth)) { - gstate_c.usingDepth = true; - gstate_c.clearingDepth = isClearingDepth; - framebufferManager_->SetDepthFrameBuffer(); - } - } + CheckDepthUsage(vfb); const void *verts = Memory::GetPointerUnchecked(gstate_c.vertexAddr); const void *inds = nullptr; @@ -1893,12 +1900,14 @@ void GPUCommon::Execute_Bezier(u32 op, u32 diff) { gstate_c.framebufFormat = gstate.FrameBufFormat(); // This also make skipping drawing very effective. - framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); + VirtualFramebuffer *vfb = 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; } + CheckDepthUsage(vfb); + if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); return; @@ -1963,12 +1972,14 @@ void GPUCommon::Execute_Spline(u32 op, u32 diff) { gstate_c.framebufFormat = gstate.FrameBufFormat(); // This also make skipping drawing very effective. - framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason); + VirtualFramebuffer *vfb = 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; } + CheckDepthUsage(vfb); + if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); return; diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index 59298d8e92..e61d5dada9 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -15,6 +15,8 @@ class FramebufferManagerCommon; class TextureCacheCommon; class DrawEngineCommon; class GraphicsContext; +struct VirtualFramebuffer; + namespace Draw { class DrawContext; } @@ -282,17 +284,11 @@ protected: void SlowRunLoop(DisplayList &list); void UpdatePC(u32 currentPC, u32 newPC); void UpdateState(GPURunState state); - void PopDLQueue(); - void CheckDrawSync(); - int GetNextListIndex(); - virtual void FastLoadBoneMatrix(u32 target); + void FastLoadBoneMatrix(u32 target); // TODO: Unify this. virtual void FinishDeferred() {} - void DoBlockTransfer(u32 skipDrawReason); - void DoExecuteCall(u32 target); - void AdvanceVerts(u32 vertType, int count, int bytesRead) { if ((vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { int indexShift = ((vertType & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT) - 1; @@ -362,6 +358,13 @@ protected: private: void FlushImm(); + void CheckDepthUsage(VirtualFramebuffer *vfb); + void DoBlockTransfer(u32 skipDrawReason); + void DoExecuteCall(u32 target); + void PopDLQueue(); + void CheckDrawSync(); + int GetNextListIndex(); + // Debug stats. double timeSteppingStarted_; double timeSpentStepping_; diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index 7748f24371..7061f68ae7 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -75,7 +75,4 @@ void FramebufferManagerVulkan::NotifyClear(bool clearColor, bool clearAlpha, boo if (clearColor || clearAlpha) { SetColorUpdated(gstate_c.skipDrawReason); } - if (clearDepth) { - SetDepthUpdated(); - } } diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 166f3dc153..cb1f45aaca 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -254,9 +254,6 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag key.depthTestEnable = true; key.depthCompareOp = VK_COMPARE_OP_ALWAYS; key.depthWriteEnable = gstate.isClearModeDepthMask(); - if (gstate.isClearModeDepthMask()) { - fbManager.SetDepthUpdated(); - } // Stencil Test bool alphaMask = gstate.isClearModeAlphaMask(); @@ -287,9 +284,6 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag key.depthTestEnable = true; key.depthCompareOp = compareOps[gstate.getDepthTestFunction()]; key.depthWriteEnable = gstate.isDepthWriteEnabled(); - if (gstate.isDepthWriteEnabled()) { - fbManager.SetDepthUpdated(); - } } else { key.depthTestEnable = false; key.depthWriteEnable = false;