Re: Radeon acceleration with Xfbdev

Eric Anholt <[email protected]>
Newsgroups gmane.comp.freedesktop.xserver
Message-ID <1069890047.701.255.camel@leguin>
On Mon, 2003-11-24 at 16:17, Michel Dänzer wrote:
> Here's a quick'n'dirty patch to get this going, comments appreciated.
> 
> I see some corruption with it, is that to be expected Eric?

Depends on the sort of corruption.  I haven't seen unexplained
corruption at 16 bit for a while.  8-bit had issues, and I can't
remember if 24 was completely fixed or not (I seem to recall issues with
one of either r128 or radeon in some cases).

It seems backwards to me to have the fbdev driver implement the
acceleration itself, but I guess that was the quick'n'dirty part.  I've
been playing with having both vesa and fbdev support, with the default
being to use fbdev (since it should be more trustworthy in the end), and
what I have so far is attached.  VESA continues to work, but fb is
getting me a segfault and the following delightful output:

(gdb) r
Starting program: /usr/src/xserver/hw/kdrive/ati/Xati
 
Program received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()
(gdb) bt
#0  0x00000000 in ?? ()
(gdb)

If anyone would like to fix this up, I'd be happy for it to get in the
tree.  I'll be gone for the next couple days for Thanksgiving with the
family, so I won't be checking mail.

-- 
Eric Anholt                                [email protected]          
http://people.freebsd.org/~anholt/         [email protected]
xserver-atifbdev.diff (text/x-patch, 14.1 KB)
Index: configure.ac
===================================================================
RCS file: /cvs/xserver/xserver/configure.ac,v
retrieving revision 3.38
diff -u -r3.38 configure.ac
--- configure.ac	22 Nov 2003 02:19:44 -0000	3.38
+++ configure.ac	26 Nov 2003 22:56:40 -0000
@@ -64,6 +64,9 @@
 # APM header
 AC_CHECK_HEADERS([linux/apm_bios.h])
 
+# fbdev header
+AC_CHECK_HEADERS([linux/fb.h])
+
 # MTRR header
 AC_CHECK_HEADERS([asm/mtrr.h])
 
@@ -221,11 +224,16 @@
 if test "$USE_RGB_BUILTIN" = yes; then
 	AC_DEFINE(USE_RGB_BUILTIN,1,[Use builtin rgb color database])
 fi
-	
+
 if test "$ac_cv_header_sys_vm86_h" = yes; then
-	AC_DEFINE(KDRIVEVESA, 1, [Include vesa-based X servers])
+	AC_DEFINE(KDRIVEVESA, 1, [Include vesa-based X servers and vesa support])
 fi
 AM_CONDITIONAL(KDRIVEVESA, [test "$ac_cv_header_sys_vm86_h" = yes])
+
+if test "$ac_cv_header_linux_fb_h" = yes; then
+	AC_DEFINE(KDRIVEFBDEV, 1, [Include framebuffer-based X servers and framebuffer support])
+fi
+AM_CONDITIONAL(KDRIVEFBDEV, [test "$ac_cv_header_linux_fb_h" = yes])
 
 AC_DEFINE_UNQUOTED(COMPILEDDEFAULTFONTPATH, ["$FONTPATH"], [Default font path])
 AC_DEFINE_UNQUOTED(VENDOR_STRING,["$VENDOR_STRING"], [Vendor name])
Index: hw/kdrive/Makefile.am
===================================================================
RCS file: /cvs/xserver/xserver/hw/kdrive/Makefile.am,v
retrieving revision 1.15
diff -u -r1.15 Makefile.am
--- hw/kdrive/Makefile.am	19 Nov 2003 08:32:33 -0000	1.15
+++ hw/kdrive/Makefile.am	26 Nov 2003 21:55:44 -0000
@@ -1,10 +1,14 @@
 if KDRIVEVESA
-VESA_SUBDIRS = vesa ati mach64 mga nvidia r128 smi
+VESA_SUBDIRS = vesa mach64 mga nvidia r128 smi
 endif
 
-SUBDIRS =	\
-	src	\
-	linux	\
-	fbdev	\
-	$(VESA_SUBDIRS)
+if KDRIVEFBDEV
+FBDEV_SUBDIRS = fbdev
+endif
 
