[Mesa-dev] [PATCH 1/7] mesa: Add field gl_renderbuffer.Unwrapped
Chad Versace
chad at chad-versace.us
Wed Jun 15 17:34:38 PDT 2011
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;
+ }
+ _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);
}
--
1.7.5.2
More information about the mesa-dev
mailing list