Add Rage 128 pageflipping support, defaults to off. DRM version bump to
authorEric Anholt <anholt@freebsd.org>
Sat, 26 Jul 2003 03:25:40 +0000 (03:25 +0000)
committerEric Anholt <anholt@freebsd.org>
Sat, 26 Jul 2003 03:25:40 +0000 (03:25 +0000)
    2.5.0. It still has some issues, including a flicker in the fps meter
    in tuxracer and I've seen garbage left behind after moving/closing
    windows. However, it's usable. Add the Option "EnablePageFlip" "YES" to
    use it.

shared-core/r128_cce.c
shared-core/r128_drm.h
shared-core/r128_drv.h
shared-core/r128_state.c
shared/r128.h
shared/r128_cce.c
shared/r128_drm.h
shared/r128_drv.h
shared/r128_state.c

index 1549e68..3cc0ff5 100644 (file)
@@ -782,59 +782,8 @@ int r128_engine_reset( DRM_IOCTL_ARGS )
        return r128_do_engine_reset( dev );
 }
 
-
-/* ================================================================
- * Fullscreen mode
- */
-
-static int r128_do_init_pageflip( drm_device_t *dev )
-{
-       drm_r128_private_t *dev_priv = dev->dev_private;
-       DRM_DEBUG( "\n" );
-
-       dev_priv->crtc_offset =      R128_READ( R128_CRTC_OFFSET );
-       dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL );
-
-       R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset );
-       R128_WRITE( R128_CRTC_OFFSET_CNTL,
-                   dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL );
-
-       dev_priv->page_flipping = 1;
-       dev_priv->current_page = 0;
-
-       return 0;
-}
-
-int r128_do_cleanup_pageflip( drm_device_t *dev )
-{
-       drm_r128_private_t *dev_priv = dev->dev_private;
-       DRM_DEBUG( "\n" );
-
-       R128_WRITE( R128_CRTC_OFFSET,      dev_priv->crtc_offset );
-       R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
-
-       dev_priv->page_flipping = 0;
-       dev_priv->current_page = 0;
-
-       return 0;
-}
-
 int r128_fullscreen( DRM_IOCTL_ARGS )
 {
-       DRM_DEVICE;
-       drm_r128_fullscreen_t fs;
-
-       LOCK_TEST_WITH_RETURN( dev, filp );
-
-       DRM_COPY_FROM_USER_IOCTL( fs, (drm_r128_fullscreen_t *)data, sizeof(fs) );
-
-       switch ( fs.func ) {
-       case R128_INIT_FULLSCREEN:
-               return r128_do_init_pageflip( dev );
-       case R128_CLEANUP_FULLSCREEN:
-               return r128_do_cleanup_pageflip( dev );
-       }
-
        return DRM_ERR(EINVAL);
 }
 
index 61f51e9..5da219e 100644 (file)
@@ -164,6 +164,8 @@ typedef struct drm_r128_sarea {
        drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1];
        unsigned int tex_age[R128_NR_TEX_HEAPS];
        int ctx_owner;
+        int pfAllowPageFlip;        /* number of 3d windows (0,1,2 or more) */
+        int pfCurrentPage;         /* which buffer is being displayed? */
 } drm_r128_sarea_t;
 
 
