From aaf2105be967ad7f99c643b4be09cf6d3d063b65 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 26 Jul 2003 03:25:40 +0000 Subject: Add Rage 128 pageflipping support, defaults to off. DRM version bump to 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 | 51 ---------------------------- shared-core/r128_drm.h | 3 ++ shared-core/r128_drv.h | 1 + shared-core/r128_state.c | 87 +++++++++++++++++++++++++++++++++++++++++------- shared/r128.h | 5 +-- shared/r128_cce.c | 51 ---------------------------- shared/r128_drm.h | 3 ++ shared/r128_drv.h | 1 + shared/r128_state.c | 87 +++++++++++++++++++++++++++++++++++++++++------- 9 files changed, 161 insertions(+), 128 deletions(-) diff --git a/shared-core/r128_cce.c b/shared-core/r128_cce.c index 1549e683..3cc0ff54 100644 --- a/shared-core/r128_cce.c +++ b/shared-core/r128_cce.c @@ -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); } diff --git a/shared-core/r128_drm.h b/shared-core/r128_drm.h index 61f51e93..5da219e5 100644 --- a/shared-core/r128_drm.h +++ b/shared-core/r128_drm.h @@ -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 { diff --git a/shared-core/r128_drv.h b/shared-core/r128_drv.h index 9f96fcd0..26f7cf86 100644 --- a/shared-core/r128_drv.h +++ b/shared-core/r128_drv.h @@ -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 ); diff --git a/shared-core/r128_state.c b/shared-core/r128_state.c index 27720cff..5416d35e 100644 --- a/shared-core/r128_state.c +++ b/shared-core/r128_state.c @@ -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; } diff --git a/shared/r128.h b/shared/r128.h index 94e43d73..210b7da9 100644 --- a/shared/r128.h +++ b/shared/r128.h @@ -47,10 +47,10 @@ #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 }, \ diff --git a/shared/r128_cce.c b/shared/r128_cce.c index 1549e683..3cc0ff54 100644 --- a/shared/r128_cce.c +++ b/shared/r128_cce.c @@ -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); } diff --git a/shared/r128_drm.h b/shared/r128_drm.h index 61f51e93..5da219e5 100644 --- a/shared/r128_drm.h +++ b/shared/r128_drm.h @@ -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 { diff --git a/shared/r128_drv.h b/shared/r128_drv.h index 9f96fcd0..26f7cf86 100644 --- a/shared/r128_drv.h +++ b/shared/r128_drv.h @@ -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 ); diff --git a/shared/r128_state.c b/shared/r128_state.c index 27720cff..5416d35e 100644 --- a/shared/r128_state.c +++ b/shared/r128_state.c @@ -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; } -- cgit v1.2.3