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