static void intel_delete_renderbuffer(struct gl_renderbuffer *rb) { GET_CURRENT_CONTEXT(ctx); struct intel_context *intel = intel_context(ctx); struct intel_renderbuffer *irb = intel_renderbuffer(rb); ASSERT(irb); if (irb->PairedStencil || irb->PairedDepth) { intel_unpair_depth_stencil(ctx, irb); } if (intel && irb->region) { intel_region_release(&irb->region); } _mesa_free(irb); }
/** * 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. */ }