@@ -191,6 +193,7 @@ typedef struct drm_r128_sarea {
 #define DRM_IOCTL_R128_FULLSCREEN      DRM_IOW( 0x50, drm_r128_fullscreen_t)
 #define DRM_IOCTL_R128_CLEAR2          DRM_IOW( 0x51, drm_r128_clear2_t)
 #define DRM_IOCTL_R128_GETPARAM                DRM_IOW( 0x52, drm_r128_getparam_t)
+#define DRM_IOCTL_R128_FLIP            DRM_IO(  0x53)
 
 typedef struct drm_r128_init {
        enum {
index 9f96fcd..26f7cf8 100644 (file)
@@ -147,6 +147,7 @@ extern int r128_do_cleanup_pageflip( drm_device_t *dev );
                                /* r128_state.c */
 extern int r128_cce_clear( DRM_IOCTL_ARGS );
 extern int r128_cce_swap( DRM_IOCTL_ARGS );
+extern int r128_cce_flip( DRM_IOCTL_ARGS );
 extern int r128_cce_vertex( DRM_IOCTL_ARGS );
 extern int r128_cce_indices( DRM_IOCTL_ARGS );
 extern int r128_cce_blit( DRM_IOCTL_ARGS );
index 27720cf..5416d35 100644 (file)
@@ -500,8 +500,16 @@ static void r128_cce_dispatch_swap( drm_device_t *dev )
                          R128_GMC_AUX_CLIP_DIS |
                          R128_GMC_WR_MSK_DIS );
 
-               OUT_RING( dev_priv->back_pitch_offset_c );
-               OUT_RING( dev_priv->front_pitch_offset_c );
+               /* Make this work even if front & back are flipped:
+                */
+               if (dev_priv->current_page == 0) {
+                       OUT_RING( dev_priv->back_pitch_offset_c );
+                       OUT_RING( dev_priv->front_pitch_offset_c );
+               } 
+               else {
+                       OUT_RING( dev_priv->front_pitch_offset_c );
+                       OUT_RING( dev_priv->back_pitch_offset_c );
+               }
 
                OUT_RING( (x << 16) | y );
                OUT_RING( (x << 16) | y );
@@ -528,7 +536,10 @@ static void r128_cce_dispatch_flip( drm_device_t *dev )
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        RING_LOCALS;
-       DRM_DEBUG( "page=%d\n", dev_priv->current_page );
+       DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", 
+               __FUNCTION__,
+               dev_priv->current_page,
+               dev_priv->sarea_priv->pfCurrentPage);
 
 #if R128_PERFORMANCE_BOXES
        /* Do some trivial performance monitoring...
@@ -543,10 +554,8 @@ static void r128_cce_dispatch_flip( drm_device_t *dev )
 
        if ( dev_priv->current_page == 0 ) {
                OUT_RING( dev_priv->back_offset );
-               dev_priv->current_page = 1;
        } else {
                OUT_RING( dev_priv->front_offset );
-               dev_priv->current_page = 0;
        }
 
        ADVANCE_RING();
@@ -556,6 +565,8 @@ static void r128_cce_dispatch_flip( drm_device_t *dev )
         * performing the swapbuffer ioctl.
         */
        dev_priv->sarea_priv->last_frame++;
+       dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =
+                                             1 - dev_priv->current_page;
 
        BEGIN_RING( 2 );
 
@@ -1266,6 +1277,62 @@ int r128_cce_clear( DRM_IOCTL_ARGS )
        return 0;
 }
 
+static int r128_do_init_pageflip( drm_device_t *dev )
+{
+       drm_r128_private_t *dev_priv = dev->dev_private;
+       DRM_DEBUG( "\n" );
+
+       dev_priv->crtc_offset =      R128_READ( R128_CRTC_OFFSET );
+       dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL );
+
+       R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset );
+       R128_WRITE( R128_CRTC_OFFSET_CNTL,
+                   dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL );
+
+       dev_priv->page_flipping = 1;
+       dev_priv->current_page = 0;
+       dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
+
+       return 0;
+}
+
+int r128_do_cleanup_pageflip( drm_device_t *dev )
+{
+       drm_r128_private_t *dev_priv = dev->dev_private;
+       DRM_DEBUG( "\n" );
+
+       R128_WRITE( R128_CRTC_OFFSET,      dev_priv->crtc_offset );
+       R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
+
+       if (dev_priv->current_page != 0)
+               r128_cce_dispatch_flip( dev );
+
+       dev_priv->page_flipping = 0;
+       return 0;
+}
+
+/* Swapping and flipping are different operations, need different ioctls.
+ * They can & should be intermixed to support multiple 3d windows.  
+ */
+
+int r128_cce_flip( DRM_IOCTL_ARGS )
+{
+       DRM_DEVICE;
+       drm_r128_private_t *dev_priv = dev->dev_private;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+       LOCK_TEST_WITH_RETURN( dev, filp );
+
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
+
+       if (!dev_priv->page_flipping) 
+               r128_do_init_pageflip( dev );
+
+       r128_cce_dispatch_flip( dev );
+
+       return 0;
+}
+
 int r128_cce_swap( DRM_IOCTL_ARGS )
 {
        DRM_DEVICE;
@@ -1280,13 +1347,9 @@ int r128_cce_swap( DRM_IOCTL_ARGS )
        if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
                sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
 
-       if ( !dev_priv->page_flipping ) {
-               r128_cce_dispatch_swap( dev );
-               dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
-                                               R128_UPLOAD_MASKS);
-       } else {
-               r128_cce_dispatch_flip( dev );
-       }
+       r128_cce_dispatch_swap( dev );
+       dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
+                                       R128_UPLOAD_MASKS);
 
        return 0;
 }
