From 4cd0e24f86a5e3fa67774be546f922ca241cb0ea Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 6 Feb 2006 00:09:58 +0000 Subject: [PATCH] add vblank support to i915 driver --- src/mesa/drivers/dri/i915/intel_batchbuffer.c | 50 ++++++++++++++++++++++++++ src/mesa/drivers/dri/i915/intel_context.c | 22 +++++++++++- src/mesa/drivers/dri/i915/intel_context.h | 16 +++++++++ src/mesa/drivers/dri/i915/intel_ioctl.c | 22 ++++++++---- src/mesa/drivers/dri/i915/intel_ioctl.h | 4 ++- src/mesa/drivers/dri/i915/intel_screen.c | 52 ++++++++++++++++++++++----- 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 323d0b2..508900d 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 60b588e..c79ce96 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 b1c1757..2f362f9 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 8834f87..82ad14c 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 07b8a9c..099a7e1 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 66dfe34..ed8038e 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 }; -- 2.7.4