summaryrefslogtreecommitdiff
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
parent10900dab7caa593a54d76e5f6abdc3df9bdd0a04 (diff)
preserve CRTC{,2}_OFFSET_CNTL in 2D driver to avoid bad effects whennv-0-0-1-branch
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
-rw-r--r--bsd/Imakefile1
-rw-r--r--linux/Makefile.linux2
-rw-r--r--shared-core/drm_sarea.h57
-rw-r--r--shared-core/radeon_drm.h1
-rw-r--r--shared-core/radeon_drv.h4
-rw-r--r--shared-core/radeon_state.c38
-rw-r--r--shared/drm_sarea.h57
-rw-r--r--shared/radeon_drm.h1
-rw-r--r--shared/radeon_drv.h4
-rw-r--r--shared/radeon_state.c38
10 files changed, 160 insertions, 43 deletions
diff --git a/bsd/Imakefile b/bsd/Imakefile
index 13b2791f..0e92b13f 100644
--- a/bsd/Imakefile
+++ b/bsd/Imakefile
@@ -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)
diff --git a/linux/Makefile.linux b/linux/Makefile.linux
index 7c3f1db9..a498ed8c 100644
--- a/linux/Makefile.linux
+++ b/linux/Makefile.linux
@@ -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)
diff --git a/shared-core/drm_sarea.h b/shared-core/drm_sarea.h
new file mode 100644
index 00000000..cee48eee
--- /dev/null
+++ b/shared-core/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-core/radeon_drm.h b/shared-core/radeon_drm.h
index 91b395c3..6ef0c97a 100644
--- a/shared-core/radeon_drm.h
+++ b/shared-core/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-core/radeon_drv.h b/shared-core/radeon_drv.h
index 81615a78..65f3c926 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/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-core/radeon_state.c b/shared-core/radeon_state.c
index b4d66524..7b480a7e 100644
--- a/shared-core/radeon_state.c
+++ b/shared-core/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;
}
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;
}