[Mesa-dev] [PATCH 4/4] st/dri: implement new driver hook flush_with_flags

Marek Olšák maraeo at gmail.com
Fri Nov 23 11:35:35 PST 2012


---
 .../state_trackers/dri/common/dri_drawable.c       |  105 +++++++++++++-------
 .../state_trackers/dri/common/dri_drawable.h       |    6 ++
 src/gallium/state_trackers/dri/common/dri_screen.h |    1 +
 src/gallium/state_trackers/dri/drm/dri2.c          |   28 ++----
 4 files changed, 84 insertions(+), 56 deletions(-)

diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c
index 5a261dd..deef003 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
@@ -350,46 +350,83 @@ swap_fences_unref(struct dri_drawable *draw)
    }
 }
 
+/**
+ * DRI2 flush extension, the flush_with_flags function.
+ */
+void
+dri_flush(__DRIcontext *cPriv,
+          __DRIdrawable *dPriv,
+          unsigned flags,
+          enum __DRI2throttleReason reason)
+{
+   struct dri_context *ctx = dri_context(cPriv);
+   struct dri_drawable *drawable = dri_drawable(dPriv);
+   unsigned flush_flags;
+
+   if (!ctx) {
+      assert(0);
+      return;
+   }
+
+   if (!drawable) {
+      flags &= ~__DRI2_FLUSH_DRAWABLE;
+   }
+
+   /* Flush the drawable. */
+   if (flags & __DRI2_FLUSH_DRAWABLE) {
+      struct pipe_resource *ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
+
+      if (ptex && ctx->pp && drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL])
+         pp_run(ctx->pp, ptex, ptex, drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]);
+   }
+
+   flush_flags = 0;
+   if (flags & __DRI2_FLUSH_CONTEXT)
+      flush_flags |= ST_FLUSH_FRONT;
+
+   /* Flush the context and throttle if needed. */
+   if (dri_screen(ctx->sPriv)->throttling_enabled &&
+       (reason == __DRI2_THROTTLE_SWAPBUFFER ||
+        reason == __DRI2_THROTTLE_FLUSHFRONT)) {
+      /* Throttle.
+       *
+       * This pulls a fence off the throttling queue and waits for it if the
+       * number of fences on the throttling queue has reached the desired
+       * number.
+       *
+       * Then flushes to insert a fence at the current rendering position, and
+       * pushes that fence on the queue. This requires that the st_context_iface
+       * flush method returns a fence even if there are no commands to flush.
+       */
+      struct dri_drawable *draw = dri_drawable(dPriv);
+      struct pipe_screen *screen = draw->screen->base.screen;
+      struct pipe_fence_handle *fence;
+
+      fence = swap_fences_pop_front(draw);
+      if (fence) {
+         (void) screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
+         screen->fence_reference(screen, &fence, NULL);
+      }
+
+      ctx->st->flush(ctx->st, flush_flags, &fence);
+      if (fence) {
+         swap_fences_push_back(draw, fence);
+         screen->fence_reference(screen, &fence, NULL);
+      }
+   }
+   else if (flags & (__DRI2_FLUSH_DRAWABLE | __DRI2_FLUSH_CONTEXT)) {
+      ctx->st->flush(ctx->st, flush_flags, NULL);
+   }
+}
 
 /**
  * dri_throttle - A DRI2ThrottleExtension throttling function.
- *
- * pulls a fence off the throttling queue and waits for it if the
- * number of fences on the throttling queue has reached the desired
- * number.
- *
- * Then flushes to insert a fence at the current rendering position, and
- * pushes that fence on the queue. This requires that the st_context_iface
- * flush method returns a fence even if there are no commands to flush.
  */
 static void