+SUBDIRS =			\
+	src			\
+	linux			\
+	$(FBDEV_SUBDIRS)	\
+	$(VESA_SUBDIRS)		\
+	ati
Index: hw/kdrive/ati/Makefile.am
===================================================================
RCS file: /cvs/xserver/xserver/hw/kdrive/ati/Makefile.am,v
retrieving revision 1.1
diff -u -r1.1 Makefile.am
--- hw/kdrive/ati/Makefile.am	19 Nov 2003 08:32:35 -0000	1.1
+++ hw/kdrive/ati/Makefile.am	26 Nov 2003 20:42:15 -0000
@@ -1,6 +1,18 @@
+if KDRIVEFBDEV
+FBDEV_INCLUDES =-I$(top_srcdir)/hw/kdrive/fbdev
+FBDEV_LIBS = $(top_builddir)/hw/kdrive/fbdev/libfbdev.a
+endif
+
+if KDRIVEVESA
+VESA_INCLUDES = -I$(top_srcdir)/hw/kdrive/vesa
+VESA_LIBS = $(top_builddir)/hw/kdrive/vesa/libvesa.a
+endif
+
+
 INCLUDES = 					\
 	@KDRIVE_INCS@				\
-	-I$(top_srcdir)/hw/kdrive/vesa		\
+	$(FBDEV_INCLUDES)			\
+	$(VESA_INCLUDES)			\
 	@XSERVER_CFLAGS@
 
 bin_PROGRAMS = Xati
@@ -22,7 +34,8 @@
 
 Xati_LDADD = \
 	libati.a 				\
-	$(top_builddir)/hw/kdrive/vesa/libvesa.a \
+	$(FBDEV_LIBS)				\
+	$(VESA_LIBS)				\
 	@KDRIVE_LIBS@				\
 	@XSERVER_LIBS@                          \
 	$(TSLIB_FLAG)
