Mesa (master): intel: Add fields to intel_renderbuffer for unwrapping packed depth/ stencil buffers

Chad Versace chadversary at kemper.freedesktop.org
Tue Jun 21 18:36:02 UTC 2011


Module: Mesa
Branch: master
Commit: 39d0e3632a4ccb10f2ce6578151e854ba52d3c0e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=39d0e3632a4ccb10f2ce6578151e854ba52d3c0e

Author: Chad Versace <chad at chad-versace.us>
Date:   Thu Jun 16 14:12:54 2011 -0700

intel: Add fields to intel_renderbuffer for unwrapping packed depth/stencil buffers

Add the following fields:
    intel_renderbuffer.wrapped_depth;
    intel_renderbuffer.wrapped_stencil

If the intel_context is using separate stencil and the renderbuffer has
a packed depth/stencil format, then wrapped_depth and wrapped_stencil are
the real renderbuffers.

Alter the following functions to accomodate the wrapped buffers:
    intel_delete_renderbuffer
    intel_draw_buffer
    intel_get_renderbuffer
    intel_renderbuffer_map
    intel_renderbuffer_unmap

Subsequent commits allocate renderbuffer storage for wrapped_depth and
wrapped_stencil.

Reviewed-by: Eric Anholt <eric at anholt.net>
Signed-off-by: Chad Versace <chad at chad-versace.us>

---

 src/mesa/drivers/dri/intel/intel_buffers.c |   82 +++++++++++++++-------------
 src/mesa/drivers/dri/intel/intel_fbo.c     |    6 ++
 src/mesa/drivers/dri/intel/intel_fbo.h     |   54 +++++++++++++++++--
 src/mesa/drivers/dri/intel/intel_span.c    |   20 ++++++-
 4 files changed, 118 insertions(+), 44 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c
index 7eb50ed..33f691b 100644
--- a/src/mesa/drivers/dri/intel/intel_buffers.c
+++ b/src/mesa/drivers/dri/intel/intel_buffers.c
@@ -28,7 +28,9 @@
 #include "intel_context.h"
 #include "intel_buffers.h"
 #include "intel_fbo.h"
+
 #include "main/framebuffer.h"
+#include "main/renderbuffer.h"
 
 /**
  * Return pointer to current color drawing region, or NULL.
@@ -100,6 +102,26 @@ intel_draw_buffer(struct gl_context * ctx, struct gl_framebuffer *fb)
       return;
    }
 
+   /*
+    * If intel_context is using separate stencil, but the depth attachment
+    * (gl_framebuffer.Attachment[BUFFER_DEPTH]) has a packed depth/stencil
+    * format, then we must install the real depth buffer at
+    * gl_framebuffer._DepthBuffer before calling _mesa_update_framebuffer.
+    * Otherwise, _mesa_update_framebuffer will create and install a swrast
+    * depth wrapper instead.
+    *
+    * Ditto for stencil.
+    */
+   irbDepth = intel_get_renderbuffer(fb, BUFFER_DEPTH);
+   if (irbDepth && irbDepth->Base.Format == MESA_FORMAT_X8_Z24) {
+      _mesa_reference_renderbuffer(&fb->_DepthBuffer, &irbDepth->Base);
+   }
+
+   irbStencil = intel_get_renderbuffer(fb, BUFFER_STENCIL);
+   if (irbStencil && irbStencil->Base.Format == MESA_FORMAT_S8) {
+      _mesa_reference_renderbuffer(&fb->_StencilBuffer, &irbStencil->Base);
+   }
+
    /* Do this here, not core Mesa, since this function is called from
     * many places within the driver.
     */
@@ -165,47 +187,33 @@ intel_draw_buffer(struct gl_context * ctx, struct gl_framebuffer *fb)
       FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE);
    }
 
-   /***
-    *** Get depth buffer region and check if we need a software fallback.
-    ***/
-   if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) {
-      irbDepth = intel_renderbuffer(fb->_DepthBuffer->Wrapped);
-      if (irbDepth && irbDepth->region) {
-	 assert(!fb_has_hiz || irbDepth->Base.Format != MESA_FORMAT_S8_Z24);
-         FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
-         depthRegion = irbDepth->region;
-      }
-      else {
-         FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE);
-         depthRegion = NULL;
-      }
-   }
-   else {
-      /* not using depth buffer */
+   /* Check for depth fallback. */
+   if (irbDepth && irbDepth->region) {
+      assert(!fb_has_hiz || irbDepth->Base.Format != MESA_FORMAT_S8_Z24);
+      FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
+      depthRegion = irbDepth->region;
+   } else if (irbDepth && !irbDepth->region) {
+      FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE);
+      depthRegion = NULL;
+   } else { /* !irbDepth */
+      /* No fallback is needed because there is no depth buffer. */
       FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
       depthRegion = NULL;
    }
 
-   /***
-    *** Stencil buffer
-    ***/
-   if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) {
-      irbStencil = intel_renderbuffer(fb->_StencilBuffer->Wrapped);
-      if (irbStencil && irbStencil->region) {
-	 if (!intel->has_separate_stencil)
-	    assert(irbStencil->Base.Format == MESA_FORMAT_S8_Z24);
-	 if (fb_has_hiz || intel->must_use_separate_stencil)
-	    assert(irbStencil->Base.Format == MESA_FORMAT_S8);
-	 if (irbStencil->Base.Format == MESA_FORMAT_S8)
-	    assert(intel->has_separate_stencil);
-         FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
-      }
-      else {
-         FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE);
-      }
-   }
-   else {
-      /* XXX FBO: instead of FALSE, pass ctx->Stencil._Enabled ??? */
+   /* Check for stencil fallback. */
+   if (irbStencil && irbStencil->region) {
+      if (!intel->has_separate_stencil)
+	 assert(irbStencil->Base.Format == MESA_FORMAT_S8_Z24);
+      if (fb_has_hiz || intel->must_use_separate_stencil)
+	 assert(irbStencil->Base.Format == MESA_FORMAT_S8);
+      if (irbStencil->Base.Format == MESA_FORMAT_S8)
+	 assert(intel->has_separate_stencil);
+      FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
+   } else if (irbStencil && !irbStencil->region) {
+      FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE);
+   } else { /* !irbStencil */
+      /* No fallback is needed because there is no stencil buffer. */
       FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
    }
 
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index e7c23f0..b48eac4 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -82,6 +82,12 @@ intel_delete_renderbuffer(struct gl_renderbuffer *rb)
    if (intel && irb->hiz_region) {
       intel_region_release(&irb->hiz_region);
    }
+   if (intel && irb->wrapped_depth) {
+      _mesa_reference_renderbuffer(&irb->wrapped_depth, NULL);
+   }
+   if (intel && irb->wrapped_stencil) {
+      _mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL);
+   }
 
    free(irb);
 }
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h
index 509f588..da0b240 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.h
+++ b/src/mesa/drivers/dri/intel/intel_fbo.h
@@ -45,6 +45,18 @@ struct intel_renderbuffer
    /** Only used by depth renderbuffers for which HiZ is enabled. */
    struct intel_region *hiz_region;
 
+   /**
+    * \name Packed depth/stencil unwrappers
+    *
+    * If the intel_context is using separate stencil and this renderbuffer has
+    * a a packed depth/stencil format, then wrapped_depth and wrapped_stencil
+    * are the real renderbuffers.
+    */
+   struct gl_renderbuffer *wrapped_depth;
+   struct gl_renderbuffer *wrapped_stencil;
+
+   /** \} */
+
    GLuint draw_offset; /**< Offset of drawing address within the region */
    GLuint draw_x, draw_y; /**< Offset of drawing within the region */
 };
@@ -76,15 +88,47 @@ intel_renderbuffer(struct gl_renderbuffer *rb)
 
 
 /**
- * Return a framebuffer's renderbuffer, named by a BUFFER_x index.
+ * \brief Return the framebuffer attachment specified by attIndex.
+ *
+ * If the framebuffer lacks the specified attachment, then return null.
+ *
+ * If the attached renderbuffer is a wrapper, then return wrapped
+ * renderbuffer.
  */
 static INLINE struct intel_renderbuffer *
-intel_get_renderbuffer(struct gl_framebuffer *fb, int attIndex)
+intel_get_renderbuffer(struct gl_framebuffer *fb, gl_buffer_index attIndex)
 {
-   if (attIndex >= 0)
-      return intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer);
-   else
+   struct gl_renderbuffer *rb;
+   struct intel_renderbuffer *irb;
+
+   /* XXX: Who passes -1 to intel_get_renderbuffer? */
+   if (attIndex < 0)
+      return NULL;
+
+   rb = fb->Attachment[attIndex].Renderbuffer;
+   if (!rb)
       return NULL;
+
+   irb = intel_renderbuffer(rb);
+   if (!irb)
+      return NULL;
+
+   switch (attIndex) {
+   case BUFFER_DEPTH:
+      if (irb->wrapped_depth) {
+	 irb = intel_renderbuffer(irb->wrapped_depth);
+      }
+      break;
+   case BUFFER_STENCIL:
+      if (irb->wrapped_stencil) {
+	 irb = intel_renderbuffer(irb->wrapped_stencil);
+      }
+      break;
+   default:
+      break;
+   }
+
+   return irb;
 }
 
 /**
diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c
index fdf687a..153803f 100644
--- a/src/mesa/drivers/dri/intel/intel_span.c
+++ b/src/mesa/drivers/dri/intel/intel_span.c
@@ -177,7 +177,15 @@ intel_renderbuffer_map(struct intel_context *intel, struct gl_renderbuffer *rb)
 {
    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
 
-   if (irb == NULL || irb->region == NULL)
+   if (!irb)
+      return;
+
+   if (irb->wrapped_depth)
+      intel_renderbuffer_map(intel, irb->wrapped_depth);
+   if (irb->wrapped_stencil)
+      intel_renderbuffer_map(intel, irb->wrapped_stencil);
+
+   if (!irb->region)
       return;
 
    drm_intel_gem_bo_map_gtt(irb->region->buffer);
@@ -206,7 +214,15 @@ intel_renderbuffer_unmap(struct intel_context *intel,
 {
    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
 
-   if (irb == NULL || irb->region == NULL)
+   if (!irb)
+      return;
+
+   if (irb->wrapped_depth)
+      intel_renderbuffer_unmap(intel, irb->wrapped_depth);
+   if (irb->wrapped_stencil)
+      intel_renderbuffer_unmap(intel, irb->wrapped_stencil);
+
+   if (!irb->region)
       return;
 
    drm_intel_gem_bo_unmap_gtt(irb->region->buffer);




More information about the mesa-commit mailing list