st/dri: implement new driver hook flush_with_flags
authorMarek Olšák <maraeo@gmail.com>
Fri, 23 Nov 2012 17:33:54 +0000 (18:33 +0100)
committerMarek Olšák <maraeo@gmail.com>
Sat, 1 Dec 2012 23:19:02 +0000 (00:19 +0100)
v2: added documentation for dri_flush as per Brian's request

src/gallium/state_trackers/dri/common/dri_drawable.c
src/gallium/state_trackers/dri/common/dri_drawable.h
src/gallium/state_trackers/dri/common/dri_screen.h
src/gallium/state_trackers/dri/drm/dri2.c

index 5a261ddb3007cf094d10bd02b445956913711fc6..7e87f87ed67e242e00714fb7c307f5c5b4379f63 100644 (file)
@@ -350,46 +350,88 @@ swap_fences_unref(struct dri_drawable *draw)
    }
 }
 
+/**
+ * DRI2 flush extension, the flush_with_flags function.
+ *
+ * \param context           the context
+ * \param drawable          the drawable to flush
+ * \param flags             a combination of _DRI2_FLUSH_xxx flags
+ * \param throttle_reason   the reason for throttling, 0 = no throttling
+ */
+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);
 }
 
 
index 3e3876e74a572699b79355f27f433e4f3d238b08..6336c81a7155a524eb1bbea22a1beec07f88ab14 100644 (file)
@@ -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
index ff48b0221577b9811e7795ff8420be7e99663c0f..329e70b514c126cf334b3a35f7d1b443af46f876 100644 (file)
@@ -54,6 +54,7 @@ struct dri_screen
 
    /* dri */
    __DRIscreen *sPriv;
+   boolean throttling_enabled;
    int default_throttle_frames;
 
    /**
index 2f83dabf1657b2fb0c847425ab6f5b157aab576a..c346e3b161ccd1908aa081928917a5f37eeeae27 100644 (file)
 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,
 };
 
 /**
@@ -752,14 +743,6 @@ static struct __DRIimageExtensionRec dri2ImageExtension = {
  */
 
 static const __DRIextension *dri_screen_extensions[] = {
-   &driTexBufferExtension.base,
-   &dri2FlushExtension.base,
-   &dri2ImageExtension.base,
-   &dri2ConfigQueryExtension.base,
-   NULL
-};
-
-static const __DRIextension *dri_screen_extensions_throttle[] = {
    &driTexBufferExtension.base,
    &dri2FlushExtension.base,
    &dri2ImageExtension.base,
@@ -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 */