Skip to content

[graphics] Initialize shadows FB with a depth buffer#90

Merged
modawan merged 1 commit intomasterfrom
retro-render-bug
Mar 9, 2026
Merged

[graphics] Initialize shadows FB with a depth buffer#90
modawan merged 1 commit intomasterfrom
retro-render-bug

Conversation

@modawan
Copy link
Copy Markdown
Owner

@modawan modawan commented Feb 20, 2026

Always attach a depth buffer during initialization. Render calls glClear(GL_DEPTH_BUFFER_BIT) before a depth buffer is attached. If nothing is attached before glClear, some drivers trip and never recover.

Reproduced on Linux with Nvidia GTX 1070 and driver versions 535.261 and 550.163.

Fixes #82 "Retro renderer is broken".

@modawan modawan added this to the Endar Spire milestone Feb 20, 2026
@modawan modawan mentioned this pull request Feb 20, 2026
@modawan
Copy link
Copy Markdown
Owner Author

modawan commented Feb 21, 2026

The following patch also helps. I think the driver trips on glClear(GL_DEPTH_BUFFER_BIT) when there is no depth buffer attached, and never recovers. If we skip glClear for the first frame, the bug disappears.

diff --git a/include/reone/scene/render/pipeline/retro.h b/include/reone/scene/render/pipeline/retro.h
index d621a68d6..53cbd45f3 100644
--- a/include/reone/scene/render/pipeline/retro.h
+++ b/include/reone/scene/render/pipeline/retro.h
@@ -76,6 +76,7 @@ private:
     };
 
     RenderTargets _targets;
+    bool _shouldClear { false };
 
     void initRenderTargets();
 };
diff --git a/src/libs/scene/render/pipeline/retro.cpp b/src/libs/scene/render/pipeline/retro.cpp
index 9f0d893e3..b7bda0f49 100644
--- a/src/libs/scene/render/pipeline/retro.cpp
+++ b/src/libs/scene/render/pipeline/retro.cpp
@@ -176,7 +176,9 @@ Texture &RetroRenderPipeline::render() {
     if (dirLightShadows || pointLightShadows) {
         _context.bindDrawFramebuffer(*_targets.shadows, {});
         _context.withViewport(glm::ivec4 {0, 0, _options.shadowResolution, _options.shadowResolution}, [this, &pass, &dirLightShadows]() {
-            _context.clearDepth();
+            if (_shouldClear) {
+                _context.clearDepth();
+            }
             if (dirLightShadows) {
                 _targets.shadows->attachTexture(*_targets.dirLightShadowsDepth, Framebuffer::Attachment::Depth);
                 _passCallbacks.at(RenderPassName::DirLightShadowsPass)(pass);
@@ -184,6 +186,7 @@ Texture &RetroRenderPipeline::render() {
                 _targets.shadows->attachTexture(*_targets.pointLightShadowsDepth, Framebuffer::Attachment::Depth);
                 _passCallbacks.at(RenderPassName::PointLightShadows)(pass);
             }
+            _shouldClear = true;
         });
     }
 

@modawan modawan force-pushed the retro-render-bug branch from c8c3279 to 45f07d7 Compare March 9, 2026 03:58
@modawan modawan changed the title [graphics] Workaround: initialize shadows FB with a depth buffer [graphics] Initialize shadows FB with a depth buffer Mar 9, 2026
Always attach a depth buffer during initialization. Render calls
glClear(GL_DEPTH_BUFFER_BIT) before a depth buffer is attached. If
nothing is attached before glClear, some drivers trip and never
recover.

Reproduced on Linux with Nvidia GTX 1070 and driver versions 535.261
and 550.163.

Fixes #82 "Retro renderer is broken".
@modawan modawan force-pushed the retro-render-bug branch from 45f07d7 to 60d40d5 Compare March 9, 2026 04:18
@modawan modawan merged commit c2643e1 into master Mar 9, 2026
2 checks passed
@modawan modawan deleted the retro-render-bug branch March 9, 2026 10:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Retro renderer is broken

1 participant