static void update_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) { /* Completeness only matters for user-created framebuffers */ if (fb->Name != 0) { /* XXX: EXT_framebuffer_blit: framebuffer must still be complete wrt read/draw? */ _mesa_test_framebuffer_completeness(ctx, fb); _mesa_update_framebuffer_visual(fb); } /* update_color_draw/read_buffers not needed for read/draw only fb, but shouldn't hurt ??? */ update_color_draw_buffers(ctx, fb); update_color_read_buffer(ctx, fb); _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH); _mesa_update_stencil_buffer(ctx, fb, BUFFER_STENCIL); compute_depth_max(fb); }
/** * Update a gl_framebuffer's derived state. * * Specifically, update these framebuffer fields: * _ColorDrawBuffers * _NumColorDrawBuffers * _ColorReadBuffer * _DepthBuffer * _StencilBuffer * * If the framebuffer is user-created, make sure it's complete. * * The following functions (at least) can effect framebuffer state: * glReadBuffer, glDrawBuffer, glDrawBuffersARB, glFramebufferRenderbufferEXT, * glRenderbufferStorageEXT. */ static void update_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) { if (fb->Name == 0) { /* This is a window-system framebuffer */ /* Need to update the FB's GL_DRAW_BUFFER state to match the * context state (GL_READ_BUFFER too). */ if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) { _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, ctx->Color.DrawBuffer, NULL); } if (fb->ColorReadBuffer != ctx->Pixel.ReadBuffer) { } } else { /* This is a user-created framebuffer. * Completeness only matters for user-created framebuffers. */ if (fb->_Status != GL_FRAMEBUFFER_COMPLETE) { _mesa_test_framebuffer_completeness(ctx, fb); } } /* Strictly speaking, we don't need to update the draw-state * if this FB is bound as ctx->ReadBuffer (and conversely, the * read-state if this FB is bound as ctx->DrawBuffer), but no * harm. */ update_color_draw_buffers(ctx, fb); update_color_read_buffer(ctx, fb); _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH); _mesa_update_stencil_buffer(ctx, fb, BUFFER_STENCIL); compute_depth_max(fb); }
/** * Examine the depth and stencil renderbuffers which are attached to the * framebuffer. If both depth and stencil are attached, make sure that the * renderbuffers are 'paired' (combined). If only depth or only stencil is * attached, undo any previous pairing. * * Must be called if NewState & _NEW_BUFFER (when renderbuffer attachments * change, for example). */ void intel_validate_paired_depth_stencil(GLcontext * ctx, struct gl_framebuffer *fb) { struct intel_renderbuffer *depthRb, *stencilRb; depthRb = intel_get_renderbuffer(fb, BUFFER_DEPTH); stencilRb = intel_get_renderbuffer(fb, BUFFER_STENCIL); if (depthRb && stencilRb) { if (depthRb == stencilRb) { /* Using a user-created combined depth/stencil buffer. * Nothing to do. */ ASSERT(depthRb->Base._BaseFormat == GL_DEPTH_STENCIL_EXT); ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); } else { /* Separate depth/stencil buffers, need to interleave now */ ASSERT(depthRb->Base._BaseFormat == GL_DEPTH_COMPONENT); ASSERT(stencilRb->Base._BaseFormat == GL_STENCIL_INDEX); /* may need to interleave depth/stencil now */ if (depthRb->PairedStencil == stencilRb->Base.Name) { /* OK, the depth and stencil buffers are already interleaved */ ASSERT(stencilRb->PairedDepth == depthRb->Base.Name); } else { /* need to setup new pairing/interleaving */ if (depthRb->PairedStencil) { intel_unpair_depth_stencil(ctx, depthRb); } if (stencilRb->PairedDepth) { intel_unpair_depth_stencil(ctx, stencilRb); } ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); ASSERT(stencilRb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT || stencilRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); /* establish new pairing: interleave stencil into depth buffer */ map_regions(ctx, depthRb, stencilRb); _mesa_insert_stencil(ctx, &depthRb->Base, &stencilRb->Base); unmap_regions(ctx, depthRb, stencilRb); depthRb->PairedStencil = stencilRb->Base.Name; stencilRb->PairedDepth = depthRb->Base.Name; } } } else if (depthRb) { /* Depth buffer but no stencil buffer. * We'll use a GL_DEPTH24_STENCIL8 buffer and ignore the stencil bits. */ /* can't assert this until storage is allocated: ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); */ /* intel_undo any previous pairing */ if (depthRb->PairedStencil) { intel_unpair_depth_stencil(ctx, depthRb); } } else if (stencilRb) { /* Stencil buffer but no depth buffer. * Since h/w doesn't typically support just 8bpp stencil w/out Z, * we'll use a GL_DEPTH24_STENCIL8 buffer and ignore the depth bits. */ /* undo any previous pairing */ if (stencilRb->PairedDepth) { intel_unpair_depth_stencil(ctx, stencilRb); } if (stencilRb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT) { /* promote buffer to GL_DEPTH24_STENCIL8 for hw rendering */ _mesa_promote_stencil(ctx, &stencilRb->Base); ASSERT(stencilRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); } } /* Finally, update the fb->_DepthBuffer and fb->_StencilBuffer fields */ _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH); if (depthRb && depthRb->PairedStencil) _mesa_update_stencil_buffer(ctx, fb, BUFFER_DEPTH); else _mesa_update_stencil_buffer(ctx, fb, BUFFER_STENCIL); /* The hardware should use fb->Attachment[BUFFER_DEPTH].Renderbuffer * first, if present, then fb->Attachment[BUFFER_STENCIL].Renderbuffer * if present. */ }