-dri_throttle(__DRIcontext *driCtx, __DRIdrawable *dPriv,
-	     enum __DRI2throttleReason reason)
+dri_throttle(__DRIcontext *cPriv, __DRIdrawable *dPriv,
+             enum __DRI2throttleReason reason)
 {
-    struct dri_drawable *draw = dri_drawable(dPriv);
-    struct st_context_iface *ctxi;
-    struct pipe_screen *screen = draw->screen->base.screen;
-    struct pipe_fence_handle *fence;
-
-    if (reason != __DRI2_THROTTLE_SWAPBUFFER &&
-	reason != __DRI2_THROTTLE_FLUSHFRONT)
-	return;
-
-    fence = swap_fences_pop_front(draw);
-    if (fence) {
-	(void) screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
-	screen->fence_reference(screen, &fence, NULL);
-    }
-
-    if (driCtx == NULL)
-	return;
-
-    ctxi = dri_context(driCtx)->st;
-    ctxi->flush(ctxi, 0, &fence);
-    if (fence) {
-	swap_fences_push_back(draw, fence);
-	screen->fence_reference(screen, &fence, NULL);
-    }
+   dri_flush(cPriv, dPriv, 0, reason);
 }
 
 
diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.h b/src/gallium/state_trackers/dri/common/dri_drawable.h
index 3e3876e..6336c81 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.h
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.h
@@ -106,6 +106,12 @@ dri_drawable_get_format(struct dri_drawable *drawable,
                         enum pipe_format *format,
                         unsigned *bind);
 
+void
+dri_flush(__DRIcontext *cPriv,
+          __DRIdrawable *dPriv,
+          unsigned flags,
+          enum __DRI2throttleReason reason);
+
 extern const __DRItexBufferExtension driTexBufferExtension;
 extern const __DRI2throttleExtension dri2ThrottleExtension;
 #endif
diff --git a/src/gallium/state_trackers/dri/common/dri_screen.h b/src/gallium/state_trackers/dri/common/dri_screen.h
index ff48b02..329e70b 100644
--- a/src/gallium/state_trackers/dri/common/dri_screen.h
+++ b/src/gallium/state_trackers/dri/common/dri_screen.h
@@ -54,6 +54,7 @@ struct dri_screen
 
    /* dri */
    __DRIscreen *sPriv;
+   boolean throttling_enabled;
    int default_throttle_frames;
 
    /**
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index 2f83dab..c346e3b 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -46,17 +46,7 @@
 static void
 dri2_flush_drawable(__DRIdrawable *dPriv)
 {
-   struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv);
-   struct dri_drawable *drawable = dri_drawable(dPriv);
-
-   struct pipe_resource *ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
-
-   if (ctx) {
-      if (ptex && ctx->pp && drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL])
-         pp_run(ctx->pp, ptex, ptex, drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]);
-
-      ctx->st->flush(ctx->st, 0, NULL);
-   }
+   dri_flush(dPriv->driContextPriv, dPriv, __DRI2_FLUSH_DRAWABLE, 0);
 }
 
 static void
@@ -74,6 +64,7 @@ static const __DRI2flushExtension dri2FlushExtension = {
     { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
     dri2_flush_drawable,
     dri2_invalidate_drawable,
+    dri_flush,
 };
 
 /**
@@ -756,14 +747,6 @@ static const __DRIextension *dri_screen_extensions[] = {
    &dri2FlushExtension.base,
    &dri2ImageExtension.base,
    &dri2ConfigQueryExtension.base,
-   NULL
-};
-
-static const __DRIextension *dri_screen_extensions_throttle[] = {
-   &driTexBufferExtension.base,
-   &dri2FlushExtension.base,
-   &dri2ImageExtension.base,
-   &dri2ConfigQueryExtension.base,
    &dri2ThrottleExtension.base,
    NULL
 };
@@ -795,10 +778,11 @@ dri2_init_screen(__DRIscreen * sPriv)
       throttle_ret = driver_descriptor.configuration(DRM_CONF_THROTTLE);
 
    if (throttle_ret && throttle_ret->val.val_int != -1) {
-      sPriv->extensions = dri_screen_extensions_throttle;
+      screen->throttling_enabled = TRUE;
       screen->default_throttle_frames = throttle_ret->val.val_int;
-   } else
-      sPriv->extensions = dri_screen_extensions;
+   }
+
+   sPriv->extensions = dri_screen_extensions;
 
    /* dri_init_screen_helper checks pscreen for us */
 
-- 
1.7.10.4



More information about the mesa-dev mailing list