[Mesa-dev] [PATCH 1/7] mesa: Add field gl_renderbuffer.Unwrapped

Ian Romanick idr at freedesktop.org
Thu Jun 16 09:24:13 PDT 2011


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 06/15/2011 05:34 PM, Chad Versace wrote:
> If a renderbuffer wraps multiple renderbuffers, then Unwrapped points to
> the them.
> 
> For example, if hardware requires separate depth and stencil buffers
> (X8_Z24 and S8), then glRenderbufferStorage(GL_DEPTH24_STENCIL8) may
> create a fake S8_Z24 renderbuffer for which Unwrapped[BUFFER_DEPTH] and
> Unwrapped[BUFFER_STENCIL] point to the real X8_Z24 and S8 renderbuffers.
> 
> Alter the following function to take Unwrapped into account:
>     _mesa_framebuffer_renderbuffer
>     _mesa_update_depth_buffer
>     _mesa_update_stencil_buffer
>     _mesa_reference_renderbuffer
> 
> Signed-off-by: Chad Versace <chad at chad-versace.us>
> ---
>  src/mesa/main/fbobject.c     |   26 +++++++++++++++++---
>  src/mesa/main/framebuffer.c  |   54 +++++++++++++++++++++++++++++++-----------
>  src/mesa/main/mtypes.h       |   11 ++++++++
>  src/mesa/main/renderbuffer.c |    6 ++++
>  4 files changed, 79 insertions(+), 18 deletions(-)
> 
> diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
> index 2230b26..61a0619 100644
> --- a/src/mesa/main/fbobject.c
> +++ b/src/mesa/main/fbobject.c
> @@ -379,10 +379,28 @@ _mesa_framebuffer_renderbuffer(struct gl_context *ctx,
>     if (rb) {
>        _mesa_set_renderbuffer_attachment(ctx, att, rb);
>        if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
> -         /* do stencil attachment here (depth already done above) */
> -         att = _mesa_get_attachment(ctx, fb, GL_STENCIL_ATTACHMENT_EXT);
> -         assert(att);
> -         _mesa_set_renderbuffer_attachment(ctx, att, rb);
> +	 struct gl_renderbuffer_attachment *depth_att =
> +	    _mesa_get_attachment(ctx, fb, GL_DEPTH_ATTACHMENT);
> +	 struct gl_renderbuffer_attachment *stencil_att =
> +	    _mesa_get_attachment(ctx, fb, GL_STENCIL_ATTACHMENT_EXT);
> +	 struct gl_renderbuffer *depth_rb;
> +	 struct gl_renderbuffer *stencil_rb;
> +
> +	 /* Set depth attachment. */
> +	 if (rb->Unwrapped[BUFFER_DEPTH]) {
> +	    depth_rb = rb->Unwrapped[BUFFER_DEPTH];
> +	 } else {
> +	    depth_rb = rb;
> +	 }

Instead of doing this, would it be easier to have Unwrapped[] point back
to itself for non-wrapper renderbuffers?  That may have other
consequences that I'm not foreseeing.

> +	 _mesa_set_renderbuffer_attachment(ctx, depth_att, depth_rb);
> +
> +	 /* Set stencil attachment. */
> +	 if (rb->Unwrapped[BUFFER_STENCIL]) {
> +	    stencil_rb = rb->Unwrapped[BUFFER_STENCIL];
> +	 } else {
> +	    stencil_rb = rb;
> +	 }
> +	 _mesa_set_renderbuffer_attachment(ctx, stencil_att, stencil_rb);
>        }
>        rb->AttachedAnytime = GL_TRUE;
>     }
> diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
> index 66c9bd9..6e1f1f1 100644
> --- a/src/mesa/main/framebuffer.c
> +++ b/src/mesa/main/framebuffer.c
> @@ -604,14 +604,20 @@ _mesa_update_framebuffer_visual(struct gl_context *ctx,
>  
>  
>  /**
> - * Update the framebuffer's _DepthBuffer field using the renderbuffer
> - * found at the given attachment index.
> + * \brief Update gl_framebuffer._DepthBuffer.
>   *
> - * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer,
> - * create and install a depth wrapper/adaptor.
> + * Set gl_framebuffer._DepthBuffer to the attachment's renderbuffer, unless
> + * the renderbuffer has packed depth/stencil format.
> + *
> + * Renderbuffers with packed depth/stencil format are a special case. If the
> + * attachment's renderbuffer contains a depth unwrapper (that is,
> + * gl_renderbuffer.Unwrapper[BUFFER_DEPTH != NULL), then install the
> + * unwrapper. Otherwise, create and install a x8_z24 depth wrapper.
>   *
>   * \param fb  the framebuffer whose _DepthBuffer field to update
>   * \param attIndex  indicates the renderbuffer to possibly wrap
> + *
> + * \see _mesa_new_z24_renderbuffer_wrapper
>   */
>  void
>  _mesa_update_depth_buffer(struct gl_context *ctx,
> @@ -627,9 +633,16 @@ _mesa_update_depth_buffer(struct gl_context *ctx,
>  
>     if (depthRb && _mesa_is_format_packed_depth_stencil(depthRb->Format)) {
>        /* The attached depth buffer is a GL_DEPTH_STENCIL renderbuffer */
> -      if (!fb->_DepthBuffer
> -          || fb->_DepthBuffer->Wrapped != depthRb
> -          || _mesa_get_format_base_format(fb->_DepthBuffer->Format) != GL_DEPTH_COMPONENT) {
> +      struct gl_renderbuffer *unwrapper = depthRb->Unwrapped[BUFFER_DEPTH];
> +      if (unwrapper) {
> +	 if (fb->_DepthBuffer != unwrapper) {
> +	    _mesa_reference_renderbuffer(&fb->_DepthBuffer, unwrapper);
> +	 }
> +      }
> +      else if (!fb->_DepthBuffer
> +	       || fb->_DepthBuffer->Wrapped != depthRb
> +	       || _mesa_get_format_base_format(fb->_DepthBuffer->Format)
> +		  != GL_DEPTH_COMPONENT) {
>           /* need to update wrapper */
>           struct gl_renderbuffer *wrapper
>              = _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb);
> @@ -645,14 +658,20 @@ _mesa_update_depth_buffer(struct gl_context *ctx,
>  
>  
>  /**
> - * Update the framebuffer's _StencilBuffer field using the renderbuffer
> - * found at the given attachment index.
> + * \brief Update gl_framebuffer._StencilBuffer.
>   *
> - * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer,
> - * create and install a stencil wrapper/adaptor.
> + * Set gl_framebuffer._StencilBuffer to the attachment's renderbuffer, unless
> + * the renderbuffer has packed depth/stencil format.
> + *
> + * Renderbuffers with packed depth/stencil format are a special case. If the
> + * attachment's renderbuffer contains a stencil unwrapper (that is,
> + * gl_renderbuffer.Unwrapper[BUFFER_STENCIL != NULL), then install the
> + * unwrapper. Otherwise, create and install a s8 stencil wrapper.
>   *
>   * \param fb  the framebuffer whose _StencilBuffer field to update
>   * \param attIndex  indicates the renderbuffer to possibly wrap
> + *
> + * \see _mesa_new_s8_renderbuffer_wrapper
>   */
>  void
>  _mesa_update_stencil_buffer(struct gl_context *ctx,
> @@ -668,9 +687,16 @@ _mesa_update_stencil_buffer(struct gl_context *ctx,
>  
>     if (stencilRb && _mesa_is_format_packed_depth_stencil(stencilRb->Format)) {
>        /* The attached stencil buffer is a GL_DEPTH_STENCIL renderbuffer */
> -      if (!fb->_StencilBuffer
> -          || fb->_StencilBuffer->Wrapped != stencilRb
> -          || _mesa_get_format_base_format(fb->_StencilBuffer->Format) != GL_STENCIL_INDEX) {
> +      struct gl_renderbuffer *unwrapper = stencilRb->Unwrapped[BUFFER_STENCIL];
> +      if (unwrapper) {
> +	 if (fb->_StencilBuffer != unwrapper) {
> +	    _mesa_reference_renderbuffer(&fb->_StencilBuffer, unwrapper);
> +	 }
> +      }
> +      else if (!fb->_StencilBuffer
> +	       || fb->_StencilBuffer->Wrapped != stencilRb
> +	       || _mesa_get_format_base_format(fb->_StencilBuffer->Format)
> +		  != GL_STENCIL_INDEX) {
>           /* need to update wrapper */
>           struct gl_renderbuffer *wrapper
>              = _mesa_new_s8_renderbuffer_wrapper(ctx, stencilRb);
> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
> index eb2efc8..6cda4a3 100644
> --- a/src/mesa/main/mtypes.h
> +++ b/src/mesa/main/mtypes.h
> @@ -2437,6 +2437,17 @@ struct gl_renderbuffer
>     /* Used to wrap one renderbuffer around another: */
>     struct gl_renderbuffer *Wrapped;
>  
> +   /**
> +    * If this renderbuffer wraps multiple renderbuffers, then Unwrapped points
> +    * to the them.
> +    *
> +    * For example, if hardware requires separate depth and stencil buffers
> +    * (X8_Z24 and S8), then glRenderbufferStorage(GL_DEPTH24_STENCIL8) may
> +    * create a fake S8_Z24 renderbuffer for which Unwrapped[BUFFER_DEPTH] and
> +    * Unwrapped[BUFFER_STENCIL] point to the real X8_Z24 and S8 renderbuffers.
> +    */
> +   struct gl_renderbuffer *Unwrapped[BUFFER_COUNT];
> +
>     /* Delete this renderbuffer */
>     void (*Delete)(struct gl_renderbuffer *rb);
>  
> diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c
> index fa884c0..12b45ac 100644
> --- a/src/mesa/main/renderbuffer.c
> +++ b/src/mesa/main/renderbuffer.c
> @@ -2551,6 +2551,12 @@ _mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
>        _glthread_UNLOCK_MUTEX(oldRb->Mutex);
>  
>        if (deleteFlag) {
> +	 for (int i = 0; i < BUFFER_COUNT; ++i) {
> +	    struct gl_renderbuffer **unwrapper = &oldRb->Unwrapped[i];
> +	    if (*unwrapper) {
> +	       _mesa_reference_renderbuffer(unwrapper, NULL);
> +	    }
> +	 }
>           oldRb->Delete(oldRb);
>        }
>  

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAk36LiYACgkQX1gOwKyEAw+ehACfTNIK/AadDouMSYRP4Y9EHhb3
jRAAn2+w7A6BaFy+xG98tIH1CNZP2aIy
=X6aE
-----END PGP SIGNATURE-----


More information about the mesa-dev mailing list