4141import static org .lwjgl .opengl .GL42 .glDepthFunc ;
4242import static org .lwjgl .opengl .GL42 .*;
4343import static org .lwjgl .opengl .GL45 .glClearNamedFramebufferfi ;
44+ import static org .lwjgl .opengl .GL45 .glGetNamedFramebufferAttachmentParameteri ;
4445import static org .lwjgl .opengl .GL45C .glBindTextureUnit ;
4546import static org .lwjgl .opengl .GL45C .glBlitNamedFramebuffer ;
4647
@@ -55,6 +56,8 @@ public abstract class AbstractRenderPipeline extends TrackedObject {
5556
5657 private final FullscreenBlit depthMaskBlit = new FullscreenBlit ("voxy:post/fullscreen2.vert" , "voxy:post/noop.frag" );
5758 private final FullscreenBlit depthSetBlit = new FullscreenBlit ("voxy:post/fullscreen2.vert" , "voxy:post/depth0.frag" );
59+ private final FullscreenBlit depthCopy = new FullscreenBlit ("voxy:post/fullscreen2.vert" , "voxy:post/depth_copy.frag" );
60+
5861 protected AbstractRenderPipeline (AsyncNodeManager nodeManager , NodeCleaner nodeCleaner , HierarchicalOcclusionTraverser traversal , BooleanSupplier frexSupplier ) {
5962 this .frexStillHasWork = frexSupplier ;
6063 this .nodeManager = nodeManager ;
@@ -106,10 +109,16 @@ public void runPipeline(Viewport<?> viewport, int sourceFrameBuffer, int srcWidt
106109
107110 protected void initDepthStencil (int sourceFrameBuffer , int targetFb , int srcWidth , int srcHeight , int width , int height ) {
108111 glClearNamedFramebufferfi (targetFb , GL_DEPTH_STENCIL , 0 , 1.0f , 1 );
109- glBlitNamedFramebuffer ( sourceFrameBuffer , targetFb , 0 , 0 , srcWidth , srcHeight , 0 , 0 , width , height , GL_DEPTH_BUFFER_BIT , GL_NEAREST );
110-
112+ // using blit to copy depth from mismatched depth formats is not portable so instead a full screen pass is performed for a depth copy
113+ // the mismatched formats in this case is the d32 to d24s8
111114 glBindFramebuffer (GL30 .GL_FRAMEBUFFER , targetFb );
112115
116+ int depthTexture = glGetNamedFramebufferAttachmentParameteri (sourceFrameBuffer , GL_DEPTH_ATTACHMENT , GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME );
117+ glBindTextureUnit (0 , depthTexture );
118+
119+ glColorMask (false ,false ,false ,false );
120+ this .depthCopy .blit ();
121+
113122 /*
114123 if (Capabilities.INSTANCE.isMesa){
115124 glClearStencil(1);
@@ -126,7 +135,6 @@ protected void initDepthStencil(int sourceFrameBuffer, int targetFb, int srcWidt
126135
127136 glEnable (GL_DEPTH_TEST );
128137 glDepthFunc (GL_NOTEQUAL );//If != 1 pass
129- glColorMask (false ,false ,false ,false );
130138 //We do here
131139 this .depthMaskBlit .blit ();
132140 glDisable (GL_DEPTH_TEST );
@@ -147,6 +155,9 @@ protected void initDepthStencil(int sourceFrameBuffer, int targetFb, int srcWidt
147155
148156 private static final long SCRATCH = MemoryUtil .nmemAlloc (4 *4 *4 );
149157 protected static void transformBlitDepth (FullscreenBlit blitShader , int srcDepthTex , int dstFB , Viewport <?> viewport , Matrix4f targetTransform ) {
158+ // at this point the dst frame buffer doesn't have a stencil attachment so we don't need to keep the stencil test on for the blit
159+ // in the worst case the dstFB does have a stencil attachment causing this pass to become 'corrupted'
160+ glDisable (GL_STENCIL_TEST );
150161 glBindFramebuffer (GL30 .GL_FRAMEBUFFER , dstFB );
151162
152163 blitShader .bind ();
@@ -157,7 +168,6 @@ protected static void transformBlitDepth(FullscreenBlit blitShader, int srcDepth
157168 nglUniformMatrix4fv (2 , 1 , false , SCRATCH );//tooProjection
158169
159170 glEnable (GL_DEPTH_TEST );
160- //We keep the stencil test on with the emitting, only to where non terrain is rendered
161171 blitShader .blit ();
162172 glDisable (GL_STENCIL_TEST );
163173 glDisable (GL_DEPTH_TEST );
@@ -198,6 +208,7 @@ protected void free0() {
198208 this .sectionRenderer .free ();
199209 this .depthMaskBlit .delete ();
200210 this .depthSetBlit .delete ();
211+ this .depthCopy .delete ();
201212 super .free0 ();
202213 }
203214
0 commit comments