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 disabledmain
parent
10900dab7c
commit
5e1b8ed88a
|
@ -19,6 +19,7 @@ all::
|
|||
clean::
|
||||
$(MAKE) -f Makefile.bsd clean
|
||||
|
||||
LinkSourceFile(drm_sarea.h,$(XF86OSSRC)/shared/drm/kernel)
|
||||
LinkSourceFile(mga.h,$(XF86OSSRC)/shared/drm/kernel)
|
||||
LinkSourceFile(mga_dma.c,$(XF86OSSRC)/shared/drm/kernel)
|
||||
LinkSourceFile(mga_drm.h,$(XF86OSSRC)/shared/drm/kernel)
|
||||
|
|
|
@ -44,7 +44,7 @@ LIBS =
|
|||
DRMTEMPLATES = drm_auth.h drm_bufs.h drm_context.h drm_dma.h drm_drawable.h \
|
||||
drm_drv.h drm_fops.h drm_init.h drm_ioctl.h drm_lists.h \
|
||||
drm_lock.h drm_memory.h drm_proc.h drm_stub.h drm_vm.h
|
||||
DRMHEADERS = drm.h drmP.h
|
||||
DRMHEADERS = drm.h drmP.h drm_sarea.h
|
||||
|
||||
GAMMAOBJS = gamma_drv.o gamma_dma.o
|
||||
GAMMAHEADERS = gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES)
|
||||
|
|
|
@ -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_ */
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_ */
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue