[Mesa-dev] [PATCH 08/10] intel: Refactor intel_update_renderbuffers()

Chad Versace chad at chad-versace.us
Sat Jun 4 17:45:41 PDT 2011


Extract the code that queries DRI2 to obtain the DRIdrawable's buffers
into intel_query_dri2_buffers_no_separate_stencil().

Extract the code that assigns the DRI buffer's DRM region to the
corresponding renderbuffer into
intel_process_dri2_buffer_no_separate_stencil().

Rationale
---------
The next commit enables intel_update_renderbuffers() to query for separate
stencil and hiz buffers. Without separating the separate-stencil and
no-separate-stencil paths, intel_update_renderbuffers() degenerates into
an impenetrable labyrinth of if-trees.

CC: Eric Anholt <eric at anholt.net>
CC: Ian Romanick <idr at freedesktop.org>
CC: Kenneth Graunke <kenneth at whitecape.org>
CC: Kristian Høgsberg <krh at bitplanet.net>
Signed-off-by: Chad Versace <chad at chad-versace.us>
---
 src/mesa/drivers/dri/intel/intel_context.c |  323 ++++++++++++++++++----------
 1 files changed, 212 insertions(+), 111 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index 8091d4f..3af96f5 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -227,18 +227,27 @@ intel_bits_per_pixel(const struct intel_renderbuffer *rb)
    return _mesa_get_format_bytes(rb->Base.Format) * 8;
 }
 
