Skip to content

Commit

Permalink
Fix deferred-depth for bezier/spline. Move updating of last_frame_dep…
Browse files Browse the repository at this point in the history
…th_render to GPUCommon.
  • Loading branch information
hrydgard committed Aug 18, 2022
1 parent 6eb8785 commit f8ab610
Show file tree
Hide file tree
Showing 12 changed files with 33 additions and 61 deletions.
2 changes: 1 addition & 1 deletion GPU/Common/FramebufferManagerCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
6 changes: 0 additions & 6 deletions GPU/Common/FramebufferManagerCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,12 +343,6 @@ class FramebufferManagerCommon {
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);
Expand Down
3 changes: 0 additions & 3 deletions GPU/D3D11/DrawEngineD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -693,9 +693,6 @@ void DrawEngineD3D11::DoFlush() {
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);
}
Expand Down
6 changes: 0 additions & 6 deletions GPU/D3D11/StateMappingD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 0 additions & 3 deletions GPU/Directx9/DrawEngineDX9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -640,9 +640,6 @@ void DrawEngineDX9::DoFlush() {
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);
}
Expand Down
6 changes: 0 additions & 6 deletions GPU/Directx9/StateMappingDX9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
}
Expand Down
3 changes: 0 additions & 3 deletions GPU/GLES/DrawEngineGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 0 additions & 6 deletions GPU/GLES/StateMappingGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
33 changes: 22 additions & 11 deletions GPU/GPUCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
17 changes: 10 additions & 7 deletions GPU/GPUCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class FramebufferManagerCommon;
class TextureCacheCommon;
class DrawEngineCommon;
class GraphicsContext;
struct VirtualFramebuffer;

namespace Draw {
class DrawContext;
}
Expand Down Expand Up @@ -282,17 +284,11 @@ class GPUCommon : public GPUInterface, public GPUDebugInterface {
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;
Expand Down Expand Up @@ -362,6 +358,13 @@ class GPUCommon : public GPUInterface, public GPUDebugInterface {

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_;
Expand Down
3 changes: 0 additions & 3 deletions GPU/Vulkan/FramebufferManagerVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,4 @@ void FramebufferManagerVulkan::NotifyClear(bool clearColor, bool clearAlpha, boo
if (clearColor || clearAlpha) {
SetColorUpdated(gstate_c.skipDrawReason);
}
if (clearDepth) {
SetDepthUpdated();
}
}
6 changes: 0 additions & 6 deletions GPU/Vulkan/StateMappingVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit f8ab610

Please sign in to comment.