aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.c110
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.h6
-rw-r--r--src/gallium/state_trackers/dri/common/dri_screen.h1
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.c28
4 files changed, 89 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 5a261ddb300..7e87f87ed67 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
@@ -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);
}
diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.h b/src/gallium/state_trackers/dri/common/dri_drawable.h
index 3e3876e74a5..6336c81a715 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 ff48b022157..329e70b514c 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 2f83dabf165..c346e3b161c 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 */