Index: hw/kdrive/ati/ati.c
===================================================================
RCS file: /cvs/xserver/xserver/hw/kdrive/ati/ati.c,v
retrieving revision 1.5
diff -u -r1.5 ati.c
--- hw/kdrive/ati/ati.c	25 Nov 2003 22:39:54 -0000	1.5
+++ hw/kdrive/ati/ati.c	26 Nov 2003 23:34:09 -0000
@@ -153,15 +153,50 @@
 {
 	ATICardInfo *atic;
 	int i;
+	Bool initialized = FALSE;
 
-	atic = xalloc(sizeof(ATICardInfo));
+	atic = xcalloc(sizeof(ATICardInfo), 1);
 	if (atic == NULL)
 		return FALSE;
 
 	ATIMapReg(card, atic);
 
-	if (!vesaInitialize(card, &atic->vesa))
-	{
+#ifdef KDRIVEFBDEV
+	if (!initialized && fbdevInitialize(card, &atic->backend_priv.fbdev)) {
+		atic->use_fbdev = TRUE;
+		initialized = TRUE;
+		atic->backend_funcs.cardfini = fbdevCardFini;
+		atic->backend_funcs.scrfini = fbdevScreenFini;
+		atic->backend_funcs.initScreen = fbdevInitScreen;
+		atic->backend_funcs.finishInitScreen = fbdevFinishInitScreen;
+		atic->backend_funcs.preserve = fbdevPreserve;
+		atic->backend_funcs.restore = fbdevRestore;
+		atic->backend_funcs.dpms = fbdevDPMS;
+		atic->backend_funcs.enable = fbdevEnable;
+		atic->backend_funcs.disable = fbdevDisable;
+		atic->backend_funcs.getColors = fbdevGetColors;
+		atic->backend_funcs.putColors = fbdevPutColors;
+	}
+#endif
+#ifdef KDRIVEVESA
+	if (!initialized && vesaInitialize(card, &atic->backend_priv.vesa)) {
+		atic->use_vesa = TRUE;
+		initialized = TRUE;
+		atic->backend_funcs.cardfini = vesaCardFini;
+		atic->backend_funcs.scrfini = vesaScreenFini;
+		atic->backend_funcs.initScreen = vesaInitScreen;
+		atic->backend_funcs.finishInitScreen = vesaFinishInitScreen;
+		atic->backend_funcs.preserve = vesaPreserve;
+		atic->backend_funcs.restore = vesaRestore;
+		atic->backend_funcs.dpms = vesaDPMS;
+		atic->backend_funcs.enable = vesaEnable;
+		atic->backend_funcs.disable = vesaDisable;
+		atic->backend_funcs.getColors = vesaGetColors;
+		atic->backend_funcs.putColors = vesaPutColors;
+	}
+#endif
+
+	if (!initialized) {
 		xfree(atic);
 		return FALSE;
 	}
@@ -181,39 +216,41 @@
 	ATICardInfo *atic = (ATICardInfo *)card->driver;
 
 	ATIUnmapReg(card, atic);
-	vesaCardFini(card);
+	atic->backend_funcs.cardfini(card);
 }
 
 static Bool
 ATIScreenInit(KdScreenInfo *screen)
 {
 	ATIScreenInfo *atis;
-	int screen_size, memory;
+	ATICardInfo *atic = screen->card->driver;
+	int success = FALSE;
 
-	atis = xalloc(sizeof(ATIScreenInfo));
+	atis = xcalloc(sizeof(ATIScreenInfo), 1);
 	if (atis == NULL)
 		return FALSE;
-	memset(atis, '\0', sizeof(ATIScreenInfo));
 
-	if (!vesaScreenInitialize(screen, &atis->vesa))
-	{
+	if (screen->fb[0].depth == 0)
+		screen->fb[0].depth = 16;
+
+	screen->driver = atis;
+
+#ifdef KDRIVEFBDEV
+	if (atic->use_fbdev)
+		success = fbdevScreenInitialize(screen,
+		    &atis->backend_priv.fbdev);
+#endif
+#ifdef KDRIVEVESA
+	if (atic->use_vesa)
+		success = vesaScreenInitialize(screen,
+		    &atis->backend_priv.vesa);
+#endif
+	if (!success) {
+		screen->driver = NULL;
 		xfree(atis);
 		return FALSE;
 	}
-	atis->screen = atis->vesa.fb;
 
-	memory = atis->vesa.fb_size;
-	screen_size = screen->fb[0].byteStride * screen->height;
-
-	memory -= screen_size;
-	if (memory > screen->fb[0].byteStride) {
-		atis->off_screen = atis->screen + screen_size;
-		atis->off_screen_size = memory;
-	} else {
-		atis->off_screen = 0;
-		atis->off_screen_size = 0;
-	}
-	screen->driver = atis;
 	return TRUE;
 }
 
@@ -221,8 +258,9 @@
 ATIScreenFini(KdScreenInfo *screen)
 {
 	ATIScreenInfo *atis = (ATIScreenInfo *)screen->driver;
+	ATICardInfo *atic = screen->card->driver;
 
-	vesaScreenFini(screen);
+	atic->backend_funcs.scrfini(screen);
 	xfree(atis);
 	screen->driver = 0;
 }
@@ -266,12 +304,58 @@
 	ATIUnmapReg(card, atic);
 }
 
+static Bool
+ATIInitScreen(ScreenPtr pScreen)
+{
+	KdScreenPriv(pScreen);
+	ATICardInfo(pScreenPriv);
+
+	return atic->backend_funcs.initScreen(pScreen);
+}
+
+static Bool
+ATIFinishInitScreen(ScreenPtr pScreen)
+{
+	KdScreenPriv(pScreen);
+	ATICardInfo(pScreenPriv);
+
+	return atic->backend_funcs.finishInitScreen(pScreen);
+}
+
+static Bool
+ATICreateResources(ScreenPtr pScreen)
+{
+	KdScreenPriv(pScreen);
+	ATICardInfo(pScreenPriv);
+
+	return atic->backend_funcs.createRes(pScreen);
+}
+
+static void
+ATIPreserve(KdCardInfo *card)
+{
+	ATICardInfo *atic = card->driver;
+
+	atic->backend_funcs.preserve(card);
+}
+
+static void
+ATIRestore(KdCardInfo *card)
+{
+	ATICardInfo *atic = card->driver;
+
+	ATIResetMMIO(card, atic);
+
+	atic->backend_funcs.restore(card);
+}
 
 static Bool
 ATIDPMS(ScreenPtr pScreen, int mode)
 {
-	/* XXX */
-	return TRUE;
+	KdScreenPriv(pScreen);
+	ATICardInfo(pScreenPriv);
+
+	return atic->backend_funcs.dpms(pScreen, mode);
 }
 
 static Bool
@@ -280,7 +364,7 @@
 	KdScreenPriv(pScreen);
 	ATICardInfo(pScreenPriv);
 
-	if (!vesaEnable(pScreen))
+	if (!atic->backend_funcs.enable(pScreen))
 		return FALSE;
 
 	ATISetMMIO(pScreenPriv->card, atic);
@@ -296,25 +380,36 @@
 	ATICardInfo(pScreenPriv);
 
 	ATIResetMMIO(pScreenPriv->card, atic);
-	vesaDisable(pScreen);
+
+	atic->backend_funcs.disable(pScreen);
 }
 
 static void
