This fixes jerkiness in doom3 and other apps since the kernel change to
throttle less absurdly, which led to a thundering herd of frames.
---
 include/GL/internal/dri_interface.h            |   12 ++++++++++++
 src/glx/x11/dri2_glx.c                         |    5 +++++
 src/glx/x11/dri_common.c                       |    7 +++++++
 src/glx/x11/glxclient.h                        |    4 ++++
 src/mesa/drivers/dri/intel/intel_batchbuffer.c |    5 +++++
 src/mesa/drivers/dri/intel/intel_context.h     |    1 +
 src/mesa/drivers/dri/intel/intel_screen.c      |    6 ++++++
 src/mesa/drivers/dri/intel/intel_swapbuffers.c |   22 ++++++++++++++++++++++
 src/mesa/drivers/dri/intel/intel_swapbuffers.h |    2 ++
 9 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/include/GL/internal/dri_interface.h 
b/include/GL/internal/dri_interface.h
index 910c916..cca0369 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -79,6 +79,7 @@ typedef struct __DRIbufferRec                 __DRIbuffer;
 typedef struct __DRIdri2ExtensionRec           __DRIdri2Extension;
 typedef struct __DRIdri2LoaderExtensionRec     __DRIdri2LoaderExtension;
 typedef struct __DRI2flushExtensionRec __DRI2flushExtension;
+typedef struct __DRI2postswapbuffersExtensionRec 
__DRI2postswapbuffersExtension;
 
 /*...@}*/
 
@@ -268,6 +269,17 @@ struct __DRI2flushExtensionRec {
     void (*flush)(__DRIdrawable *drawable);
 };
 
+/**
+ * Used by drivers that implement DRI2, called after a SwapBuffers is done
+ * in case the driver wants to do some throttling.
+ */
+#define __DRI2_POST_SWAPBUFFERS "DRI2_PostSwapbuffers"
+#define __DRI2_POST_SWAPBUFFERS_VERSION 1
+struct __DRI2postswapbuffersExtensionRec {
+    __DRIextension base;
+    void (*post_swapbuffers)(__DRIdrawable *drawable);
+};
+
 
 /**
  * XML document describing the configuration options supported by the
diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c
index f4865ae..de59fd8 100644
--- a/src/glx/x11/dri2_glx.c
+++ b/src/glx/x11/dri2_glx.c
@@ -229,6 +229,11 @@ static void dri2SwapBuffers(__GLXDRIdrawable *pdraw)
     __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
 
     dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
+
+#ifdef __DRI2_POSTSWAPBUFFERS
+    if (pdraw->psc->dri2_postswapbuffers)
+       
(*pdraw->psc->dri2_postswapbuffers->postswapbuffers)(pdraw->driDrawable);
+#endif
 }
 
 static void dri2WaitX(__GLXDRIdrawable *pdraw)
diff --git a/src/glx/x11/dri_common.c b/src/glx/x11/dri_common.c
index 6de4111..632bbf8 100644
--- a/src/glx/x11/dri_common.c
+++ b/src/glx/x11/dri_common.c
@@ -401,6 +401,13 @@ driBindExtensions(__GLXscreenConfigs *psc, int dri2)
        }
 #endif
 
+#ifdef __DRI2_POSTSWAPBUFFERS
+       if ((strcmp(extensions[i]->name, __DRI2_POSTSWAPBUFFERS) == 0) && dri2) 
{
+           psc->f = (__DRI2flushExtension *) extensions[i];
+           /* internal driver extension, no GL extension exposed */
+       }
+#endif
+
        /* Ignore unknown extensions */
     }
 }
diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
index bf68d0f..9d230bf 100644
--- a/src/glx/x11/glxclient.h
+++ b/src/glx/x11/glxclient.h
@@ -529,6 +529,10 @@ struct __GLXscreenConfigsRec {
     const __DRI2flushExtension *f;
 #endif
 
+#ifdef __DRI2_FLUSH
+    const __DRI2postswapbuffersExtension *dri2_postswapbuffers;
+#endif
+
 #endif
 
     /**
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c 
b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index 0f87fc4..e94b836 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -196,6 +196,11 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, 
const char *file,
    struct intel_context *intel = batch->intel;
    GLuint used = batch->ptr - batch->map;
 
+   if (intel->first_post_swapbuffers_batch == NULL) {
+      intel->first_post_swapbuffers_batch = intel->batch->buf;
+      drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
+   }
+
    if (used == 0) {
       batch->cliprect_mode = IGNORE_CLIPRECTS;
       return;
diff --git a/src/mesa/drivers/dri/intel/intel_context.h 
b/src/mesa/drivers/dri/intel/intel_context.h
index 08bea88..e93eb1f 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -178,6 +178,7 @@ struct intel_context
    GLboolean ttm;
 
    struct intel_batchbuffer *batch;
+   drm_intel_bo *first_post_swapbuffers_batch;
    GLboolean no_batch_wrap;
    unsigned batch_id;
 
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c 
b/src/mesa/drivers/dri/intel/intel_screen.c
index 6bbc995..8154e65 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -225,6 +225,11 @@ static const __DRItexBufferExtension 
intelTexBufferExtension = {
    intelSetTexBuffer2,
 };
 
+static const __DRI2postswapbuffersExtension intelPostSwapbuffersExtension = {
+    { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+   intel_dri2_post_swapbuffers,
+};
+
 static const __DRIextension *intelScreenExtensions[] = {
     &driReadDrawableExtension,
     &driCopySubBufferExtension.base,
@@ -233,6 +238,7 @@ static const __DRIextension *intelScreenExtensions[] = {
     &driMediaStreamCounterExtension.base,
     &intelTexOffsetExtension.base,
     &intelTexBufferExtension.base,
+    &intelPostSwapbuffersExtension.base,
     NULL
 };
 
diff --git a/src/mesa/drivers/dri/intel/intel_swapbuffers.c 
b/src/mesa/drivers/dri/intel/intel_swapbuffers.c
index 7d035b9..b230049 100644
--- a/src/mesa/drivers/dri/intel/intel_swapbuffers.c
+++ b/src/mesa/drivers/dri/intel/intel_swapbuffers.c
@@ -246,3 +246,25 @@ intelWindowMoved(struct intel_context *intel)
    if (ctx->Driver.DepthRange != NULL)
       ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far );
 }
+
+void
+intel_dri2_post_swapbuffers(__DRIdrawablePrivate *dPriv)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct intel_context *intel = intel_context(ctx);
+
+   /* Wait for the swapbuffers before the one we just emitted, so we don't
+    * get too many swaps outstanding for apps that are GPU-heavy but not
+    * CPU-heavy.
+    *
+    * Unfortunately, we don't have a handle to the batch containing the swap,
+    * and getting our hands on that doesn't seem worth it, so we just us the
+    * first batch we emitted after the last swap.
+    */
+   if (intel->first_post_swapbuffers_batch != NULL) {
+      drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
+      drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
+      intel->first_post_swapbuffers_batch = NULL;
+   }
+}
+
diff --git a/src/mesa/drivers/dri/intel/intel_swapbuffers.h 
b/src/mesa/drivers/dri/intel/intel_swapbuffers.h
index 75bb624..6d748f6 100644
--- a/src/mesa/drivers/dri/intel/intel_swapbuffers.h
+++ b/src/mesa/drivers/dri/intel/intel_swapbuffers.h
@@ -48,5 +48,7 @@ intelFixupVblank(struct intel_context *intel, 
__DRIdrawablePrivate *dPriv);
 extern void
 intelWindowMoved(struct intel_context *intel);
 
+void
+intel_dri2_post_swapbuffers(__DRIdrawablePrivate *dPriv);
 
 #endif /* INTEL_SWAPBUFFERS_H */
-- 
1.6.3.3


------------------------------------------------------------------------------
_______________________________________________
Mesa3d-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to