From 3039addf9363dbae1bbad1cd75d32e0013038c08 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 23 Nov 2012 18:33:54 +0100 Subject: [PATCH] st/dri: implement new driver hook flush_with_flags v2: added documentation for dri_flush as per Brian's request --- .../state_trackers/dri/common/dri_drawable.c | 110 ++++++++++++------ .../state_trackers/dri/common/dri_drawable.h | 6 + .../state_trackers/dri/common/dri_screen.h | 1 + src/gallium/state_trackers/dri/drm/dri2.c | 28 +---- 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, }; /** @@ -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 */ -- 2.30.2