X.org on Amiga, 16 color mode
Jukka Andberg <[email protected]> Thu, 29 Feb 2024 21:03:09 +0200
| Newsgroups | gmane.os.netbsd.devel.x11,gmane.os.netbsd.ports.amiga |
|---|---|
| Message-ID | <[email protected]> |
Hi all, I was looking into how to get the x.org server running with color on non-AGA Amigas. As you may remember, it is currently working with 256 colors on AGA-equipped Amigas and black/white on others. Looks like the server wants to use 8bpp memory layout for depth 4 (16 colors), defined in xf86Init.c formats array. This differs from old Xamiga which used 4bpp with depth 4. Working solution seems to be creating the shadowfb with 8bpp and depth 4, and then handling conversion from 8bpp pixels to 4 bitplanes in the shadow update function. For the conversion it needs a new shadow update function, which is pretty similar to existing shadowUpdateAfb4, just reading 8-bit input pixels instead of 4-bit pixels. Patch attached. Any thoughts? --jukka
x4bpp.diff
(application/octet-stream, 4.8 KB)
diff -r e61cebc6a4c9 external/mit/xf86-video-wsfb/dist/src/wsfb_driver.c
--- a/external/mit/xf86-video-wsfb/dist/src/wsfb_driver.c Wed Feb 07 18:01:48 2024 +0000
+++ b/external/mit/xf86-video-wsfb/dist/src/wsfb_driver.c Wed Feb 28 18:02:11 2024 +0200
@@ -554,14 +554,20 @@
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.
+ * 8bpp, 4bpp, and 1bpp supported in this driver.
+ * With 8bpp/4bpp conversion to bitplane format
+ * is done in shadow update proc. In both cases
+ * shadow fb uses 8bpp memory layout and shadow
+ * update proc ignores the possible extra bits.
* With 1bpp no conversion needed.
*/
#ifdef HAVE_SHADOW_AFB
if (bitsperpixel == 8) {
fPtr->planarAfb = TRUE;
+ } else if (bitsperpixel == 4) {
+ fPtr->planarAfb = TRUE;
+ default_depth = 4;
+ bitsperpixel = 8;
} else
#endif
{
@@ -643,6 +649,16 @@
fPtr->fbi.fbi_pixeltype = WSFB_RGB;
}
#endif
+#ifdef HAVE_SHADOW_AFB
+ if (fPtr->planarAfb)
+ {
+ if (!fPtr->shadowFB) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Shadow FB forced on for planar framebuffer\n");
+ fPtr->shadowFB = TRUE;
+ }
+ }
+#endif
/* Rotation */
fPtr->rotate = WSFB_ROTATE_NONE;
if ((s = xf86GetOptValString(fPtr->Options, OPTION_ROTATE))) {
@@ -891,9 +907,12 @@
shadowproc = wsfbUpdateRotatePacked;
} else
#ifdef HAVE_SHADOW_AFB
- if (fPtr->planarAfb) {
+ if (fPtr->planarAfb && fPtr->fbi.fbi_bitsperpixel == 8) {
shadowproc = shadowUpdateAfb8;
windowproc = WsfbWindowAfb;
+ } else if (fPtr->planarAfb && fPtr->fbi.fbi_bitsperpixel == 4) {
+ shadowproc = shadowUpdateAfb4x8;
+ windowproc = WsfbWindowAfb;
} else
#endif
{
diff -r e61cebc6a4c9 external/mit/xorg-server/dist/miext/shadow/shadow.h
--- a/external/mit/xorg-server/dist/miext/shadow/shadow.h Wed Feb 07 18:01:48 2024 +0000
+++ b/external/mit/xorg-server/dist/miext/shadow/shadow.h Wed Feb 28 18:02:11 2024 +0200
@@ -88,6 +88,9 @@
shadowUpdateAfb8(ScreenPtr pScreen, shadowBufPtr pBuf);
extern _X_EXPORT void
+ shadowUpdateAfb4x8(ScreenPtr pScreen, shadowBufPtr pBuf);
+
+extern _X_EXPORT void
shadowUpdateIplan2p4(ScreenPtr pScreen, shadowBufPtr pBuf);
extern _X_EXPORT void
diff -r e61cebc6a4c9 external/mit/xorg-server/dist/miext/shadow/shafb4.c
--- a/external/mit/xorg-server/dist/miext/shadow/shafb4.c Wed Feb 07 18:01:48 2024 +0000
+++ b/external/mit/xorg-server/dist/miext/shadow/shafb4.c Wed Feb 28 18:02:11 2024 +0200
@@ -137,3 +137,70 @@
pbox++;
}
}
+
+ /*
+ * Like above, except input is 8-bit chunky pixels (upper 4 bits zero)
+ */
+void
+shadowUpdateAfb4x8(ScreenPtr pScreen, shadowBufPtr pBuf)
+{
+ RegionPtr damage = DamageRegion(pBuf->pDamage);
+ PixmapPtr pShadow = pBuf->pPixmap;
+ int nbox = RegionNumRects(damage);
+ BoxPtr pbox = RegionRects(damage);
+ FbBits *shaBase;
+ CARD32 *shaLine, *sha;
+ FbStride shaStride;
+ int scrLine;
+ _X_UNUSED int shaBpp, shaXoff, shaYoff;
+ int x, y, w, h;
+ int i, n;
+ CARD32 *win;
+ CARD32 off, winStride;
+ CARD32 dwords[4];
+
+ fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff,
+ shaYoff);
+ if (sizeof(FbBits) != sizeof(CARD32))
+ shaStride = shaStride * sizeof(FbBits) / sizeof(CARD32);
+
+ while (nbox--) {
+ x = pbox->x1;
+ y = pbox->y1;
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+
+ scrLine = x & -32;
+ shaLine = (CARD32 *)shaBase + y * shaStride + scrLine / sizeof(CARD32);
+
+ off = scrLine / 8; /* byte offset in bitplane scanline */
+ n = ((x & 31) + w + 31) / 32; /* number of c2p units in scanline */
+
+ while (h--) {
+ sha = shaLine;
+ win = (CARD32 *) (*pBuf->window) (pScreen,
+ y,
+ off,
+ SHADOW_WINDOW_WRITE,
+ &winStride,
+ pBuf->closure);
+ if (!win)
+ return;
+ for (i = 0; i < n; i++) {
+ dwords[0] = (sha[0] << 4) | sha[1];
+ dwords[2] = (sha[2] << 4) | sha[3];
+ dwords[1] = (sha[4] << 4) | sha[5];
+ dwords[3] = (sha[6] << 4) | sha[7];
+ transp4(dwords, 16, 1);
+ transp4(dwords, 8, 2);
+ transp4(dwords, 2, 1);
+ transp4(dwords, 1, 2);
+ store_afb4(win++, winStride, dwords);
+ sha += 8;
+ }
+ shaLine += shaStride;
+ y++;
+ }
+ pbox++;
+ }
+}