diff options
author | Michel Daenzer <michel@daenzer.net> | 2002-10-29 13:49:26 +0000 |
---|---|---|
committer | Michel Daenzer <michel@daenzer.net> | 2002-10-29 13:49:26 +0000 |
commit | 5e1b8ed88ae8fb8b697515140f7a00d022ac2db0 (patch) | |
tree | 95553095ecb8905672e40c7bc153e73aa07e4478 /shared | |
parent | 10900dab7caa593a54d76e5f6abdc3df9bdd0a04 (diff) |
preserve CRTC{,2}_OFFSET_CNTL in 2D driver to avoid bad effects when
pageflipping after a mode switch
take current page into account in AdjustFrame(); writing the CRTC offset
via the CP was probably a bad idea as this can happen asynchronously,
reverted
take frame offset into account when flipping pages
handle CRTC2 as well for pageflipping (untested)
preserve GEN_INT_CNTL on mode switches to prevent interrupts from getting
disabled
Diffstat (limited to 'shared')
-rw-r--r-- | shared/drm_sarea.h | 57 | ||||
-rw-r--r-- | shared/radeon_drm.h | 1 | ||||
-rw-r--r-- | shared/radeon_drv.h | 4 | ||||
-rw-r--r-- | shared/radeon_state.c | 38 |
4 files changed, 79 insertions, 21 deletions
diff --git a/shared/drm_sarea.h b/shared/drm_sarea.h new file mode 100644 index 00000000..cee48eee --- /dev/null +++ b/shared/drm_sarea.h @@ -0,0 +1,57 @@ +/* sarea.h -- SAREA definitions -*- linux-c -*- + * + * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Michel Dänzer <michel@daenzer.net> + */ + +#ifndef _DRM_SAREA_H_ +#define _DRM_SAREA_H_ + +#define SAREA_MAX_DRAWABLES 256 + +typedef struct _drm_sarea_drawable_t { + unsigned int stamp; + unsigned int flags; +} drm_sarea_drawable_t; + +typedef struct _dri_sarea_frame_t { + unsigned int x; + unsigned int y; + unsigned int width; + unsigned int height; + unsigned int fullscreen; +} drm_sarea_frame_t; + +typedef struct _drm_sarea_t { + /* first thing is always the drm locking structure */ + drm_hw_lock_t lock; + /* NOT_DONE: Use readers/writer lock for drawable_lock */ + drm_hw_lock_t drawable_lock; + drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES]; + drm_sarea_frame_t frame; + drm_context_t dummy_context; +} drm_sarea_t; + +#endif /* _DRM_SAREA_H_ */ diff --git a/shared/radeon_drm.h b/shared/radeon_drm.h index 91b395c3..6ef0c97a 100644 --- a/shared/radeon_drm.h +++ b/shared/radeon_drm.h @@ -355,6 +355,7 @@ typedef struct { int ctx_owner; int pfState; /* number of 3d windows (0,1,2ormore) */ int pfCurrentPage; /* which buffer is being displayed? */ + int crtc2_base; /* CRTC2 frame offset */ } drm_radeon_sarea_t; diff --git a/shared/radeon_drv.h b/shared/radeon_drv.h index 81615a78..65f3c926 100644 --- a/shared/radeon_drv.h +++ b/shared/radeon_drv.h @@ -109,8 +109,6 @@ typedef struct drm_radeon_private { int do_boxes; int page_flipping; int current_page; - u32 crtc_offset; - u32 crtc_offset_cntl; u32 color_fmt; unsigned int front_offset; @@ -230,6 +228,8 @@ extern int radeon_emit_irq(drm_device_t *dev); #define RADEON_CRTC_OFFSET_CNTL 0x0228 # define RADEON_CRTC_TILE_EN (1 << 15) # define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16) +#define RADEON_CRTC2_OFFSET 0x0324 +#define RADEON_CRTC2_OFFSET_CNTL 0x0328 #define RADEON_RB3D_COLORPITCH 0x1c48 diff --git a/shared/radeon_state.c b/shared/radeon_state.c index b4d66524..7b480a7e 100644 --- a/shared/radeon_state.c +++ b/shared/radeon_state.c @@ -30,6 +30,7 @@ #include "radeon.h" #include "drmP.h" #include "drm.h" +#include "drm_sarea.h" #include "radeon_drm.h" #include "radeon_drv.h" @@ -803,6 +804,9 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev ) static void radeon_cp_dispatch_flip( drm_device_t *dev ) { drm_radeon_private_t *dev_priv = dev->dev_private; + drm_sarea_t *sarea = (drm_sarea_t *)dev_priv->sarea->handle; + int offset = (dev_priv->current_page == 1) + ? dev_priv->front_offset : dev_priv->back_offset; RING_LOCALS; DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", __FUNCTION__, @@ -816,18 +820,17 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev ) radeon_cp_performance_boxes( dev_priv ); } - BEGIN_RING( 4 ); + /* Update the frame offsets for both CRTCs + */ + BEGIN_RING( 6 ); RADEON_WAIT_UNTIL_3D_IDLE(); - OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET, 0 ) ); - - 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; - } + OUT_RING_REG( RADEON_CRTC_OFFSET, ( ( sarea->frame.y * dev_priv->front_pitch + + sarea->frame.x + * ( dev_priv->color_fmt - 2 ) ) & ~7 ) + + offset ); + OUT_RING_REG( RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base + + offset ); ADVANCE_RING(); @@ -836,7 +839,8 @@ static void radeon_cp_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; + dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = + 1 - dev_priv->current_page; BEGIN_RING( 2 ); @@ -1304,12 +1308,12 @@ static int radeon_do_init_pageflip( drm_device_t *dev ) DRM_DEBUG( "\n" ); - dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL ); - - BEGIN_RING( 4 ); + BEGIN_RING( 6 ); RADEON_WAIT_UNTIL_3D_IDLE(); OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET_CNTL, 0 ) ); - OUT_RING( dev_priv->crtc_offset_cntl | RADEON_CRTC_OFFSET_FLIP_CNTL ); + OUT_RING( RADEON_READ( RADEON_CRTC_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL ); + OUT_RING( CP_PACKET0( RADEON_CRTC2_OFFSET_CNTL, 0 ) ); + OUT_RING( RADEON_READ( RADEON_CRTC2_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL ); ADVANCE_RING(); dev_priv->page_flipping = 1; @@ -1330,10 +1334,6 @@ int radeon_do_cleanup_pageflip( drm_device_t *dev ) if (dev_priv->current_page != 0) radeon_cp_dispatch_flip( dev ); - /* FIXME: If the X server changes screen resolution, it - * clobbers the value of RADEON_CRTC_OFFSET_CNTL, above, - * leading to a flashing efect. - */ dev_priv->page_flipping = 0; return 0; } |