-ATIRestore(KdCardInfo *card)
+ATIGetColors(ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
 {
-	ATICardInfo *atic = card->driver;
+	KdScreenPriv(pScreen);
+	ATICardInfo(pScreenPriv);
 
-	ATIResetMMIO(card, atic);
-	vesaRestore(card);
+	atic->backend_funcs.getColors(pScreen, fb, n, pdefs);
+}
+
+
+static void
+ATIPutColors(ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
+{
+	KdScreenPriv(pScreen);
+	ATICardInfo(pScreenPriv);
+
+	atic->backend_funcs.putColors(pScreen, fb, n, pdefs);
 }
 
 KdCardFuncs ATIFuncs = {
 	ATICardInit,		/* cardinit */
 	ATIScreenInit,		/* scrinit */
-	vesaInitScreen,		/* initScreen */
-	vesaFinishInitScreen,	/* finishInitScreen */
-	vesaCreateResources,	/* createRes */
-	vesaPreserve,		/* preserve */
+	ATIInitScreen,		/* initScreen */
+	ATIFinishInitScreen,	/* finishInitScreen */
+	ATICreateResources,	/* createRes */
+	ATIPreserve,		/* preserve */
 	ATIEnable,		/* enable */
 	ATIDPMS,		/* dpms */
 	ATIDisable,		/* disable */
@@ -334,7 +429,7 @@
 	ATIDrawDisable,		/* disableAccel */
 	ATIDrawFini,		/* finiAccel */
 
-	vesaGetColors,		/* getColors */
-	vesaPutColors,		/* putColors */
+	ATIGetColors,		/* getColors */
+	ATIPutColors,		/* putColors */
 };
 
Index: hw/kdrive/ati/ati.h
===================================================================
RCS file: /cvs/xserver/xserver/hw/kdrive/ati/ati.h,v
retrieving revision 1.2
diff -u -r1.2 ati.h
--- hw/kdrive/ati/ati.h	20 Nov 2003 07:49:45 -0000	1.2
+++ hw/kdrive/ati/ati.h	26 Nov 2003 22:53:48 -0000
@@ -25,14 +25,52 @@
 
 #ifndef _ATI_H_
 #define _ATI_H_
+
+#include "config.h"
+
+#ifdef KDRIVEFBDEV
+#include <fbdev.h>
+#endif
+#ifdef KDRIVEVESA
 #include <vesa.h>
+#endif
 
 #define RADEON_REG_BASE(c)		((c)->attr.address[1])
 #define RADEON_REG_SIZE(c)		(0x10000)
 
+#ifdef __powerpc__
+
+static __inline__ void
+MMIO_OUT32(__volatile__ void *base, const unsigned long offset,
+	   const unsigned int val)
+{
+        __asm__ __volatile__(
+                        "stwbrx %1,%2,%3\n\t"
+			"eieio"
+                        : "=m" (*((volatile unsigned char *)base+offset))
+                        : "r" (val), "b" (base), "r" (offset));
+}
+
+static __inline__ CARD32
+MMIO_IN32(__volatile__ void *base, const unsigned long offset)
+{
+        register unsigned int val;
+        __asm__ __volatile__(
+                        "lwbrx %0,%1,%2\n\t"
+                        "eieio"
+                        : "=r" (val)
+                        : "b" (base), "r" (offset),
+                        "m" (*((volatile unsigned char *)base+offset)));
+        return val;
+}
+
+#else
+
 #define MMIO_OUT32(mmio, a, v)		(*(VOL32 *)((mmio) + (a)) = (v))
 #define MMIO_IN32(mmio, a)		(*(VOL32 *)((mmio) + (a)))
 
+#endif
+
 typedef volatile CARD8	VOL8;
 typedef volatile CARD16	VOL16;
 typedef volatile CARD32	VOL32;
@@ -43,20 +81,49 @@
 	char *name;
 };
 
+struct backend_funcs {	
+	void	(*cardfini)(KdCardInfo *);
+	void	(*scrfini)(KdScreenInfo *);
+	Bool	(*initScreen)(ScreenPtr);
+	Bool	(*finishInitScreen)(ScreenPtr pScreen);
+	Bool	(*createRes)(ScreenPtr);
+	void	(*preserve)(KdCardInfo *);
+	void	(*restore)(KdCardInfo *);
+	Bool	(*dpms)(ScreenPtr, int);
+	Bool	(*enable)(ScreenPtr);
+	void	(*disable)(ScreenPtr);
+	void	(*getColors)(ScreenPtr, int, int, xColorItem *);
+	void	(*putColors)(ScreenPtr, int, int, xColorItem *);
+};
+
 typedef struct _ATICardInfo {
-	VesaCardPrivRec vesa;
+	union {
+#ifdef KDRIVEFBDEV
+		FbdevPriv fbdev;
+#endif
+#ifdef KDRIVEVESA
+		VesaCardPrivRec vesa;
+#endif
+	} backend_priv;
+	struct backend_funcs backend_funcs;
+
 	CARD8 *reg_base;
 	Bool is_radeon;
+	Bool use_fbdev, use_vesa;
 } ATICardInfo;
 
 #define getATICardInfo(kd)	((ATICardInfo *) ((kd)->card->driver))
 #define ATICardInfo(kd)		ATICardInfo *atic = getATICardInfo(kd)
 
 typedef struct _ATIScreenInfo {
-	VesaScreenPrivRec vesa;
-	CARD8 *screen;
-	CARD8 *off_screen;
-	int off_screen_size;
+	union {
+#ifdef KDRIVEFBDEV
+		FbdevScrPriv fbdev;
+#endif
+#ifdef KDRIVEVESA
+		VesaScreenPrivRec vesa;
+#endif
+	} backend_priv;
 
 	int datatype;
 	int dp_gui_master_cntl;
Index: hw/kdrive/ati/ati_draw.c
===================================================================
RCS file: /cvs/xserver/xserver/hw/kdrive/ati/ati_draw.c,v
retrieving revision 1.4
diff -u -r1.4 ati_draw.c
--- hw/kdrive/ati/ati_draw.c	23 Nov 2003 10:12:04 -0000	1.4
+++ hw/kdrive/ati/ati_draw.c	25 Nov 2003 22:45:15 -0000
@@ -22,7 +22,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 /* $Header: /cvs/xserver/xserver/hw/kdrive/ati/ati_draw.c,v 1.4 2003/11/23 10:12:04 anholt Exp $ */
-#include <sys/io.h>
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
Index: hw/kdrive/ati/ati_stub.c
===================================================================
RCS file: /cvs/xserver/xserver/hw/kdrive/ati/ati_stub.c,v
retrieving revision 1.1
diff -u -r1.1 ati_stub.c
--- hw/kdrive/ati/ati_stub.c	19 Nov 2003 08:32:35 -0000	1.1
+++ hw/kdrive/ati/ati_stub.c	26 Nov 2003 22:03:52 -0000
@@ -73,7 +73,9 @@
 ddxUseMsg (void)
 {
 	KdUseMsg();
+#ifdef KDRIVEVESA
 	vesaUseMsg();
+#endif
 }
 
 int
@@ -81,7 +83,9 @@
 {
 	int	ret;
     
+#ifdef KDRIVEVESA
 	if (!(ret = vesaProcessArgument (argc, argv, i)))
 		ret = KdProcessArgument(argc, argv, i);
+#endif
 	return ret;
 }
Index: hw/kdrive/fbdev/fbdev.c
===================================================================
RCS file: /cvs/xserver/xserver/hw/kdrive/fbdev/fbdev.c,v
retrieving revision 1.40
diff -u -r1.40 fbdev.c
--- hw/kdrive/fbdev/fbdev.c	17 Nov 2003 06:54:52 -0000	1.40
+++ hw/kdrive/fbdev/fbdev.c	26 Nov 2003 21:21:22 -0000
@@ -37,7 +37,7 @@
     int		    k;
     unsigned long   off;
     if ((priv->fd = open("/dev/fb0", O_RDWR)) < 0) {
-	perror("Error opening /dev/fb0\n");
+	perror("Error opening /dev/fb0");
 	return FALSE;
     }
     /* quiet valgrind */
Index: hw/kdrive/src/kdrive.h
===================================================================
RCS file: /cvs/xserver/xserver/hw/kdrive/src/kdrive.h,v
retrieving revision 1.44
diff -u -r1.44 kdrive.h
--- hw/kdrive/src/kdrive.h	19 Nov 2003 08:32:38 -0000	1.44
+++ hw/kdrive/src/kdrive.h	26 Nov 2003 20:28:10 -0000
@@ -23,6 +23,9 @@
  */
 /* $RCSId: xc/programs/Xserver/hw/kdrive/kdrive.h,v 1.29 2002/11/13 16:37:39 keithp Exp $ */
 
+#ifndef _KDRIVE_H_
+#define _KDRIVE_H_
+
 #include <stdio.h>
 #include <X11/X.h>
 #define NEED_EVENTS
@@ -851,3 +854,5 @@
 /* function prototypes to be implemented by the drivers */
 void
 InitCard (char *name);
+
+#endif /* _KDRIVE_H_ */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.