⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intel_depthstencil.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
字号:
/************************************************************************** *  * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. *  * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: *  * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. *  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *  **************************************************************************/#include "glheader.h"#include "imports.h"#include "context.h"#include "depthstencil.h"#include "fbobject.h"#include "framebuffer.h"#include "hash.h"#include "mtypes.h"#include "renderbuffer.h"#include "intel_context.h"#include "intel_fbo.h"#include "intel_depthstencil.h"#include "intel_regions.h"/** * The GL_EXT_framebuffer_object allows the user to create their own * framebuffer objects consisting of color renderbuffers (0 or more), * depth renderbuffers (0 or 1) and stencil renderbuffers (0 or 1). * * The spec considers depth and stencil renderbuffers to be totally independent * buffers.  In reality, most graphics hardware today uses a combined * depth+stencil buffer (one 32-bit pixel = 24 bits of Z + 8 bits of stencil). * * This causes difficulty because the user may create some number of depth * renderbuffers and some number of stencil renderbuffers and bind them * together in framebuffers in any combination. * * This code manages all that. * * 1. Depth renderbuffers are always allocated in hardware as 32bpp *    GL_DEPTH24_STENCIL8 buffers. * * 2. Stencil renderbuffers are initially allocated in software as 8bpp *    GL_STENCIL_INDEX8 buffers. * * 3. Depth and Stencil renderbuffers use the PairedStencil and PairedDepth *    fields (respectively) to indicate if the buffer's currently paired *    with another stencil or depth buffer (respectively). * * 4. When a depth and stencil buffer are initially both attached to the *    current framebuffer, we merge the stencil buffer values into the *    depth buffer (really a depth+stencil buffer).  The then hardware uses *    the combined buffer. * * 5. Whenever a depth or stencil buffer is reallocated (with *    glRenderbufferStorage) we undo the pairing and copy the stencil values *    from the combined depth/stencil buffer back to the stencil-only buffer. * * 6. We also undo the pairing when we find a change in buffer bindings. * * 7. If a framebuffer is only using a depth renderbuffer (no stencil), we *    just use the combined depth/stencil buffer and ignore the stencil values. * * 8. If a framebuffer is only using a stencil renderbuffer (no depth) we have *    to promote the 8bpp software stencil buffer to a 32bpp hardware *    depth+stencil buffer. * */static voidmap_regions(GLcontext * ctx,            struct intel_renderbuffer *depthRb,            struct intel_renderbuffer *stencilRb){   struct intel_context *intel = intel_context(ctx);   if (depthRb && depthRb->region) {      intel_region_map(intel, depthRb->region);      depthRb->pfMap = depthRb->region->map;      depthRb->pfPitch = depthRb->region->pitch;   }   if (stencilRb && stencilRb->region) {      intel_region_map(intel, stencilRb->region);      stencilRb->pfMap = stencilRb->region->map;      stencilRb->pfPitch = stencilRb->region->pitch;   }}static voidunmap_regions(GLcontext * ctx,              struct intel_renderbuffer *depthRb,              struct intel_renderbuffer *stencilRb){   struct intel_context *intel = intel_context(ctx);   if (depthRb && depthRb->region) {      intel_region_unmap(intel, depthRb->region);      depthRb->pfMap = NULL;      depthRb->pfPitch = 0;   }   if (stencilRb && stencilRb->region) {      intel_region_unmap(intel, stencilRb->region);      stencilRb->pfMap = NULL;      stencilRb->pfPitch = 0;   }}/** * Undo the pairing/interleaving between depth and stencil buffers. * irb should be a depth/stencil or stencil renderbuffer. */voidintel_unpair_depth_stencil(GLcontext * ctx, struct intel_renderbuffer *irb){   if (irb->PairedStencil) {      /* irb is a depth/stencil buffer */      struct gl_renderbuffer *stencilRb;      struct intel_renderbuffer *stencilIrb;      ASSERT(irb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT);      stencilRb = _mesa_lookup_renderbuffer(ctx, irb->PairedStencil);      stencilIrb = intel_renderbuffer(stencilRb);      if (stencilIrb) {         /* need to extract stencil values from the depth buffer */         ASSERT(stencilIrb->PairedDepth == irb->Base.Name);         map_regions(ctx, irb, stencilIrb);         _mesa_extract_stencil(ctx, &irb->Base, &stencilIrb->Base);         unmap_regions(ctx, irb, stencilIrb);         stencilIrb->PairedDepth = 0;      }      irb->PairedStencil = 0;   }   else if (irb->PairedDepth) {      /* irb is a stencil buffer */      struct gl_renderbuffer *depthRb;      struct intel_renderbuffer *depthIrb;      ASSERT(irb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT ||             irb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT);      depthRb = _mesa_lookup_renderbuffer(ctx, irb->PairedDepth);      depthIrb = intel_renderbuffer(depthRb);      if (depthIrb) {         /* need to extract stencil values from the depth buffer */         ASSERT(depthIrb->PairedStencil == irb->Base.Name);         map_regions(ctx, depthIrb, irb);         _mesa_extract_stencil(ctx, &depthIrb->Base, &irb->Base);         unmap_regions(ctx, depthIrb, irb);         depthIrb->PairedStencil = 0;      }      irb->PairedDepth = 0;   }   else {      _mesa_problem(ctx, "Problem in undo_depth_stencil_pairing");   }   ASSERT(irb->PairedStencil == 0);   ASSERT(irb->PairedDepth == 0);}/** * 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). */voidintel_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.    */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -