Add vsync swapbuffers. This waits on the irq so gears run in this mode
authorKeith Whitwell <keith@tungstengraphics.com>
Tue, 21 Dec 2004 11:57:03 +0000 (11:57 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Tue, 21 Dec 2004 11:57:03 +0000 (11:57 +0000)
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
src/mesa/drivers/dri/unichrome/via_context.h
src/mesa/drivers/dri/unichrome/via_ioctl.c
src/mesa/drivers/dri/unichrome/via_render.c
src/mesa/drivers/dri/unichrome/via_screen.c
src/mesa/drivers/dri/unichrome/via_screen.h
src/mesa/drivers/dri/unichrome/via_texstate.c

index 54b574c..ca106f0 100644 (file)
@@ -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)
 {
index 54e8660..8805430 100644 (file)
@@ -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
index 1a4c5c4..685a51e 100644 (file)
@@ -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 <sys/ioctl.h>
@@ -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));
index 2b1ba5e..1ea5a53 100644 (file)
@@ -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.
      */
index d84d366..ec2affb 100644 (file)
@@ -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"
 #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;
+}
index e34636d..c70ff44 100644 (file)
@@ -28,6 +28,7 @@
 #include <sys/time.h>
 #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
index 01f31a9..f1db81e 100644 (file)
@@ -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.