summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airliedfreedesktop.org>2006-02-06 00:09:58 +0000
committerDave Airlie <airliedfreedesktop.org>2006-02-06 00:09:58 +0000
commit4cd0e24f86a5e3fa67774be546f922ca241cb0ea (patch)
treef1136bdc585fae8b4510d5383835a4ea5d1be079
parent640ef7f8908a3c25390125f5727d154ca66c9505 (diff)
add vblank support to i915 driver
-rw-r--r--src/mesa/drivers/dri/i915/intel_batchbuffer.c50
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.c22
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.h16
-rw-r--r--src/mesa/drivers/dri/i915/intel_ioctl.c22
-rw-r--r--src/mesa/drivers/dri/i915/intel_ioctl.h4
-rw-r--r--src/mesa/drivers/dri/i915/intel_screen.c52
6 files changed, 150 insertions, 16 deletions
diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c
index 323d0b2212..508900de30 100644
--- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c
@@ -32,6 +32,7 @@
#include "mtypes.h"
#include "context.h"
#include "enums.h"
+#include "vblank.h"
#include "intel_reg.h"
#include "intel_batchbuffer.h"
@@ -329,6 +330,38 @@ GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel,
}
+static void intelWaitForFrameCompletion( intelContextPtr intel )
+{
+ drm_i915_sarea_t *sarea = (drm_i915_sarea_t *)intel->sarea;
+
+ if (intel->do_irqs) {
+ if (intelGetLastFrame(intel) < sarea->last_dispatch) {
+ if (!intel->irqsEmitted) {
+ while (intelGetLastFrame (intel) < sarea->last_dispatch)
+ ;
+ }
+ else {
+ UNLOCK_HARDWARE( intel );
+ intelWaitIrq( intel, intel->alloc.irq_emitted );
+ LOCK_HARDWARE( intel );
+ }
+ intel->irqsEmitted = 10;
+ }
+
+ if (intel->irqsEmitted) {
+ intelEmitIrqLocked( intel );
+ intel->irqsEmitted--;
+ }
+ }
+ else {
+ while (intelGetLastFrame (intel) < sarea->last_dispatch) {
+ UNLOCK_HARDWARE( intel );
+ if (intel->do_usleeps)
+ DO_USLEEP( 1 );
+ LOCK_HARDWARE( intel );
+ }
+ }
+}
/*
* Copy the back buffer to the front buffer.
@@ -336,6 +369,8 @@ GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel,
void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
{
intelContextPtr intel;
+ GLboolean missed_target;
+ int64_t ust;
if (0)
fprintf(stderr, "%s\n", __FUNCTION__);
@@ -347,6 +382,12 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
intelFlush( &intel->ctx );
+
+ LOCK_HARDWARE( intel );
+ intelWaitForFrameCompletion( intel );
+ UNLOCK_HARDWARE( intel );
+ driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target );
+
LOCK_HARDWARE( intel );
{
const intelScreenPrivate *intelScreen = intel->intelScreen;
@@ -412,6 +453,15 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
}
intelFlushBatchLocked( intel, GL_TRUE, GL_TRUE, GL_TRUE );
UNLOCK_HARDWARE( intel );
+
+ intel->swap_count++;
+ (*dri_interface->getUST)(&ust);
+ if (missed_target) {
+ intel->swap_missed_count++;
+ intel->swap_missed_ust = ust - intel->swap_ust;
+ }
+
+ intel->swap_ust = ust;
}
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c
index 60b588e7e0..c79ce9661c 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -55,7 +55,9 @@
#include "intel_ioctl.h"
#include "intel_batchbuffer.h"
+#include "vblank.h"
#include "utils.h"
+#include "xmlpool.h" /* for symbolic values of enum-type options */
#ifndef INTEL_DEBUG
int INTEL_DEBUG = (0);
#endif
@@ -303,6 +305,7 @@ GLboolean intelInitContext( intelContextPtr intel,
intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
drmI830Sarea *saPriv = (drmI830Sarea *)
(((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
+ int fthrottle_mode;
if (!_mesa_initialize_context(&intel->ctx,
mesaVis, shareCtx,
@@ -319,6 +322,9 @@ GLboolean intelInitContext( intelContextPtr intel,
(void) memset( intel->texture_heaps, 0, sizeof( intel->texture_heaps ) );
make_empty_list( & intel->swapped );
+ driParseConfigFiles (&intel->optionCache, &intelScreen->optionCache,
+ intel->driScreen->myNum, "i915");
+
ctx->Const.MaxTextureMaxAnisotropy = 2.0;
ctx->Const.MinLineWidth = 1.0;
@@ -382,9 +388,19 @@ GLboolean intelInitContext( intelContextPtr intel,
intel->RenderIndex = ~0;
+ fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode");
+ intel->iw.irq_seq = -1;
+ intel->irqsEmitted = 0;
+
intel->do_irqs = (intel->intelScreen->irq_active &&
- !getenv("INTEL_NO_IRQS"));
+ fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS);
+
+ intel->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
+
+ intel->vblank_flags = (intel->intelScreen->irq_active != 0)
+ ? driGetDefaultVBlankFlags(&intelScreen->optionCache) : VBLANK_FLAG_NO_IRQ;
+ (*dri_interface->getUST)(&intel->swap_ust);
_math_matrix_ctr (&intel->ViewportMatrix);
driInitExtensions( ctx, card_extensions, GL_TRUE );
@@ -581,6 +597,8 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
if ( intel->driDrawable != driDrawPriv ) {
/* Shouldn't the readbuffer be stored also? */
+ driDrawableInitVBlank( driDrawPriv, intel->vblank_flags );
+
intel->driDrawable = driDrawPriv;
intelWindowMoved( intel );
}
@@ -809,3 +827,5 @@ void intelInitState( GLcontext *ctx )
ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
}
+
+
diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h
index b1c175726d..2f362f9c2f 100644
--- a/src/mesa/drivers/dri/i915/intel_context.h
+++ b/src/mesa/drivers/dri/i915/intel_context.h
@@ -36,6 +36,7 @@
#include "texmem.h"
#include "intel_screen.h"
+#include "i915_drm.h"
#include "i830_common.h"
#include "tnl/t_vertex.h"
@@ -227,7 +228,11 @@ struct intel_context
int dirtyAge;
int perf_boxes;
+
+ GLuint do_usleeps;
int do_irqs;
+ GLuint irqsEmitted;
+ drm_i915_irq_wait_t iw;
GLboolean scissor;
drm_clip_rect_t draw_rect;
@@ -246,6 +251,17 @@ struct intel_context
* Configuration cache
*/
driOptionCache optionCache;
+
+ /* VBI
+ */
+ GLuint vbl_seq;
+ GLuint vblank_flags;
+
+ int64_t swap_ust;
+ int64_t swap_missed_ust;
+
+ GLuint swap_count;
+ GLuint swap_missed_count;
};
diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.c b/src/mesa/drivers/dri/i915/intel_ioctl.c
index 8834f871ee..82ad14ca11 100644
--- a/src/mesa/drivers/dri/i915/intel_ioctl.c
+++ b/src/mesa/drivers/dri/i915/intel_ioctl.c
@@ -40,9 +40,20 @@
#include "intel_batchbuffer.h"
#include "drm.h"
+u_int32_t intelGetLastFrame (intelContextPtr intel)
+{
+ int ret;
+ u_int32_t frame;
+ drm_i915_getparam_t gp;
+
+ gp.param = I915_PARAM_LAST_DISPATCH;
+ gp.value = (int *)&frame;
+ ret = drmCommandWriteRead( intel->driFd, DRM_I915_GETPARAM,
+ &gp, sizeof(gp) );
+ return frame;
+}
-
-static int intelEmitIrqLocked( intelContextPtr intel )
+int intelEmitIrqLocked( intelContextPtr intel )
{
drmI830IrqEmit ie;
int ret, seq;
@@ -65,18 +76,17 @@ static int intelEmitIrqLocked( intelContextPtr intel )
return seq;
}
-static void intelWaitIrq( intelContextPtr intel, int seq )
+void intelWaitIrq( intelContextPtr intel, int seq )
{
- drmI830IrqWait iw;
int ret;
if (0)
fprintf(stderr, "%s %d\n", __FUNCTION__, seq );
- iw.irq_seq = seq;
+ intel->iw.irq_seq = seq;
do {
- ret = drmCommandWrite( intel->driFd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) );
+ ret = drmCommandWrite( intel->driFd, DRM_I830_IRQ_WAIT, &intel->iw, sizeof(intel->iw) );
} while (ret == -EAGAIN || ret == -EINTR);
if ( ret ) {
diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.h b/src/mesa/drivers/dri/i915/intel_ioctl.h
index 07b8a9c8df..099a7e1a44 100644
--- a/src/mesa/drivers/dri/i915/intel_ioctl.h
+++ b/src/mesa/drivers/dri/i915/intel_ioctl.h
@@ -67,5 +67,7 @@ extern GLboolean intelIsAgpMemory( intelContextPtr intel, const GLvoid *pointer,
extern GLuint intelAgpOffsetFromVirtual( intelContextPtr intel, const GLvoid *p );
-
+extern void intelWaitIrq( intelContextPtr intel, int seq );
+extern u_int32_t intelGetLastFrame (intelContextPtr intel);
+extern int intelEmitIrqLocked( intelContextPtr intel );
#endif
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c
index 66dfe34ec9..ed8038ea6d 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -32,6 +32,7 @@
#include "renderbuffer.h"
#include "simple_list.h"
#include "utils.h"
+#include "vblank.h"
#include "xmlpool.h"
@@ -46,12 +47,16 @@
PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN
- DRI_CONF_SECTION_PERFORMANCE
- DRI_CONF_FORCE_S3TC_ENABLE(false)
- DRI_CONF_ALLOW_LARGE_TEXTURES(1)
- DRI_CONF_SECTION_END
+ DRI_CONF_SECTION_PERFORMANCE
+ DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
+ DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
+ DRI_CONF_SECTION_END
+ DRI_CONF_SECTION_QUALITY
+ DRI_CONF_FORCE_S3TC_ENABLE(false)
+ DRI_CONF_ALLOW_LARGE_TEXTURES(1)
+ DRI_CONF_SECTION_END
DRI_CONF_END;
-const GLuint __driNConfigOptions = 2;
+const GLuint __driNConfigOptions = 4;
#ifdef USE_NEW_INTERFACE
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
@@ -330,6 +335,10 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
}
if (glx_enable_extension != NULL) {
+ (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
+ (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
+ (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
+ (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
(*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
(*glx_enable_extension)( psc, "GLX_MESA_allocate_memory" );
}
@@ -440,6 +449,33 @@ static void intelDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
}
+/**
+ * Get information about previous buffer swaps.
+ */
+static int
+intelGetSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
+{
+ intelContextPtr intel;
+
+ if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
+ || (dPriv->driContextPriv->driverPrivate == NULL)
+ || (sInfo == NULL) ) {
+ return -1;
+ }
+
+ intel = dPriv->driContextPriv->driverPrivate;
+ sInfo->swap_count = intel->swap_count;
+ sInfo->swap_ust = intel->swap_ust;
+ sInfo->swap_missed_count = intel->swap_missed_count;
+
+ sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
+ ? driCalculateSwapUsage( dPriv, 0, intel->swap_missed_ust )
+ : 0.0;
+
+ return 0;
+}
+
+
/* There are probably better ways to do this, such as an
* init-designated function to register chipids and createcontext
* functions.
@@ -494,9 +530,9 @@ static const struct __DriverAPIRec intelAPI = {
.SwapBuffers = intelSwapBuffers,
.MakeCurrent = intelMakeCurrent,
.UnbindContext = intelUnbindContext,
- .GetSwapInfo = NULL,
- .GetMSC = NULL,
- .WaitForMSC = NULL,
+ .GetSwapInfo = intelGetSwapInfo,
+ .GetMSC = driGetMSC32,
+ .WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
};