summaryrefslogtreecommitdiff
path: root/shared/radeon_state.c
diff options
context:
space:
mode:
authorMichel Daenzer <michel@daenzer.net>2002-10-29 13:49:26 +0000
committerMichel Daenzer <michel@daenzer.net>2002-10-29 13:49:26 +0000
commit5e1b8ed88ae8fb8b697515140f7a00d022ac2db0 (patch)
tree95553095ecb8905672e40c7bc153e73aa07e4478 /shared/radeon_state.c
parent10900dab7caa593a54d76e5f6abdc3df9bdd0a04 (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/radeon_state.c')
-rw-r--r--shared/radeon_state.c38
1 files changed, 19 insertions, 19 deletions
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;
}