index 94e43d7..210b7da 100644 (file)
 
 #define DRIVER_NAME            "r128"
 #define DRIVER_DESC            "ATI Rage 128"
-#define DRIVER_DATE            "20030526"
+#define DRIVER_DATE            "20030725"
 
 #define DRIVER_MAJOR           2
-#define DRIVER_MINOR           4
+#define DRIVER_MINOR           5
 #define DRIVER_PATCHLEVEL      0
 
 /* Interface history:
@@ -68,6 +68,7 @@
    [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)]      = { r128_engine_reset, 1, 0 }, \
    [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen,   1, 0 }, \
    [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)]       = { r128_cce_swap,     1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_FLIP)]       = { r128_cce_flip,     1, 0 }, \
    [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)]      = { r128_cce_clear,    1, 0 }, \
    [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)]     = { r128_cce_vertex,   1, 0 }, \
    [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)]    = { r128_cce_indices,  1, 0 }, \
index 1549e68..3cc0ff5 100644 (file)
@@ -782,59 +782,8 @@ int r128_engine_reset( DRM_IOCTL_ARGS )
        return r128_do_engine_reset( dev );
 }
 
-
-/* ================================================================
- * Fullscreen mode
- */
-
-static int r128_do_init_pageflip( drm_device_t *dev )
-{
-       drm_r128_private_t *dev_priv = dev->dev_private;
-       DRM_DEBUG( "\n" );
-
-       dev_priv->crtc_offset =      R128_READ( R128_CRTC_OFFSET );
-       dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL );
-
-       R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset );
-       R128_WRITE( R128_CRTC_OFFSET_CNTL,
-                   dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL );
-
-       dev_priv->page_flipping = 1;
-       dev_priv->current_page = 0;
-
-       return 0;
-}
-
-int r128_do_cleanup_pageflip( drm_device_t *dev )
-{
-       drm_r128_private_t *dev_priv = dev->dev_private;
-       DRM_DEBUG( "\n" );
-
-       R128_WRITE( R128_CRTC_OFFSET,      dev_priv->crtc_offset );
-       R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
-
-       dev_priv->page_flipping = 0;
-       dev_priv->current_page = 0;
-
-       return 0;
-}
-
 int r128_fullscreen( DRM_IOCTL_ARGS )
 {
-       DRM_DEVICE;
-       drm_r128_fullscreen_t fs;
-
-       LOCK_TEST_WITH_RETURN( dev, filp );
-
-       DRM_COPY_FROM_USER_IOCTL( fs, (drm_r128_fullscreen_t *)data, sizeof(fs) );
-
-       switch ( fs.func ) {
-       case R128_INIT_FULLSCREEN:
-               return r128_do_init_pageflip( dev );
-       case R128_CLEANUP_FULLSCREEN:
-               return r128_do_cleanup_pageflip( dev );
-       }
-
        return DRM_ERR(EINVAL);
 }
 
index 61f51e9..5da219e 100644 (file)
@@ -164,6 +164,8 @@ typedef struct drm_r128_sarea {
        drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1];
        unsigned int tex_age[R128_NR_TEX_HEAPS];
        int ctx_owner;
+        int pfAllowPageFlip;        /* number of 3d windows (0,1,2 or more) */
+        int pfCurrentPage;         /* which buffer is being displayed? */
 } drm_r128_sarea_t;
 
 
@@ -191,6 +193,7 @@ typedef struct drm_r128_sarea {
 #define DRM_IOCTL_R128_FULLSCREEN      DRM_IOW( 0x50, drm_r128_fullscreen_t)
 #define DRM_IOCTL_R128_CLEAR2          DRM_IOW( 0x51, drm_r128_clear2_t)
 #define DRM_IOCTL_R128_GETPARAM                DRM_IOW( 0x52, drm_r128_getparam_t)
+#define DRM_IOCTL_R128_FLIP            DRM_IO(  0x53)
 
 typedef struct drm_r128_init {
        enum {
index 9f96fcd..26f7cf8 100644 (file)
@@ -147,6 +147,7 @@ extern int r128_do_cleanup_pageflip( drm_device_t *dev );
                                /* r128_state.c */
 extern int r128_cce_clear( DRM_IOCTL_ARGS );
 extern int r128_cce_swap( DRM_IOCTL_ARGS );
+extern int r128_cce_flip( DRM_IOCTL_ARGS );
 extern int r128_cce_vertex( DRM_IOCTL_ARGS );
 extern int r128_cce_indices( DRM_IOCTL_ARGS );
 extern int r128_cce_blit( DRM_IOCTL_ARGS );
index 27720cf..5416d35 100644 (file)
@@ -500,8 +500,16 @@ static void r128_cce_dispatch_swap( drm_device_t *dev )
                          R128_GMC_AUX_CLIP_DIS |
                          R128_GMC_WR_MSK_DIS );
 
-               OUT_RING( dev_priv->back_pitch_offset_c );
-               OUT_RING( dev_priv->front_pitch_offset_c );
+               /* Make this work even if front & back are flipped:
+                */
+               if (dev_priv->current_page == 0) {
+                       OUT_RING( dev_priv->back_pitch_offset_c );
+                       OUT_RING( dev_priv->front_pitch_offset_c );
+               } 
+               else {
+                       OUT_RING( dev_priv->front_pitch_offset_c );
+                       OUT_RING( dev_priv->back_pitch_offset_c );
+               }
 
                OUT_RING( (x << 16) | y );
                OUT_RING( (x << 16) | y );
@@ -528,7 +536,10 @@ static void r128_cce_dispatch_flip( drm_device_t *dev )
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        RING_LOCALS;
-       DRM_DEBUG( "page=%d\n", dev_priv->current_page );
+       DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", 
+               __FUNCTION__,
+               dev_priv->current_page,
+               dev_priv->sarea_priv->pfCurrentPage);
 
 #if R128_PERFORMANCE_BOXES
        /* Do some trivial performance monitoring...
@@ -543,10 +554,8 @@ static void r128_cce_dispatch_flip( drm_device_t *dev )
 
        if ( dev_priv->current_page == 0 ) {
                OUT_RING( dev_priv->back_offset );
-               dev_priv->current_page = 1;
        } else {
                OUT_RING( dev_priv->front_offset );
-               dev_priv->current_page = 0;
        }
 
        ADVANCE_RING();
@@ -556,6 +565,8 @@ static void r128_cce_dispatch_flip( drm_device_t *dev )
         * performing the swapbuffer ioctl.
         */
        dev_priv->sarea_priv->last_frame++;
+       dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =
+                                             1 - dev_priv->current_page;
 
        BEGIN_RING( 2 );
 
@@ -1266,6 +1277,62 @@ int r128_cce_clear( DRM_IOCTL_ARGS )
        return 0;
 }
 
+static int r128_do_init_pageflip( drm_device_t *dev )
+{
+       drm_r128_private_t *dev_priv = dev->dev_private;
+       DRM_DEBUG( "\n" );
+
+       dev_priv->crtc_offset =      R128_READ( R128_CRTC_OFFSET );
+       dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL );
+
+       R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset );
+       R128_WRITE( R128_CRTC_OFFSET_CNTL,
+                   dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL );
+
+       dev_priv->page_flipping = 1;
+       dev_priv->current_page = 0;
+       dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
+
+       return 0;
+}
+
+int r128_do_cleanup_pageflip( drm_device_t *dev )
+{
+       drm_r128_private_t *dev_priv = dev->dev_private;
+       DRM_DEBUG( "\n" );
+
+       R128_WRITE( R128_CRTC_OFFSET,      dev_priv->crtc_offset );
+       R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
+
+       if (dev_priv->current_page != 0)
+               r128_cce_dispatch_flip( dev );
+
+       dev_priv->page_flipping = 0;
+       return 0;
+}
+
+/* Swapping and flipping are different operations, need different ioctls.
+ * They can & should be intermixed to support multiple 3d windows.  
+ */
+
+int r128_cce_flip( DRM_IOCTL_ARGS )
+{
+       DRM_DEVICE;
+       drm_r128_private_t *dev_priv = dev->dev_private;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+       LOCK_TEST_WITH_RETURN( dev, filp );
+
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
+
+       if (!dev_priv->page_flipping) 
+               r128_do_init_pageflip( dev );
+
+       r128_cce_dispatch_flip( dev );
+
+       return 0;
+}
+
 int r128_cce_swap( DRM_IOCTL_ARGS )
 {
        DRM_DEVICE;
@@ -1280,13 +1347,9 @@ int r128_cce_swap( DRM_IOCTL_ARGS )
        if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
                sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
 
-       if ( !dev_priv->page_flipping ) {
-               r128_cce_dispatch_swap( dev );
-               dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
-                                               R128_UPLOAD_MASKS);
-       } else {
-               r128_cce_dispatch_flip( dev );
-       }
+       r128_cce_dispatch_swap( dev );
+       dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
+                                       R128_UPLOAD_MASKS);
 
        return 0;
 }