From 314f8e4d9d600f9db95977ebf931a3fb9bb8ce79 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 21 Dec 2004 11:57:03 +0000 Subject: Add vsync swapbuffers. This waits on the irq so gears run in this mode will have a very low cpu utilization (and also a very low framerate). Fix up the pageflipping code. This works now but is totally oblivious to the X server (ie. it works but it's broken). Turned off by a #define. --- src/mesa/drivers/dri/unichrome/via_context.c | 52 +++++++++- src/mesa/drivers/dri/unichrome/via_context.h | 16 +++ src/mesa/drivers/dri/unichrome/via_ioctl.c | 51 +++++++++- src/mesa/drivers/dri/unichrome/via_render.c | 2 +- src/mesa/drivers/dri/unichrome/via_screen.c | 138 ++++++++++++++++++-------- src/mesa/drivers/dri/unichrome/via_screen.h | 5 + src/mesa/drivers/dri/unichrome/via_texstate.c | 1 + 7 files changed, 215 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c index 54b574c60c..ca106f0ad5 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.c +++ b/src/mesa/drivers/dri/unichrome/via_context.c @@ -62,6 +62,7 @@ #define DRIVER_DATE "20041215" +#include "vblank.h" #include "utils.h" viaContextPtr current_mesa; @@ -230,9 +231,14 @@ calculate_buffer_parameters( viaContextPtr vmesa ) vmesa->depth.size); /*=* John Sheng [2003.5.31] flip *=*/ - if( (vmesa->viaScreen->width == vmesa->driDrawable->w) - && (vmesa->viaScreen->height == vmesa->driDrawable->h) ) { + if( vmesa->viaScreen->width == vmesa->driDrawable->w && + vmesa->viaScreen->height == vmesa->driDrawable->h ) { +#define ALLOW_EXPERIMENTAL_PAGEFLIP 1 +#if ALLOW_EXPERIMENTAL_PAGEFLIP + vmesa->doPageFlip = GL_TRUE; +#else vmesa->doPageFlip = GL_FALSE; +#endif vmesa->currentPage = 0; vmesa->back.pitch = vmesa->front.pitch; } @@ -368,6 +374,13 @@ FreeBuffer(viaContextPtr vmesa) via_free_dma_buffer(vmesa); } +static int +get_ust_nop( int64_t * ust ) +{ + *ust = 1; + return 0; +} + GLboolean viaCreateContext(const __GLcontextModes *mesaVis, __DRIcontextPrivate *driContextPriv, @@ -387,6 +400,12 @@ viaCreateContext(const __GLcontextModes *mesaVis, return GL_FALSE; } if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); + + /* Parse configuration files. + */ + driParseConfigFiles (&vmesa->optionCache, &viaScreen->optionCache, + sPriv->myNum, "via"); + current_mesa = vmesa; /* pick back buffer */ if (mesaVis->doubleBufferMode) { @@ -555,6 +574,24 @@ viaCreateContext(const __GLcontextModes *mesaVis, } #endif + /* I don't understand why this isn't working: + */ + vmesa->vblank_flags = + vmesa->viaScreen->irqEnabled ? + driGetDefaultVBlankFlags(&vmesa->optionCache) : VBLANK_FLAG_NO_IRQ; + + /* Hack this up in its place: + */ + vmesa->vblank_flags = getenv("VIA_VSYNC") ? VBLANK_FLAG_SYNC : VBLANK_FLAG_NO_IRQ; + + + vmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( (const GLubyte *) "__glXGetUST" ); + if ( vmesa->get_ust == NULL ) { + vmesa->get_ust = get_ust_nop; + } + (*vmesa->get_ust)( & vmesa->swap_ust ); + + if (!AllocateDmaBuffer(mesaVis, vmesa)) { fprintf(stderr ,"AllocateDmaBuffer fail\n"); FREE(vmesa); @@ -894,9 +931,12 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv, if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent: w = %d\n", vmesa->driDrawable->w); - vmesa->driDrawable = driDrawPriv; - if ( ! calculate_buffer_parameters( vmesa ) ) { - return GL_FALSE; + if ( vmesa->driDrawable != driDrawPriv ) { + driDrawableInitVBlank( driDrawPriv, vmesa->vblank_flags ); + vmesa->driDrawable = driDrawPriv; + if ( ! calculate_buffer_parameters( vmesa ) ) { + return GL_FALSE; + } } _mesa_make_current2(vmesa->glCtx, @@ -938,6 +978,7 @@ void viaGetLock(viaContextPtr vmesa, GLuint flags) if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); } +#if 0 void viaLock(viaContextPtr vmesa, GLuint flags) { __DRIdrawablePrivate *dPriv = vmesa->driDrawable; @@ -968,6 +1009,7 @@ void viaLock(viaContextPtr vmesa, GLuint flags) return; } +#endif void viaUnLock(viaContextPtr vmesa, GLuint flags) { diff --git a/src/mesa/drivers/dri/unichrome/via_context.h b/src/mesa/drivers/dri/unichrome/via_context.h index 54e86605d5..88054301e8 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.h +++ b/src/mesa/drivers/dri/unichrome/via_context.h @@ -291,6 +291,22 @@ struct via_context_t { volatile GLuint* regTranSpace; GLuint* agpBase; GLuint drawType; + + /* Configuration cache + */ + driOptionCache optionCache; + + GLuint vblank_flags; + GLuint vbl_seq; + + int64_t swap_ust; + int64_t swap_missed_ust; + + GLuint swap_count; + GLuint swap_missed_count; + + PFNGLXGETUSTPROC get_ust; + }; /*#define DMA_OFFSET 16*/ #define DMA_OFFSET 32 diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c index 1a4c5c494d..685a51ea42 100644 --- a/src/mesa/drivers/dri/unichrome/via_ioctl.c +++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c @@ -35,6 +35,7 @@ v * copy of this software and associated documentation files (the "Software"), #include "via_ioctl.h" #include "via_state.h" +#include "vblank.h" #include "drm.h" #include "xf86drm.h" #include @@ -316,6 +317,9 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv) drm_clip_rect_t *pbox; int nbox, i; GLuint scrn = 0, side = 0; + GLboolean missed_target; + int64_t ust; + if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__); assert(dPriv); assert(dPriv->driContextPriv); @@ -324,6 +328,8 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv) vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate; VIA_FIREVERTICES(vmesa); + + driWaitForVBlank( dPriv, & vmesa->vbl_seq, vmesa->vblank_flags, & missed_target ); LOCK_HARDWARE(vmesa); scrn = vmesa->saam & S_MASK; @@ -400,6 +406,16 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv) } UNLOCK_HARDWARE(vmesa); vmesa->uploadCliprects = GL_TRUE; + + vmesa->swap_count++; + (*vmesa->get_ust)( & ust ); + if ( missed_target ) { + vmesa->swap_missed_count++; + vmesa->swap_missed_ust = ust - vmesa->swap_ust; + } + + vmesa->swap_ust = ust; + if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__); } @@ -414,6 +430,8 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv) GLuint nBackBase; viaBuffer buffer_tmp; GLcontext *ctx; + GLboolean missed_target; + int retcode; if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); assert(dPriv); @@ -426,6 +444,29 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv) if(DRAW_FRONT) return; + VIA_FIREVERTICES(vmesa); + + /* Now wait for the vblank: + */ + retcode = driWaitForVBlank( dPriv, &vmesa->vbl_seq, + vmesa->vblank_flags, &missed_target ); + if ( missed_target ) { + vmesa->swap_missed_count++; + (void) (*vmesa->get_ust)( &vmesa->swap_missed_ust ); + } + + if (missed_target) + fprintf(stderr, "missed target\n"); +/* else */ +/* fprintf(stderr, "retcode %d vbl_seq %d vblank_flags %x missed_target %d\n", */ +/* retcode, vmesa->vbl_seq, vmesa->vblank_flags, missed_target); */ + + + + + LOCK_HARDWARE(vmesa); + + /* Page Flip*/ if(GL_FALSE) { viaFlushPrimsLocked(vmesa); @@ -454,17 +495,17 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv) /* Auto Swap */ else { viaFlushPrimsLocked(vmesa); - vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56); - if (nFirstSwap) { + vb = viaCheckDma(vmesa, 8 * 4); + if (nFirstFlip) { *vb++ = HALCYON_HEADER2; *vb++ = 0x00fe0000; *vb++ = 0x0000000e; *vb++ = 0x0000000e; vmesa->dmaLow += 16; - nFirstSwap = GL_FALSE; + nFirstFlip = GL_FALSE; } - nBackBase = (vmesa->back.offset << 1); + nBackBase = (vmesa->back.offset ); *vb++ = HALCYON_HEADER2; *vb++ = 0x00fe0000; @@ -475,6 +516,8 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv) viaFlushPrimsLocked(vmesa); } + UNLOCK_HARDWARE(vmesa); + vmesa->uploadCliprects = GL_TRUE; memcpy(&buffer_tmp, &vmesa->back, sizeof(viaBuffer)); memcpy(&vmesa->back, &vmesa->front, sizeof(viaBuffer)); diff --git a/src/mesa/drivers/dri/unichrome/via_render.c b/src/mesa/drivers/dri/unichrome/via_render.c index 2b1ba5eb9f..1ea5a53cc5 100644 --- a/src/mesa/drivers/dri/unichrome/via_render.c +++ b/src/mesa/drivers/dri/unichrome/via_render.c @@ -137,7 +137,7 @@ static GLboolean via_run_fastrender(GLcontext *ctx, viaContextPtr vmesa = VIA_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; - GLuint i, length, flags = 0; + GLuint i; /* Don't handle clipping or indexed vertices. */ diff --git a/src/mesa/drivers/dri/unichrome/via_screen.c b/src/mesa/drivers/dri/unichrome/via_screen.c index d84d366934..ec2affb333 100644 --- a/src/mesa/drivers/dri/unichrome/via_screen.c +++ b/src/mesa/drivers/dri/unichrome/via_screen.c @@ -30,6 +30,7 @@ #include "context.h" #include "matrix.h" #include "simple_list.h" +#include "vblank.h" #include "via_state.h" #include "via_tex.h" @@ -38,14 +39,34 @@ #include "via_ioctl.h" #include "via_screen.h" #include "via_fb.h" - #include "via_dri.h" + +#include "GL/internal/dri_interface.h" + +/* Radeon configuration + */ +#include "xmlpool.h" + +const char __driConfigOptions[] = +DRI_CONF_BEGIN + 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_DEBUG + DRI_CONF_NO_RAST(false) + DRI_CONF_SECTION_END +DRI_CONF_END; +static const GLuint __driNConfigOptions = 3; + + extern viaContextPtr current_mesa; #ifdef USE_NEW_INTERFACE static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; #endif /* USE_NEW_INTERFACE */ +static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ); static drmBufMapPtr via_create_empty_buffers(void) { @@ -79,6 +100,11 @@ viaInitDriver(__DRIscreenPrivate *sPriv) return GL_FALSE; } + /* parse information in __driConfigOptions */ + driParseOptionInfo (&viaScreen->optionCache, + __driConfigOptions, __driNConfigOptions); + + viaScreen->driScrnPriv = sPriv; sPriv->private = (void *)viaScreen; @@ -90,6 +116,9 @@ viaInitDriver(__DRIscreenPrivate *sPriv) viaScreen->bytesPerPixel = gDRIPriv->bytesPerPixel; viaScreen->fbOffset = 0; viaScreen->fbSize = gDRIPriv->fbSize; + viaScreen->irqEnabled = gDRIPriv->irqEnabled; + viaScreen->irqEnabled = 1; + #ifdef USE_XINERAMA viaScreen->drixinerama = gDRIPriv->drixinerama; #endif @@ -141,6 +170,33 @@ viaInitDriver(__DRIscreenPrivate *sPriv) viaScreen->agpLinearStart = 0; viaScreen->sareaPrivOffset = gDRIPriv->sarea_priv_offset; + + + + if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) { + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" ); + void * const psc = sPriv->psc->screenConfigs; + + if ( glx_enable_extension != NULL ) { + if ( viaScreen->irqEnabled ) { + (*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" ); + + if ( driCompareGLXAPIVersion( 20030915 ) >= 0 ) { + (*glx_enable_extension)( psc, "GLX_SGIX_fbconfig" ); + (*glx_enable_extension)( psc, "GLX_OML_swap_method" ); + } + + } + } + + + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); return GL_TRUE; } @@ -219,47 +275,22 @@ viaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) } -#if 0 -/* Initialize the fullscreen mode. - */ -GLboolean -XMesaOpenFullScreen(__DRIcontextPrivate *driContextPriv) -{ - viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate; - vmesa->doPageFlip = 1; - vmesa->currentPage = 0; - return GL_TRUE; -} - -/* Shut down the fullscreen mode. - */ -GLboolean -XMesaCloseFullScreen(__DRIcontextPrivate *driContextPriv) -{ - viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate; - - if (vmesa->currentPage == 1) { - viaPageFlip(vmesa); - vmesa->currentPage = 0; - } - - vmesa->doPageFlip = GL_FALSE; - vmesa->Setup[VIA_DESTREG_DI0] = vmesa->driScreen->front_offset; - return GL_TRUE; -} -#endif - static struct __DriverAPIRec viaAPI = { - viaInitDriver, - viaDestroyScreen, - viaCreateContext, - viaDestroyContext, - viaCreateBuffer, - viaDestroyBuffer, - viaSwapBuffers, - viaMakeCurrent, - viaUnbindContext + .InitDriver = viaInitDriver, + .DestroyScreen = viaDestroyScreen, + .CreateContext = viaCreateContext, + .DestroyContext = viaDestroyContext, + .CreateBuffer = viaCreateBuffer, + .DestroyBuffer = viaDestroyBuffer, + .SwapBuffers = viaSwapBuffers, + .MakeCurrent = viaMakeCurrent, + .UnbindContext = viaUnbindContext, + .GetSwapInfo = getSwapInfo, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL }; @@ -395,3 +426,30 @@ void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc return (void *) psp; } #endif /* USE_NEW_INTERFACE */ + + +/** + * Get information about previous buffer swaps. + */ +static int +getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ) +{ + viaContextPtr vmesa; + + if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL) + || (dPriv->driContextPriv->driverPrivate == NULL) + || (sInfo == NULL) ) { + return -1; + } + + vmesa = (viaContextPtr) dPriv->driContextPriv->driverPrivate; + sInfo->swap_count = vmesa->swap_count; + sInfo->swap_ust = vmesa->swap_ust; + sInfo->swap_missed_count = vmesa->swap_missed_count; + + sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0) + ? driCalculateSwapUsage( dPriv, 0, vmesa->swap_missed_ust ) + : 0.0; + + return 0; +} diff --git a/src/mesa/drivers/dri/unichrome/via_screen.h b/src/mesa/drivers/dri/unichrome/via_screen.h index e34636df7e..c70ff447fd 100644 --- a/src/mesa/drivers/dri/unichrome/via_screen.h +++ b/src/mesa/drivers/dri/unichrome/via_screen.h @@ -28,6 +28,7 @@ #include #include "dri_util.h" #include "via_dri.h" +#include "xmlconfig.h" typedef struct { viaRegion regs; @@ -68,6 +69,10 @@ typedef struct { unsigned int sareaPrivOffset; /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/ int VQEnable; + int irqEnabled; + + /* Configuration cache with default values for all contexts */ + driOptionCache optionCache; } viaScreenPrivate; extern GLboolean diff --git a/src/mesa/drivers/dri/unichrome/via_texstate.c b/src/mesa/drivers/dri/unichrome/via_texstate.c index 01f31a9e13..f1db81eaf3 100644 --- a/src/mesa/drivers/dri/unichrome/via_texstate.c +++ b/src/mesa/drivers/dri/unichrome/via_texstate.c @@ -206,6 +206,7 @@ static void viaSetTexImages(viaContextPtr vmesa, default: _mesa_problem(vmesa->glCtx, "Bad texture format in viaSetTexImages"); fprintf(stderr, "-- TexFormat = %d\n",baseImage->TexFormat->MesaFormat); + return; }; /* Compute which mipmap levels we really want to send to the hardware. -- cgit v1.2.3