Color support for wsfb/Amiga
Jukka Andberg <[email protected]> Wed, 22 Jun 2022 19:26:22 +0300
| Newsgroups | gmane.os.netbsd.devel.x11,gmane.os.netbsd.ports.amiga |
|---|---|
| Message-ID | <[email protected]> |
Hi The wsfb driver has been working only in monochrome with Amiga native graphics mode due to the driver not supporting the Amiga's planar video memory format. But actually I found out that there is a c2p routine [1] included with xorg-server that works with shadowfb to convert the pixels into Amiga planar format. Enabling it for 8-bit depth looks pretty simple. In practice with this we could get 256 color mode on AGA chipsets. For other depths I didn't have much success so it is still monochrome for non-AGA. Performance is also not that great, but it is somewhat usable. Patch attached. Any thoughts before I commit? --jukka [1] http://cvsweb.netbsd.org/bsdweb.cgi/xsrc/external/mit/xorg-server/dist/miext/shadow/shafb8.c P.S. With these wsfb changes the fake 1 bit depth hack can be removed from kernel side.
wsfb.diff
(application/octet-stream, 5.4 KB)
Index: src/sys/arch/amiga/dev/amidisplaycc.c
===================================================================
--- src/sys/arch/amiga/dev/amidisplaycc.c (revision 928)
+++ src/sys/arch/amiga/dev/amidisplaycc.c (working copy)
@@ -1112,14 +1112,13 @@
bm = adp->gfxview->bitmap;
KASSERT(bm);
- /* Depth 1 since current X wsfb driver doesn't support multiple bitplanes */
memset(fbinfo, 0, sizeof(*fbinfo));
- fbinfo->fbi_fbsize = bm->bytes_per_row * bm->rows;
+ fbinfo->fbi_fbsize = bm->bytes_per_row * bm->rows * adp->gfxdepth;
fbinfo->fbi_fboffset = 0;
fbinfo->fbi_width = bm->bytes_per_row * 8;
fbinfo->fbi_height = bm->rows;
fbinfo->fbi_stride = bm->bytes_per_row;
- fbinfo->fbi_bitsperpixel = 1;
+ fbinfo->fbi_bitsperpixel = adp->gfxdepth;
fbinfo->fbi_pixeltype = WSFB_CI;
fbinfo->fbi_flags = 0;
fbinfo->fbi_subtype.fbi_cmapinfo.cmap_entries = 1 << adp->gfxdepth;
Index: xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb.h
===================================================================
--- xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb.h (revision 928)
+++ xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb.h (working copy)
@@ -63,6 +63,7 @@
Bool shadowFB;
Bool HWCursor;
Bool useSwap32;
+ Bool planarAfb;
CloseScreenProcPtr CloseScreen;
CreateScreenResourcesProcPtr CreateScreenResources;
void (*PointerMoved)(SCRN_ARG_TYPE, int, int);
Index: xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb_driver.c
===================================================================
--- xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb_driver.c (revision 928)
+++ xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb_driver.c (working copy)
@@ -121,6 +121,8 @@
static Bool WsfbCloseScreen(CLOSE_SCREEN_ARGS_DECL);
static void *WsfbWindowLinear(ScreenPtr, CARD32, CARD32, int, CARD32 *,
void *);
+static void *WsfbWindowAfb(ScreenPtr, CARD32, CARD32, int, CARD32 *,
+ void *);
static void WsfbPointerMoved(SCRN_ARG_TYPE, int, int);
static Bool WsfbEnterVT(VT_FUNC_ARGS_DECL);
static void WsfbLeaveVT(VT_FUNC_ARGS_DECL);
@@ -211,6 +213,7 @@
"shadowUpdatePackedWeak",
"shadowUpdateRotatePacked",
"shadowUpdateRotatePackedWeak",
+ "shadowUpdateAfb8",
NULL
};
@@ -444,6 +447,13 @@
return FALSE;
}
+ if (ioctl(fPtr->fd, WSDISPLAYIO_GTYPE, &wstype) == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ioctl WSDISPLAY_GTYPE: %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+
if (ioctl(fPtr->fd, WSDISPLAYIO_GET_FBINFO, &fPtr->fbi) != 0) {
struct wsdisplay_fbinfo info;
struct wsdisplayio_fbinfo *fbi = &fPtr->fbi;
@@ -457,12 +467,6 @@
strerror(errno));
return FALSE;
}
- if (ioctl(fPtr->fd, WSDISPLAYIO_GTYPE, &wstype) == -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ioctl WSDISPLAY_GTYPE: %s\n",
- strerror(errno));
- return FALSE;
- }
if (ioctl(fPtr->fd, WSDISPLAYIO_LINEBYTES, &lb) == -1) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"ioctl WSDISPLAYIO_LINEBYTES: %s\n",
@@ -573,6 +577,25 @@
bitsperpixel = 1;
}
#endif
+#if defined(__NetBSD__) && defined(WSDISPLAY_TYPE_AMIGACC)
+ if (wstype == WSDISPLAY_TYPE_AMIGACC)
+ {
+ /*
+ * Video memory is organized in bitplanes.
+ * 8bpp or 1bpp supported in this driver.
+ * With 8bpp conversion to bitplane format
+ * is done in shadow update proc.
+ * With 1bpp no conversion needed.
+ */
+ if (bitsperpixel == 8) {
+ fPtr->planarAfb = TRUE;
+ } else {
+ default_depth = 1;
+ bitsperpixel = 1;
+ }
+ }
+#endif
+
if (!xf86SetDepthBpp(pScrn, default_depth, default_depth,
bitsperpixel,
bitsperpixel >= 24 ? Support24bppFb|Support32bppFb : 0))
@@ -826,6 +849,7 @@
PixmapPtr pPixmap;
Bool ret;
void (*shadowproc)(ScreenPtr, shadowBufPtr);
+ ShadowWindowProc windowproc = WsfbWindowLinear;
pScreen->CreateScreenResources = fPtr->CreateScreenResources;
ret = pScreen->CreateScreenResources(pScreen);
@@ -841,11 +865,14 @@
shadowproc = WsfbShadowUpdateSwap32;
} else if (fPtr->rotate) {
shadowproc = shadowUpdateRotatePacked;
+ } else if (fPtr->planarAfb) {
+ shadowproc = shadowUpdateAfb8;
+ windowproc = WsfbWindowAfb;
} else
shadowproc = shadowUpdatePacked;
if (!shadowAdd(pScreen, pPixmap, shadowproc,
- WsfbWindowLinear, fPtr->rotate, NULL)) {
+ windowproc, fPtr->rotate, NULL)) {
return FALSE;
}
return TRUE;
@@ -987,6 +1014,9 @@
*/
len = pScrn->virtualX * pScrn->virtualY *
(pScrn->bitsPerPixel >> 3);
+ } else if (fPtr->planarAfb) {
+ len = pScrn->virtualX * pScrn->virtualY *
+ (pScrn->bitsPerPixel >> 3);
} else {
len = fPtr->fbi.fbi_stride * pScrn->virtualY;
}
@@ -1006,6 +1036,8 @@
*/
if (fPtr->rotate) {
width = pScrn->displayWidth;
+ } else if (fPtr->planarAfb) {
+ width = pScrn->displayWidth;
} else {
if (pScrn->bitsPerPixel > 8) {
width =
@@ -1232,6 +1264,23 @@
return ((CARD8 *)fPtr->fbstart + row * fPtr->fbi.fbi_stride + offset);
}
+/**
+ * For use with shadowUpdateAfb8
+ *
+ * For video memory layout with non-interleaved bitplanes.
+ */
+static void *
+WsfbWindowAfb(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode,
+ CARD32 *size, void *closure)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ WsfbPtr fPtr = WSFBPTR(pScrn);
+
+ /* size is offset from start of bitplane to next bitplane */
+ *size = fPtr->fbi.fbi_stride * fPtr->fbi.fbi_height;
+ return ((CARD8 *)fPtr->fbstart + row * fPtr->fbi.fbi_stride + offset);
+}
+
static void
WsfbPointerMoved(SCRN_ARG_TYPE arg, int x, int y)
{