-----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 <c...@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----- _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev