From 249d90067ee223636d69e5e0aa93997fc17f7212 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Wed, 11 Jan 2023 08:58:12 -0400 Subject: [PATCH] Don't discard the backbuffer depth/stencil in setCanvas. #1893. --- src/modules/graphics/metal/Graphics.h | 2 +- src/modules/graphics/metal/Graphics.mm | 10 +++++----- src/modules/graphics/opengl/Graphics.cpp | 17 ++++++++++------- src/modules/graphics/opengl/Graphics.h | 2 +- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/modules/graphics/metal/Graphics.h b/src/modules/graphics/metal/Graphics.h index 8ca3e7601..9b7f30a04 100644 --- a/src/modules/graphics/metal/Graphics.h +++ b/src/modules/graphics/metal/Graphics.h @@ -207,7 +207,7 @@ private: void initCapabilities() override; void getAPIStats(int &shaderswitches) const override; - void endPass(); + void endPass(bool presenting); id getCachedDepthStencilState(const DepthState &depth, const StencilState &stencil); void applyRenderState(id renderEncoder, const VertexAttributes &attributes); diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index 15a18a369..acbbe3d3b 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -1358,7 +1358,7 @@ bool Graphics::dispatch(int x, int y, int z) void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int /*pixelw*/, int /*pixelh*/, bool /*hasSRGBtexture*/) { @autoreleasepool { - endPass(); + endPass(false); bool isbackbuffer = rts.getFirstTarget().texture == nullptr; @@ -1410,7 +1410,7 @@ void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int /*pixelw*/ dirtyRenderState = STATEBIT_ALL; }} -void Graphics::endPass() +void Graphics::endPass(bool presenting) { // Make sure the encoder gets set up, if nothing else has done it yet. useRenderEncoder(); @@ -1421,9 +1421,9 @@ void Graphics::endPass() love::graphics::Texture *depthstencil = rts.depthStencil.texture.get(); // Discard the depth/stencil buffer if we're using an internal cached one, - // or if this is the backbuffer. + // or if we're presenting the backbuffer to the display. if ((depthstencil == nullptr && (rts.temporaryRTFlags & (TEMPORARY_RT_DEPTH | TEMPORARY_RT_STENCIL)) != 0) - || !rts.getFirstTarget().texture.get()) + || (presenting && !rts.getFirstTarget().texture.get())) { attachmentStoreActions.depth = MTLStoreActionDontCare; attachmentStoreActions.stencil = MTLStoreActionDontCare; @@ -1562,7 +1562,7 @@ void Graphics::present(void *screenshotCallbackData) // endPass calls useRenderEncoder, which makes sure activeDrawable is set // when possible. - endPass(); + endPass(true); id screenshotbuffer = nil; diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 0090bfcf1..b37bcdca2 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -758,7 +758,7 @@ void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int pixelw, in OpenGL::TempDebugGroup debuggroup("setRenderTargets"); - endPass(); + endPass(false); bool iswindow = rts.getFirstTarget().texture == nullptr; Winding vertexwinding = state.winding; @@ -794,16 +794,18 @@ void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int pixelw, in } } -void Graphics::endPass() +void Graphics::endPass(bool presenting) { auto &rts = states.back().renderTargets; love::graphics::Texture *depthstencil = rts.depthStencil.texture.get(); - // Discard the depth/stencil buffer if we're using an internal cached one. - if (depthstencil == nullptr && (rts.temporaryRTFlags & (TEMPORARY_RT_DEPTH | TEMPORARY_RT_STENCIL)) != 0) + // Discard the depth/stencil buffer if we're using an internal cached one, + // or if we're presenting the backbuffer to the display. + if ((depthstencil == nullptr && (rts.temporaryRTFlags & (TEMPORARY_RT_DEPTH | TEMPORARY_RT_STENCIL)) != 0) + || (presenting && !rts.getFirstTarget().texture.get())) + { discard({}, true); - else if (!rts.getFirstTarget().texture.get()) - discard({}, true); // Backbuffer + } // Resolve MSAA buffers. MSAA is only supported for 2D render targets so we // don't have to worry about resolving to slices. @@ -1224,7 +1226,8 @@ void Graphics::present(void *screenshotCallbackData) deprecations.draw(this); flushBatchedDraws(); - endPass(); + + endPass(true); int w = getPixelWidth(); int h = getPixelHeight(); diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index cf9567bcb..f22137dad 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -149,7 +149,7 @@ private: void initCapabilities() override; void getAPIStats(int &shaderswitches) const override; - void endPass(); + void endPass(bool presenting); GLuint bindCachedFBO(const RenderTargets &targets); void discard(OpenGL::FramebufferTarget target, const std::vector &colorbuffers, bool depthstencil);