+static void
+intel_query_dri2_buffers_no_separate_stencil(struct intel_context *intel,
+					     __DRIdrawable *drawable,
+					     __DRIbuffer **buffers,
+					     int *count);
+
+static void
+intel_process_dri2_buffer_no_separate_stencil(struct intel_context *intel,
+					      __DRIdrawable *drawable,
+					      __DRIbuffer *buffer,
+					      struct intel_renderbuffer *rb,
+					      const char *buffer_name);
+
 void
 intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
 {
    struct gl_framebuffer *fb = drawable->driverPrivate;
    struct intel_renderbuffer *rb;
-   struct intel_region *region, *depth_region;
    struct intel_context *intel = context->driverPrivate;
-   struct intel_renderbuffer *front_rb, *back_rb, *depth_rb, *stencil_rb;
    __DRIbuffer *buffers = NULL;
-   __DRIscreen *screen;
    int i, count;
-   unsigned int attachments[10];
    const char *region_name;
 
    /* If we're rendering to the fake front buffer, make sure all the
@@ -260,70 +269,12 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
    if (unlikely(INTEL_DEBUG & DEBUG_DRI))
       fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
 
-   screen = intel->intelScreen->driScrnPriv;
-
-   if (screen->dri2.loader
-       && (screen->dri2.loader->base.version > 2)
-       && (screen->dri2.loader->getBuffersWithFormat != NULL)) {
-
-      front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
-      back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
-      depth_rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
-      stencil_rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
-
-      i = 0;
-      if ((intel->is_front_buffer_rendering ||
-	   intel->is_front_buffer_reading ||
-	   !back_rb) && front_rb) {
-	 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
-	 attachments[i++] = intel_bits_per_pixel(front_rb);
-      }
-
-      if (back_rb) {
-	 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
-	 attachments[i++] = intel_bits_per_pixel(back_rb);
-      }
-
-      if ((depth_rb != NULL) && (stencil_rb != NULL)) {
-	 attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
-	 attachments[i++] = intel_bits_per_pixel(depth_rb);
-      } else if (depth_rb != NULL) {
-	 attachments[i++] = __DRI_BUFFER_DEPTH;
-	 attachments[i++] = intel_bits_per_pixel(depth_rb);
-      } else if (stencil_rb != NULL) {
-	 attachments[i++] = __DRI_BUFFER_STENCIL;
-	 attachments[i++] = intel_bits_per_pixel(stencil_rb);
-      }
-
-      buffers =
-	 (*screen->dri2.loader->getBuffersWithFormat)(drawable,
-						      &drawable->w,
-						      &drawable->h,
-						      attachments, i / 2,
-						      &count,
-						      drawable->loaderPrivate);
-   } else if (screen->dri2.loader) {
-      i = 0;
-      if (intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT))
-	 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
-      if (intel_get_renderbuffer(fb, BUFFER_BACK_LEFT))
-	 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
-      if (intel_get_renderbuffer(fb, BUFFER_DEPTH))
-	 attachments[i++] = __DRI_BUFFER_DEPTH;
-      if (intel_get_renderbuffer(fb, BUFFER_STENCIL))
-	 attachments[i++] = __DRI_BUFFER_STENCIL;
-
-      buffers = (*screen->dri2.loader->getBuffers)(drawable,
-						   &drawable->w,
-						   &drawable->h,
-						   attachments, i,
-						   &count,
-						   drawable->loaderPrivate);
-   }
-
    if (buffers == NULL)
       return;
 
+   intel_query_dri2_buffers_no_separate_stencil(intel, drawable, &buffers,
+					        &count);
+
    drawable->x = 0;
    drawable->y = 0;
    drawable->backX = 0;
@@ -339,7 +290,6 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
    drawable->pBackClipRects[0].x2 = drawable->w;
    drawable->pBackClipRects[0].y2 = drawable->h;
 
-   depth_region = NULL;
    for (i = 0; i < count; i++) {
        switch (buffers[i].attachment) {
        case __DRI_BUFFER_FRONT_LEFT:
@@ -380,51 +330,9 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
 	   return;
        }
 
-       if (rb == NULL)
-	  continue;
-
-       if (rb->region && rb->region->name == buffers[i].name)
-	     continue;
-
-       if (unlikely(INTEL_DEBUG & DEBUG_DRI))
-	  fprintf(stderr,
-		  "attaching buffer %d, at %d, cpp %d, pitch %d\n",
-		  buffers[i].name, buffers[i].attachment,
-		  buffers[i].cpp, buffers[i].pitch);
-       
-       if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_region) {
-	  if (unlikely(INTEL_DEBUG & DEBUG_DRI))
-	     fprintf(stderr, "(reusing depth buffer as stencil)\n");
-	  intel_region_reference(&region, depth_region);
-       }
-       else
-          region = intel_region_alloc_for_handle(intel->intelScreen,
-						 buffers[i].cpp,
-						 drawable->w,
-						 drawable->h,
-						 buffers[i].pitch / buffers[i].cpp,
-						 buffers[i].name,
-						 region_name);
-
-       if (buffers[i].attachment == __DRI_BUFFER_DEPTH)
-	  depth_region = region;
-
-       intel_renderbuffer_set_region(intel, rb, region);
-       intel_region_release(&region);
-
-       if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
-	  rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
-	  if (rb != NULL) {
-	     struct intel_region *stencil_region = NULL;
-
-	     if (rb->region && rb->region->name == buffers[i].name)
-		   continue;
-
-	     intel_region_reference(&stencil_region, region);
-	     intel_renderbuffer_set_region(intel, rb, stencil_region);
-	     intel_region_release(&stencil_region);
-	  }
-       }
+      intel_process_dri2_buffer_no_separate_stencil(intel, drawable,
+						    &buffers[i], rb,
+						    region_name);
    }
 
    driUpdateFramebufferSize(&intel->ctx, drawable);
@@ -1033,3 +941,196 @@ intelMakeCurrent(__DRIcontext * driContextPriv,
 
    return GL_TRUE;
 }
+
+/**
+ * \brief Query DRI2 to obtain a DRIdrawable's buffers.
+ *
+ * To determine which DRI buffers to request, examine the renderbuffers
+ * attached to the drawable's framebuffer. Then request the buffers with
+ * DRI2GetBuffers() or DRI2GetBuffersWithFormat().
+ *
+ * This is called from intel_update_renderbuffers(). It is used only if either
+ * the hardware or the X driver lacks separate stencil support.
+ *
+ * \param drawable      Drawable whose buffers are queried.
+ * \param buffers       [out] List of buffers returned by DRI2 query.
+ * \param buffer_count  [out] Number of buffers returned.
+ *
+ * \see intel_update_renderbuffers()
+ * \see DRI2GetBuffers()
+ * \see DRI2GetBuffersWithFormat()
+ */
+static void
+intel_query_dri2_buffers_no_separate_stencil(struct intel_context *intel,
+					     __DRIdrawable *drawable,
+					     __DRIbuffer **buffers,
+					     int *buffer_count)
+{
+   assert(!intel->must_use_separate_stencil);
+
+   __DRIscreen *screen = intel->intelScreen->driScrnPriv;
+   struct gl_framebuffer *fb = drawable->driverPrivate;
+
+   if (screen->dri2.loader
+       && screen->dri2.loader->base.version > 2
+       && screen->dri2.loader->getBuffersWithFormat != NULL) {
+
+      int i = 0;
+      const int max_attachments = 4;
+      unsigned *attachments = calloc(2 * max_attachments, sizeof(unsigned));
+
+      struct intel_renderbuffer *front_rb;
+      struct intel_renderbuffer *back_rb;
+      struct intel_renderbuffer *depth_rb;
+      struct intel_renderbuffer *stencil_rb;
+
+      front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+      back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
+      depth_rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
+      stencil_rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
+
+      if ((intel->is_front_buffer_rendering ||
+	   intel->is_front_buffer_reading ||
+	   !back_rb) && front_rb) {
+	 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+	 attachments[i++] = intel_bits_per_pixel(front_rb);
+      }
+
+      if (back_rb) {
+	 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+	 attachments[i++] = intel_bits_per_pixel(back_rb);
+      }
+
+      if (depth_rb && stencil_rb) {
+	 attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
+	 attachments[i++] = intel_bits_per_pixel(depth_rb);
+      } else if (depth_rb) {
+	 attachments[i++] = __DRI_BUFFER_DEPTH;
+	 attachments[i++] = intel_bits_per_pixel(depth_rb);
+      } else if (stencil_rb) {
+	 attachments[i++] = __DRI_BUFFER_STENCIL;
+	 attachments[i++] = intel_bits_per_pixel(stencil_rb);
+      }
+
+      assert(i <= 2 * max_attachments);
+
+      *buffers = screen->dri2.loader->getBuffersWithFormat(drawable,
+							   &drawable->w,
+							   &drawable->h,
+							   attachments, i / 2,
+							   buffer_count,
+							   drawable->loaderPrivate);
+      free(attachments);
+
+   } else if (screen->dri2.loader) {
+
+      int i = 0;
+      const int max_attachments = 4;
+      unsigned *attachments = calloc(max_attachments, sizeof(unsigned));
+
+      if (intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT))
+	 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+      if (intel_get_renderbuffer(fb, BUFFER_BACK_LEFT))
+	 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+      if (intel_get_renderbuffer(fb, BUFFER_DEPTH))
+	 attachments[i++] = __DRI_BUFFER_DEPTH;
+      if (intel_get_renderbuffer(fb, BUFFER_STENCIL))
+	 attachments[i++] = __DRI_BUFFER_STENCIL;
+
+      assert(i <= max_attachments);
+
+      *buffers = screen->dri2.loader->getBuffersWithFormat(drawable,
+							   &drawable->w,
+							   &drawable->h,
+							   attachments, i,
+							   buffer_count,
+							   drawable->loaderPrivate);
+      free(attachments);
+
+   } else {
+      *buffers = NULL;
+      *buffer_count = 0;
+   }
+}
+
+/**
+ * \brief Assign a DRI buffer's DRM region to a renderbuffer.
+ *
+ * This is called from intel_update_renderbuffers().  It is used only if
+ * either the hardware or the X driver lacks separate stencil support.
+ *
+ * \par Note:
+ *    DRI buffers whose attachment point is DRI2BufferStencil or
+ *    DRI2BufferDepthStencil are handled as special cases.
+ *
+ * \param buffer_name is a human readable name, such as "dri2 front buffer",
+ *        that is passed to intel_region_alloc_for_handle().
+ *
+ * \see intel_update_renderbuffers()
+ * \see intel_region_alloc_for_handle()
+ * \see intel_renderbuffer_set_region()
+ */
+static void
+intel_process_dri2_buffer_no_separate_stencil(struct intel_context *intel,
+					      __DRIdrawable *drawable,
+					      __DRIbuffer *buffer,
+					      struct intel_renderbuffer *rb,
+					      const char *buffer_name)
+{
+   assert(!intel->must_use_separate_stencil);
+
+   struct gl_framebuffer *fb = drawable->driverPrivate;
+   struct intel_region *region = NULL;
+   struct intel_renderbuffer *depth_rb = NULL;
+
+   if (!rb)
+      return;
+
+   if (rb->region && rb->region->name == buffer->name)
+      return;
+
+   if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
+      fprintf(stderr,
+	      "attaching buffer %d, at %d, cpp %d, pitch %d\n",
+	      buffer->name, buffer->attachment,
+	      buffer->cpp, buffer->pitch);
+   }
+
+   bool identify_depth_and_stencil = false;
+   if (buffer->attachment == __DRI_BUFFER_STENCIL) {
+      struct intel_renderbuffer *depth_rb =
+	 intel_get_renderbuffer(fb, BUFFER_DEPTH);
+      identify_depth_and_stencil = depth_rb && depth_rb->region;
+   }
+
+   if (identify_depth_and_stencil) {
+      if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
+	 fprintf(stderr, "(reusing depth buffer as stencil)\n");
+      }
+      intel_region_reference(&region, depth_rb->region);
+   } else {
+      region = intel_region_alloc_for_handle(intel->intelScreen,
+					     buffer->cpp,
+					     drawable->w,
+					     drawable->h,
+					     buffer->pitch / buffer->cpp,
+					     buffer->name,
+					     buffer_name);
+   }
+
+   intel_renderbuffer_set_region(intel, rb, region);
+   intel_region_release(&region);
+
+   if (buffer->attachment == __DRI_BUFFER_DEPTH_STENCIL) {
+      struct intel_renderbuffer *stencil_rb =
+	 intel_get_renderbuffer(fb, BUFFER_STENCIL);
+
+      if (!stencil_rb)
+	 return;
+
+      if (stencil_rb->region && stencil_rb->region->name == buffer->name)
+	 return;
+
+      intel_renderbuffer_set_region(intel, stencil_rb, region);
+   }
+}
-- 
1.7.5.2



More information about the mesa-dev mailing list