preserve CRTC{,2}_OFFSET_CNTL in 2D driver to avoid bad effects when
authorMichel Daenzer <michel@daenzer.net>
Tue, 29 Oct 2002 13:49:26 +0000 (13:49 +0000)
committerMichel Daenzer <michel@daenzer.net>
Tue, 29 Oct 2002 13:49:26 +0000 (13:49 +0000)
    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

bsd/Imakefile
linux/Makefile.linux
shared-core/drm_sarea.h [new file with mode: 0644]
shared-core/radeon_drm.h
shared-core/radeon_drv.h
shared-core/radeon_state.c
shared/drm_sarea.h [new file with mode: 0644]
shared/radeon_drm.h
shared/radeon_drv.h
shared/radeon_state.c

index 13b2791..0e92b13 100644 (file)
@@ -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)
index 7c3f1db..a498ed8 100644 (file)
@@ -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 (file)
index 0000000..cee48ee
--- /dev/null
@@ -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_ */
index 91b395c..6ef0c97 100644 (file)
@@ -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;
 
 
index 81615a7..65f3c92 100644 (file)
@@ -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
 
index b4d6652..7b480a7 100644 (file)
@@ -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 (file)
index 0000000..cee48ee
--- /dev/null
@@ -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_ */
index 91b395c..6ef0c97 100644 (file)
@@ -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;
 
 
index 81615a7..65f3c92 100644 (file)
@@ -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
 
index b4d6652..7b480a7 100644 (file)
@@ -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;
 }