mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Clear depth buffers after changing depth rounding mode.
And thus change of depth buffer scale/offset. Previously, old depth buffers with values that now are out of range could stick around, causing #16941. This clears them to the expected 0 value, which helps Outrun. Ideally we should convert depth buffers to the new format, but if we can get away without that, that's also nice. This is enough for #16941.
This commit is contained in:
parent
ea9245d903
commit
d426ce5118
6 changed files with 29 additions and 5 deletions
|
@ -1059,7 +1059,14 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe
|
|||
if (useBufferedRendering_) {
|
||||
if (vfb->fbo) {
|
||||
shaderManager_->DirtyLastShader();
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, {Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP}, "FBSwitch");
|
||||
Draw::RPAction depthAction = Draw::RPAction::KEEP;
|
||||
float clearDepth = 0.0f;
|
||||
if (vfb->usageFlags & FB_USAGE_INVALIDATE_DEPTH) {
|
||||
depthAction = Draw::RPAction::CLEAR;
|
||||
clearDepth = GetDepthScaleFactors().offset;
|
||||
vfb->usageFlags &= ~FB_USAGE_INVALIDATE_DEPTH;
|
||||
}
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, {Draw::RPAction::KEEP, depthAction, Draw::RPAction::KEEP, 0, clearDepth}, "FBSwitch");
|
||||
} else {
|
||||
// This should only happen very briefly when toggling useBufferedRendering_.
|
||||
ResizeFramebufFBO(vfb, vfb->width, vfb->height, true);
|
||||
|
@ -2573,6 +2580,12 @@ void FramebufferManagerCommon::ShowScreenResolution() {
|
|||
INFO_LOG(SYSTEM, "%s", messageStream.str().c_str());
|
||||
}
|
||||
|
||||
void FramebufferManagerCommon::ClearAllDepthBuffers() {
|
||||
for (auto vfb : vfbs_) {
|
||||
vfb->usageFlags |= FB_USAGE_INVALIDATE_DEPTH;
|
||||
}
|
||||
}
|
||||
|
||||
// We might also want to implement an asynchronous callback-style version of this. Would probably
|
||||
// only be possible to implement optimally on Vulkan, but on GL and D3D11 we could do pixel buffers
|
||||
// and read on the next frame, then call the callback.
|
||||
|
|
|
@ -46,6 +46,7 @@ enum {
|
|||
FB_USAGE_FIRST_FRAME_SAVED = 128,
|
||||
FB_USAGE_RENDER_DEPTH = 256,
|
||||
FB_USAGE_COLOR_MIXED_DEPTH = 512,
|
||||
FB_USAGE_INVALIDATE_DEPTH = 1024, // used to clear depth buffers.
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -317,6 +318,10 @@ public:
|
|||
void ApplyClearToMemory(int x1, int y1, int x2, int y2, u32 clearColor);
|
||||
bool PerformWriteStencilFromMemory(u32 addr, int size, WriteStencil flags);
|
||||
|
||||
// We changed our depth mode, gotta start over.
|
||||
// Ideally, we should convert depth buffers here, not just clear them.
|
||||
void ClearAllDepthBuffers();
|
||||
|
||||
// Returns true if it's sure this is a direct FBO->FBO transfer and it has already handle it.
|
||||
// In that case we hardly need to actually copy the bytes in VRAM, they will be wrong anyway (unless
|
||||
// read framebuffers is on, in which case this should always return false).
|
||||
|
|
|
@ -161,8 +161,9 @@ void GPU_D3D11::BeginFrame() {
|
|||
if (gstate_c.useFlagsChanged) {
|
||||
// TODO: It'd be better to recompile them in the background, probably?
|
||||
// This most likely means that saw equal depth changed.
|
||||
WARN_LOG(G3D, "Shader use flags changed, clearing all shaders");
|
||||
WARN_LOG(G3D, "Shader use flags changed, clearing all shaders and depth buffers");
|
||||
shaderManagerD3D11_->ClearShaders();
|
||||
framebufferManager_->ClearAllDepthBuffers();
|
||||
drawEngine_.ClearInputLayoutMap();
|
||||
gstate_c.useFlagsChanged = false;
|
||||
}
|
||||
|
|
|
@ -159,8 +159,9 @@ void GPU_DX9::BeginFrame() {
|
|||
if (gstate_c.useFlagsChanged) {
|
||||
// TODO: It'd be better to recompile them in the background, probably?
|
||||
// This most likely means that saw equal depth changed.
|
||||
WARN_LOG(G3D, "Shader use flags changed, clearing all shaders");
|
||||
WARN_LOG(G3D, "Shader use flags changed, clearing all shaders and depth buffers");
|
||||
shaderManagerDX9_->ClearCache(true);
|
||||
framebufferManager_->ClearAllDepthBuffers();
|
||||
gstate_c.useFlagsChanged = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -283,8 +283,9 @@ void GPU_GLES::BeginHostFrame() {
|
|||
if (gstate_c.useFlagsChanged) {
|
||||
// TODO: It'd be better to recompile them in the background, probably?
|
||||
// This most likely means that saw equal depth changed.
|
||||
WARN_LOG(G3D, "Shader use flags changed, clearing all shaders");
|
||||
WARN_LOG(G3D, "Shader use flags changed, clearing all shaders and depth buffers");
|
||||
shaderManagerGL_->ClearCache(true);
|
||||
framebufferManager_->ClearAllDepthBuffers();
|
||||
gstate_c.useFlagsChanged = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -310,9 +310,12 @@ void GPU_Vulkan::BeginHostFrame() {
|
|||
if (gstate_c.useFlagsChanged) {
|
||||
// TODO: It'd be better to recompile them in the background, probably?
|
||||
// This most likely means that saw equal depth changed.
|
||||
WARN_LOG(G3D, "Shader use flags changed, clearing all shaders");
|
||||
WARN_LOG(G3D, "Shader use flags changed, clearing all shaders and depth buffers");
|
||||
// TODO: Not all shaders need to be recompiled. In fact, quite few? Of course, depends on
|
||||
// the use flag change.. This is a major frame rate hitch in the start of a race in Outrun.
|
||||
shaderManagerVulkan_->ClearShaders();
|
||||
pipelineManager_->Clear();
|
||||
framebufferManager_->ClearAllDepthBuffers();
|
||||
gstate_c.useFlagsChanged = false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue