Module Name: src Committed By: martin Date: Wed Jul 5 16:09:50 UTC 2023
Modified Files: src/sys/arch/sparc/dev [netbsd-10]: cgfourteen.c sx.c sxvar.h src/sys/dev/sbus [netbsd-10]: mgx.c src/sys/dev/wscons [netbsd-10]: wsdisplay_glyphcache.c wsdisplay_glyphcachevar.h wsdisplay_vcons.c wsdisplay_vconsvar.h Log Message: Pull up following revision(s) (requested by abs in ticket #224): sys/dev/wscons/wsdisplay_vconsvar.h: revision 1.34 sys/dev/wscons/wsdisplay_glyphcachevar.h: revision 1.6 sys/arch/sparc/dev/cgfourteen.c: revision 1.94 sys/arch/sparc/dev/cgfourteen.c: revision 1.95 sys/dev/sbus/mgx.c: revision 1.21 sys/dev/sbus/mgx.c: revision 1.22 sys/dev/sbus/mgx.c: revision 1.23 sys/dev/wscons/wsdisplay_vcons.c: revision 1.65 sys/dev/wscons/wsdisplay_vcons.c: revision 1.66 sys/dev/wscons/wsdisplay_glyphcache.c: revision 1.12 sys/arch/sparc/dev/sxvar.h: revision 1.5 sys/arch/sparc/dev/sx.c: revision 1.6 sys/arch/sparc/dev/sx.c: revision 1.7 make vcons_putchar_buffer() return a flag indicating if anything actually changed, skip the actual drawing op if nothing did add flags for drivers to requesr R2L bit/byte-ordered fonts, default to L2R, chack them in vcons_load_font() instead of just trusting that we'd get what we need initialize the diagnostic register with the value suggested by the SunOS header. This sets a bunch of undocumented bits and yields a 10% speed increase when rendering antialiased text. use macros compatible with xf86-video-suncg14 to issue SX instructions much more readable, alignment weirdness is handled automatically and code is interchangable allow drivers to specify horizontal alignment of glyph cache cells for things like SX which have alignment restrictions add counter to periodically drain the instruction queue in order to avoid stalling the MBus during long SX operations adapted from xf86-video-suncg14 - use sx_wait() to avoid stalling the MBus - request 32bit alignment for glyphcache cells wait for the engine to go idle before issuing rectfill commands we get occasional overlap with blit commands if we just wait for fifo slots needs further investigation, it is possible that not all writes to drawing engine registers are pipelined and of course we don't have docs following a hunch... - cache DEC and FG registers, only write them if the value actually changes - wait for the engine to go idle before writing DEC - wait for FIFO slots on everything else with this we avoid waiting if possible and still avoid overlapping blit and fill commands To generate a diff of this commit: cvs rdiff -u -r1.93 -r1.93.4.1 src/sys/arch/sparc/dev/cgfourteen.c cvs rdiff -u -r1.5 -r1.5.4.1 src/sys/arch/sparc/dev/sx.c cvs rdiff -u -r1.4 -r1.4.30.1 src/sys/arch/sparc/dev/sxvar.h cvs rdiff -u -r1.20 -r1.20.4.1 src/sys/dev/sbus/mgx.c cvs rdiff -u -r1.11 -r1.11.30.1 src/sys/dev/wscons/wsdisplay_glyphcache.c cvs rdiff -u -r1.5 -r1.5.42.1 src/sys/dev/wscons/wsdisplay_glyphcachevar.h cvs rdiff -u -r1.64 -r1.64.4.1 src/sys/dev/wscons/wsdisplay_vcons.c cvs rdiff -u -r1.33 -r1.33.4.1 src/sys/dev/wscons/wsdisplay_vconsvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sparc/dev/cgfourteen.c diff -u src/sys/arch/sparc/dev/cgfourteen.c:1.93 src/sys/arch/sparc/dev/cgfourteen.c:1.93.4.1 --- src/sys/arch/sparc/dev/cgfourteen.c:1.93 Wed May 25 21:01:04 2022 +++ src/sys/arch/sparc/dev/cgfourteen.c Wed Jul 5 16:09:50 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: cgfourteen.c,v 1.93 2022/05/25 21:01:04 macallan Exp $ */ +/* $NetBSD: cgfourteen.c,v 1.93.4.1 2023/07/05 16:09:50 martin Exp $ */ /* * Copyright (c) 1996 @@ -168,6 +168,21 @@ static void cg14_copycols(void *, int, i static void cg14_erasecols(void *, int, int, int, long); static void cg14_copyrows(void *, int, int, int); static void cg14_eraserows(void *, int, int, long); + +/* + * issue ALU instruction: + * sxi(OPCODE, srcA, srcB, dest, count) + */ +#define sxi(inst, a, b, d, cnt) \ + sx_wait(sc->sc_sx); \ + sx_write(sc->sc_sx, SX_INSTRUCTIONS, inst((a), (b), (d), (cnt))) + +/* + * issue memory referencing instruction: + * sxm(OPCODE, address, start register, count) + */ +#define sxm(inst, addr, reg, count) sta((addr) & ~7, ASI_SX, inst((reg), (count), (addr) & 7)) + #endif /* NSX > 0 */ #endif @@ -358,7 +373,7 @@ cgfourteenattach(device_t parent, device sc->sc_fbaddr, 0, 0, 0) & 0xfffff000; aprint_normal_dev(sc->sc_dev, "using %s\n", device_xname(sc->sc_sx->sc_dev)); - aprint_debug_dev(sc->sc_dev, "fb paddr: %08x\n", + aprint_normal_dev(sc->sc_dev, "fb paddr: %08x\n", sc->sc_fb_paddr); sx_write(sc->sc_sx, SX_PAGE_BOUND_LOWER, sc->sc_fb_paddr); sx_write(sc->sc_sx, SX_PAGE_BOUND_UPPER, @@ -379,7 +394,7 @@ cgfourteenattach(device_t parent, device * the last close. This kind of nonsense is needed to give screenblank * a fighting chance of working. */ - + int cgfourteenopen(dev_t dev, int flags, int mode, struct lwp *l) { @@ -567,8 +582,9 @@ cgfourteenmmap(dev_t dev, off_t off, int 0, prot, BUS_SPACE_MAP_LINEAR)); } else if (off >= CG14_SXIO_VOFF && off < (CG14_SXIO_VOFF + 0x03ffffff)) { + off -= CG14_SXIO_VOFF; return (bus_space_mmap(sc->sc_sx->sc_tag, 0x800000000LL, - sc->sc_fb_paddr + (off - CG14_SXIO_VOFF), + sc->sc_fb_paddr + off, prot, BUS_SPACE_MAP_LINEAR)); #endif } else @@ -756,13 +772,13 @@ cg14_setup_wsdisplay(struct cgfourteen_s sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; sc->sc_defaultscreen_descr.nrows = ri->ri_rows; sc->sc_defaultscreen_descr.ncols = ri->ri_cols; - glyphcache_init(&sc->sc_gc, sc->sc_fb.fb_type.fb_height + 5, + glyphcache_init_align(&sc->sc_gc, sc->sc_fb.fb_type.fb_height + 5, (sc->sc_vramsize / sc->sc_fb.fb_type.fb_width) - sc->sc_fb.fb_type.fb_height - 5, sc->sc_fb.fb_type.fb_width, ri->ri_font->fontwidth, ri->ri_font->fontheight, - defattr); + defattr, 4); if (is_cons) { wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, defattr); @@ -1204,20 +1220,20 @@ cg14_rectfill(struct cgfourteen_softc *s pptr = addr; cnt = wi; if (pre) { - sta(pptr & ~7, ASI_SX, SX_STBS(8, pre - 1, pptr & 7)); + sxm(SX_STBS, pptr, 8, pre - 1); pptr += pre; cnt -= pre; } /* now do the aligned pixels in 32bit chunks */ while(cnt > 3) { words = uimin(32, cnt >> 2); - sta(pptr & ~7, ASI_SX, SX_STS(8, words - 1, pptr & 7)); + sxm(SX_STS, pptr, 8, words - 1); pptr += words << 2; cnt -= words << 2; } /* do any remaining pixels byte-wise again */ if (cnt > 0) - sta(pptr & ~7, ASI_SX, SX_STBS(8, cnt - 1, pptr & 7)); + sxm(SX_STBS, pptr, 8, cnt - 1); addr += stride; } } @@ -1275,28 +1291,25 @@ cg14_invert(struct cgfourteen_softc *sc, for (line = 0; line < he; line++) { pptr = addr; /* load a whole scanline */ - sta(pptr & ~7, ASI_SX, SX_LD(8, words - 1, pptr & 7)); + sxm(SX_LD, pptr, 8, words - 1); reg = 8; if (pre) { cg14_set_mask(sc, lmask); - sx_write(sc->sc_sx, SX_INSTRUCTIONS, - SX_ROPB(8, 8, 40, 0)); + sxi(SX_ROPB, 8, 8, 40, 0); reg++; } if (cnt > 0) { cg14_set_mask(sc, 0xffffffff); /* XXX handle cnt > 16 */ - sx_write(sc->sc_sx, SX_INSTRUCTIONS, - SX_ROP(reg, reg, reg + 32, cnt - 1)); + sxi(SX_ROP, reg, reg, reg + 32, cnt - 1); reg += cnt; } if (post) { cg14_set_mask(sc, rmask); - sx_write(sc->sc_sx, SX_INSTRUCTIONS, - SX_ROPB(reg, 7, reg + 32, 0)); + sxi(SX_ROPB, reg, 7, reg + 32, 0); reg++; } - sta(pptr & ~7, ASI_SX, SX_ST(40, words - 1, pptr & 7)); + sxm(SX_ST, pptr, 40, words - 1); addr += stride; } } @@ -1307,7 +1320,7 @@ cg14_slurp(int reg, uint32_t addr, int c int num; while (cnt > 0) { num = uimin(32, cnt); - sta(addr & ~7, ASI_SX, SX_LD(reg, num - 1, addr & 7)); + sxm(SX_LD, addr, reg, num - 1); cnt -= num; reg += num; addr += (num << 2); @@ -1320,7 +1333,7 @@ cg14_spit(int reg, uint32_t addr, int cn int num; while (cnt > 0) { num = uimin(32, cnt); - sta(addr & ~7, ASI_SX, SX_ST(reg, num - 1, addr & 7)); + sxm(SX_ST, addr, reg, num - 1); cnt -= num; reg += num; addr += (num << 2); @@ -1355,10 +1368,8 @@ cg14_bitblt(void *cookie, int xs, int ys dptr = daddr; cnt = wi; if (pre > 0) { - sta(sptr & ~7, ASI_SX, - SX_LDB(32, pre - 1, sptr & 7)); - sta(dptr & ~7, ASI_SX, - SX_STB(32, pre - 1, dptr & 7)); + sxm(SX_LDB, sptr, 32, pre - 1); + sxm(SX_STB, dptr, 32, pre - 1); cnt -= pre; sptr += pre; dptr += pre; @@ -1373,10 +1384,8 @@ cg14_bitblt(void *cookie, int xs, int ys cnt -= num << 2; } if (cnt > 0) { - sta(sptr & ~7, ASI_SX, - SX_LDB(32, cnt - 1, sptr & 7)); - sta(dptr & ~7, ASI_SX, - SX_STB(32, cnt - 1, dptr & 7)); + sxm(SX_LDB, sptr, 32, cnt - 1); + sxm(SX_STB, dptr, 32, cnt - 1); } saddr += skip; daddr += skip; @@ -1389,17 +1398,15 @@ cg14_bitblt(void *cookie, int xs, int ys dptr = daddr; cnt = wi; while(cnt > 31) { - sta(sptr & ~7, ASI_SX, SX_LDB(32, 31, sptr & 7)); - sta(dptr & ~7, ASI_SX, SX_STB(32, 31, dptr & 7)); + sxm(SX_LDB, sptr, 32, 31); + sxm(SX_STB, dptr, 32, 31); sptr += 32; dptr += 32; cnt -= 32; } if (cnt > 0) { - sta(sptr & ~7, ASI_SX, - SX_LDB(32, cnt - 1, sptr & 7)); - sta(dptr & ~7, ASI_SX, - SX_STB(32, cnt - 1, dptr & 7)); + sxm(SX_LDB, sptr, 32, cnt - 1); + sxm(SX_STB, dptr, 32, cnt - 1); } saddr += skip; daddr += skip; @@ -1444,22 +1451,22 @@ cg14_bitblt_gc(void *cookie, int xs, int for (line = 0; line < he; line++) { /* read source line, in all quads */ - sta(saddr & ~7, ASI_SX, SX_LDUQ0(8, swi - 1, saddr & 7)); + sxm(SX_LDUQ0, saddr, 8, swi - 1); /* now write it out */ dd = daddr; r = dreg; if (in > 0) { - sta(dd & ~7, ASI_SX, SX_STB(r, in - 1, dd & 7)); + sxm(SX_STB, dd, r, in - 1); dd += in; r += in; } if (q > 0) { - sta(dd & ~7, ASI_SX, SX_STUQ0(r, q - 1, dd & 7)); + sxm(SX_STUQ0, dd, r, q - 1); r += q << 2; dd += q << 2; } if (out > 0) { - sta(dd & ~7, ASI_SX, SX_STB(r, out - 1, dd & 7)); + sxm(SX_STB, dd, r, out - 1); } saddr += stride; daddr += stride; @@ -1518,7 +1525,7 @@ cg14_putchar(void *cookie, int row, int for (i = 0; i < he; i++) { reg = *data8; cg14_set_mask(sc, reg << 24); - sta(addr & ~7, ASI_SX, SX_STBS(8, wi - 1, addr & 7)); + sxm(SX_STBS, addr, 8, wi - 1); data8++; addr += stride; } @@ -1530,7 +1537,7 @@ cg14_putchar(void *cookie, int row, int for (i = 0; i < he; i++) { reg = *data16; cg14_set_mask(sc, reg << 16); - sta(addr & ~7, ASI_SX, SX_STBS(8, wi - 1, addr & 7)); + sxm(SX_STBS, addr, 8, wi - 1); data16++; addr += stride; } @@ -1679,20 +1686,20 @@ cg14_putchar_aa(void *cookie, int row, i cnt = wi; if (in != 0) { in = 4 - in; /* pixels to write until aligned */ - sta(next & ~7, ASI_SX, SX_STB(8, in - 1, next & 7)); + sxm(SX_STB, next, 8, in - 1); next += in; reg = 8 + in; cnt -= in; } q = cnt >> 2; /* number of writes we can do in quads */ if (q > 0) { - sta(next & ~7, ASI_SX, SX_STUQ0(reg, q - 1, next & 7)); + sxm(SX_STUQ0, next, reg, q - 1); next += (q << 2); cnt -= (q << 2); reg += (q << 2); } if (cnt > 0) { - sta(next & ~7, ASI_SX, SX_STB(reg, cnt - 1, next & 7)); + sxm(SX_STB, next, reg, cnt - 1); } addr += stride; Index: src/sys/arch/sparc/dev/sx.c diff -u src/sys/arch/sparc/dev/sx.c:1.5 src/sys/arch/sparc/dev/sx.c:1.5.4.1 --- src/sys/arch/sparc/dev/sx.c:1.5 Sat Sep 11 20:28:05 2021 +++ src/sys/arch/sparc/dev/sx.c Wed Jul 5 16:09:50 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: sx.c,v 1.5 2021/09/11 20:28:05 andvar Exp $ */ +/* $NetBSD: sx.c,v 1.5.4.1 2023/07/05 16:09:50 martin Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sx.c,v 1.5 2021/09/11 20:28:05 andvar Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sx.c,v 1.5.4.1 2023/07/05 16:09:50 martin Exp $"); #include "locators.h" @@ -84,6 +84,7 @@ sx_attach(device_t parent, device_t self sc->sc_dev = self; sc->sc_tag = ma->ma_bustag; sc->sc_uregs = ma->ma_paddr + 0x1000; + sc->sc_cnt = 0; if (bus_space_map(sc->sc_tag, ma->ma_paddr, 0x1000, 0, &sc->sc_regh)) { aprint_error_dev(self, "failed to map registers\n"); @@ -104,7 +105,7 @@ sx_attach(device_t parent, device_t self sx_write(sc, SX_PAGE_BOUND_LOWER, 0xfc000000); /* cg14 takes up the whole 64MB chunk */ sx_write(sc, SX_PAGE_BOUND_UPPER, 0xffffffff); - sx_write(sc, SX_DIAGNOSTICS, 0); + sx_write(sc, SX_DIAGNOSTICS, SX_DIAG_INIT); sx_write(sc, SX_PLANEMASK, 0xffffffff); /* Index: src/sys/arch/sparc/dev/sxvar.h diff -u src/sys/arch/sparc/dev/sxvar.h:1.4 src/sys/arch/sparc/dev/sxvar.h:1.4.30.1 --- src/sys/arch/sparc/dev/sxvar.h:1.4 Fri Mar 1 02:30:42 2019 +++ src/sys/arch/sparc/dev/sxvar.h Wed Jul 5 16:09:50 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: sxvar.h,v 1.4 2019/03/01 02:30:42 macallan Exp $ */ +/* $NetBSD: sxvar.h,v 1.4.30.1 2023/07/05 16:09:50 martin Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -32,11 +32,14 @@ #ifndef SXVAR_H #define SXVAR_H +#include <sparc/dev/sxreg.h> + struct sx_softc { device_t sc_dev; bus_addr_t sc_uregs; bus_space_tag_t sc_tag; bus_space_handle_t sc_regh; + int sc_cnt; }; static inline void @@ -51,6 +54,26 @@ sx_read(struct sx_softc *sc, int addr) return bus_space_read_4(sc->sc_tag, sc->sc_regh, addr); } +/* + * to be used before issuing SX instructions + * this will periodically allow the instruction queue to drain in order + * to avoid excessive MBus relinquish & retry cycles during long SX ops + * which may cause us to lose interrupts + */ +static inline void +sx_wait(struct sx_softc *sc) +{ + uint32_t reg; + if (sc->sc_cnt > 6) { + do { + reg = bus_space_read_4(sc->sc_tag, sc->sc_regh, + SX_CONTROL_STATUS); + } while ((reg & SX_MT) == 0); + sc->sc_cnt = 0; + } else + sc->sc_cnt++; +} + void sx_dump(void); #endif Index: src/sys/dev/sbus/mgx.c diff -u src/sys/dev/sbus/mgx.c:1.20 src/sys/dev/sbus/mgx.c:1.20.4.1 --- src/sys/dev/sbus/mgx.c:1.20 Thu Nov 11 19:37:30 2021 +++ src/sys/dev/sbus/mgx.c Wed Jul 5 16:09:50 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: mgx.c,v 1.20 2021/11/11 19:37:30 macallan Exp $ */ +/* $NetBSD: mgx.c,v 1.20.4.1 2023/07/05 16:09:50 martin Exp $ */ /*- * Copyright (c) 2014 Michael Lorenz @@ -29,7 +29,7 @@ /* a console driver for the SSB 4096V-MGX graphics card */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mgx.c,v 1.20 2021/11/11 19:37:30 macallan Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mgx.c,v 1.20.4.1 2023/07/05 16:09:50 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -80,7 +80,7 @@ struct mgx_softc { int sc_fbsize; int sc_mode; char sc_name[8]; - uint32_t sc_dec; + uint32_t sc_dec, sc_r_dec, sc_r_fg; u_char sc_cmap_red[256]; u_char sc_cmap_green[256]; u_char sc_cmap_blue[256]; @@ -216,6 +216,24 @@ mgx_write_4(struct mgx_softc *sc, uint32 bus_space_write_4(sc->sc_tag, sc->sc_blith, reg, val); } +static inline void +mgx_set_dec(struct mgx_softc *sc, uint32_t dec) +{ + if (dec == sc->sc_r_dec) return; + sc->sc_r_dec = dec; + mgx_wait_engine(sc); + mgx_write_4(sc, ATR_DEC, dec); +} + +static inline void +mgx_set_fg(struct mgx_softc *sc, uint32_t fg) +{ + if (fg == sc->sc_r_fg) return; + sc->sc_r_fg = fg; + mgx_wait_fifo(sc, 1); + mgx_write_4(sc, ATR_FG, fg); +} + static int mgx_match(device_t parent, cfdata_t cf, void *aux) { @@ -342,7 +360,7 @@ mgx_attach(device_t parent, device_t sel * leave some room between visible screen and glyph cache for upload * buffers used by putchar_mono() */ - bsize = (32 * 1024 * sc->sc_stride - 1) / sc->sc_stride; + bsize = (32 * 1024 + sc->sc_stride - 1) / sc->sc_stride; glyphcache_init(&sc->sc_gc, sc->sc_height + bsize, (0x400000 / sc->sc_stride) - (sc->sc_height + bsize), @@ -531,6 +549,8 @@ mgx_setup(struct mgx_softc *sc, int dept int i; uint8_t reg; + sc->sc_r_dec = 0xffffffff; + sc->sc_r_fg = 0x12345678; /* wait for everything to go idle */ if (mgx_wait_engine(sc) == 0) return; @@ -643,9 +663,9 @@ mgx_bitblt(void *cookie, int xs, int ys, yd += he - 1; dec |= DEC_DIR_Y_REVERSE; } - mgx_wait_fifo(sc, 5); + mgx_set_dec(sc, dec); + mgx_wait_fifo(sc, 4); mgx_write_1(sc, ATR_ROP, rop); - mgx_write_4(sc, ATR_DEC, dec); mgx_write_4(sc, ATR_SRC_XY, (ys << 16) | xs); mgx_write_4(sc, ATR_DST_XY, (yd << 16) | xd); mgx_write_4(sc, ATR_WH, (he << 16) | wi); @@ -666,10 +686,10 @@ mgx_rectfill(void *cookie, int x, int y, dec = sc->sc_dec; dec |= (DEC_COMMAND_RECT << DEC_COMMAND_SHIFT) | (DEC_START_DIMX << DEC_START_SHIFT); - mgx_wait_fifo(sc, 5); + mgx_set_dec(sc, dec); + mgx_set_fg(sc, col); + mgx_wait_fifo(sc, 3); mgx_write_1(sc, ATR_ROP, ROP_SRC); - mgx_write_4(sc, ATR_FG, col); - mgx_write_4(sc, ATR_DEC, dec); mgx_write_4(sc, ATR_DST_XY, (y << 16) | x); mgx_write_4(sc, ATR_WH, (he << 16) | wi); } @@ -753,8 +773,8 @@ mgx_putchar_mono(void *cookie, int row, return; } - mgx_wait_fifo(sc, 3); - mgx_write_4(sc, ATR_FG, ri->ri_devcmap[fg]); + mgx_set_fg(sc, ri->ri_devcmap[fg]); + mgx_wait_fifo(sc, 2); mgx_write_4(sc, ATR_BG, ri->ri_devcmap[bg]); mgx_write_1(sc, ATR_ROP, ROP_SRC); @@ -789,10 +809,10 @@ mgx_putchar_mono(void *cookie, int row, for (i = 0; i < ri->ri_fontscale; i++) d[i] = s[i]; } - mgx_wait_fifo(sc, 5); - mgx_write_4(sc, ATR_DEC, sc->sc_dec | (DEC_COMMAND_BLT << DEC_COMMAND_SHIFT) | + mgx_set_dec(sc, sc->sc_dec | (DEC_COMMAND_BLT << DEC_COMMAND_SHIFT) | (DEC_START_DIMX << DEC_START_SHIFT) | DEC_SRC_LINEAR | DEC_SRC_CONTIGUOUS | DEC_MONOCHROME); + mgx_wait_fifo(sc, 3); mgx_write_4(sc, ATR_SRC_XY, ((scratch & 0xfff000) << 4) | (scratch & 0xfff)); mgx_write_4(sc, ATR_DST_XY, (y << 16) | x); mgx_write_4(sc, ATR_WH, (he << 16) | wi); Index: src/sys/dev/wscons/wsdisplay_glyphcache.c diff -u src/sys/dev/wscons/wsdisplay_glyphcache.c:1.11 src/sys/dev/wscons/wsdisplay_glyphcache.c:1.11.30.1 --- src/sys/dev/wscons/wsdisplay_glyphcache.c:1.11 Mon Sep 3 16:29:34 2018 +++ src/sys/dev/wscons/wsdisplay_glyphcache.c Wed Jul 5 16:09:50 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: wsdisplay_glyphcache.c,v 1.11 2018/09/03 16:29:34 riastradh Exp $ */ +/* $NetBSD: wsdisplay_glyphcache.c,v 1.11.30.1 2023/07/05 16:09:50 martin Exp $ */ /* * Copyright (c) 2012 Michael Lorenz @@ -53,17 +53,24 @@ static inline int attr2idx(long attr) { - if ((attr & 0xf0f0fff8) != 0) + if ((attr & 0xf0f00ff8) != 0) return -1; return (((attr >> 16) & 0x0f) | ((attr >> 20) & 0xf0)); } -/* first line, lines, width, attr */ int glyphcache_init(glyphcache *gc, int first, int lines, int width, int cellwidth, int cellheight, long attr) { + return glyphcache_init_align(gc, first, lines, width, cellwidth, cellheight, + attr, 0); +} + +int +glyphcache_init_align(glyphcache *gc, int first, int lines, int width, + int cellwidth, int cellheight, long attr, int alignment) +{ /* first the geometry stuff */ if (lines < 0) lines = 0; @@ -72,6 +79,7 @@ glyphcache_init(glyphcache *gc, int firs gc->gc_cellheight = -1; gc->gc_firstline = first; gc->gc_lines = lines; + gc->gc_cellalign = alignment; gc->gc_buckets = NULL; gc->gc_numbuckets = 0; // XXX: Never free? @@ -97,9 +105,16 @@ glyphcache_reconfig(glyphcache *gc, int } gc->gc_cellwidth = cellwidth; + if (gc->gc_cellalign != 0) { + /* alignment in bytes */ + gc->gc_cellstride = + (gc->gc_cellwidth + gc->gc_cellalign - 1) & + ~(gc->gc_cellalign - 1); + } else + gc->gc_cellstride = cellwidth; gc->gc_cellheight = cellheight; - gc->gc_cellsperline = gc->gc_width / cellwidth; + gc->gc_cellsperline = gc->gc_width / gc->gc_cellstride; cache_lines = gc->gc_lines / cellheight; gc->gc_numcells = cache_lines * gc->gc_cellsperline; @@ -144,6 +159,8 @@ glyphcache_reconfig(glyphcache *gc, int glyphcache_wipe(gc); DPRINTF("%s: using %d cells total, from %d width %d\n", __func__, gc->gc_numcells, gc->gc_firstline, gc->gc_cellsperline); + DPRINTF("%s: cell size %d x %d, stride %d\n", __func__, + gc->gc_cellwidth, gc->gc_cellheight, gc->gc_cellstride); return 0; } @@ -209,7 +226,7 @@ glyphcache_add(glyphcache *gc, int c, in cell += b->gb_firstcell; cy = gc->gc_firstline + (cell / gc->gc_cellsperline) * gc->gc_cellheight; - cx = (cell % gc->gc_cellsperline) * gc->gc_cellwidth; + cx = (cell % gc->gc_cellsperline) * gc->gc_cellstride; b->gb_map[c - 33] = (cx << 16) | cy; gc->gc_bitblt(gc->gc_blitcookie, x, y, cx, cy, gc->gc_cellwidth, gc->gc_cellheight, gc->gc_rop); Index: src/sys/dev/wscons/wsdisplay_glyphcachevar.h diff -u src/sys/dev/wscons/wsdisplay_glyphcachevar.h:1.5 src/sys/dev/wscons/wsdisplay_glyphcachevar.h:1.5.42.1 --- src/sys/dev/wscons/wsdisplay_glyphcachevar.h:1.5 Fri Jun 2 19:30:10 2017 +++ src/sys/dev/wscons/wsdisplay_glyphcachevar.h Wed Jul 5 16:09:50 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: wsdisplay_glyphcachevar.h,v 1.5 2017/06/02 19:30:10 macallan Exp $ */ +/* $NetBSD: wsdisplay_glyphcachevar.h,v 1.5.42.1 2023/07/05 16:09:50 martin Exp $ */ /* * Copyright (c) 2012 Michael Lorenz @@ -45,6 +45,8 @@ typedef struct _glyphcache { /* geometry */ int gc_numcells; int gc_cellwidth; + int gc_cellstride; + int gc_cellalign; int gc_cellheight; int gc_cellsperline; int gc_firstline; /* first line in vram to use for glyphs */ @@ -71,6 +73,9 @@ typedef struct _glyphcache { /* first line, lines, width, cellwidth, cellheight, attr */ int glyphcache_init(glyphcache *, int, int, int, int, int, long); +/* first line, lines, width, cellwidth, cellheight, attr, alignment */ +int glyphcache_init_align(glyphcache *, int, int, int, int, int, long, int); + /* adapt to changed font */ int glyphcache_reconfig(glyphcache *, int, int, long); Index: src/sys/dev/wscons/wsdisplay_vcons.c diff -u src/sys/dev/wscons/wsdisplay_vcons.c:1.64 src/sys/dev/wscons/wsdisplay_vcons.c:1.64.4.1 --- src/sys/dev/wscons/wsdisplay_vcons.c:1.64 Mon Jul 18 11:09:22 2022 +++ src/sys/dev/wscons/wsdisplay_vcons.c Wed Jul 5 16:09:50 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: wsdisplay_vcons.c,v 1.64 2022/07/18 11:09:22 martin Exp $ */ +/* $NetBSD: wsdisplay_vcons.c,v 1.64.4.1 2023/07/05 16:09:50 martin Exp $ */ /*- * Copyright (c) 2005, 2006 Michael Lorenz @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.64 2022/07/18 11:09:22 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.64.4.1 2023/07/05 16:09:50 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -121,7 +121,7 @@ static void vcons_copycols_buffer(void * static void vcons_erasecols_buffer(void *, int, int, int, long); static void vcons_copyrows_buffer(void *, int, int, int); static void vcons_eraserows_buffer(void *, int, int, long); -static void vcons_putchar_buffer(void *, int, int, u_int, long); +static int vcons_putchar_buffer(void *, int, int, u_int, long); /* * actual wrapper methods which call both the _buffer ones above and the @@ -478,7 +478,14 @@ vcons_load_font(void *v, void *cookie, s flags |= WSFONT_FIND_ALPHA; } - fcookie = wsfont_find(f->name, 0, 0, 0, 0, 0, flags); + fcookie = wsfont_find(f->name, 0, 0, 0, + /* bitorder */ + scr->scr_flags & VCONS_FONT_BITS_R2L ? + WSDISPLAY_FONTORDER_R2L : WSDISPLAY_FONTORDER_L2R, + /* byteorder */ + scr->scr_flags & VCONS_FONT_BYTES_R2L ? + WSDISPLAY_FONTORDER_R2L : WSDISPLAY_FONTORDER_L2R, + flags); if (fcookie == -1) return EINVAL; @@ -1237,22 +1244,25 @@ vcons_eraserows(void *cookie, int row, i vcons_unlock(scr); } -static void +static int vcons_putchar_buffer(void *cookie, int row, int col, u_int c, long attr) { struct rasops_info *ri = cookie; struct vcons_screen *scr = ri->ri_hw; int offset = vcons_offset_to_zero(scr); - int pos; + int pos, ret = 0; if ((row >= 0) && (row < ri->ri_rows) && (col >= 0) && (col < ri->ri_cols)) { pos = col + row * ri->ri_cols; + ret = (scr->scr_attrs[pos + offset] != attr) || + (scr->scr_chars[pos + offset] != c); scr->scr_attrs[pos + offset] = attr; scr->scr_chars[pos + offset] = c; } - vcons_dirty(scr); + if (ret) vcons_dirty(scr); + return ret; } #ifdef VCONS_DRAW_INTR @@ -1282,8 +1292,9 @@ vcons_putchar(void *cookie, int row, int { struct rasops_info *ri = cookie; struct vcons_screen *scr = ri->ri_hw; - - vcons_putchar_buffer(cookie, row, col, c, attr); + int need_draw; + + need_draw = vcons_putchar_buffer(cookie, row, col, c, attr); if (vcons_use_intr(scr)) return; @@ -1291,12 +1302,13 @@ vcons_putchar(void *cookie, int row, int vcons_lock(scr); if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) { #ifdef VCONS_DRAW_INTR - vcons_putchar_cached(cookie, row, col, c, attr); + if (need_draw) vcons_putchar_cached(cookie, row, col, c, attr); #else if (row == ri->ri_crow && col == ri->ri_ccol) { ri->ri_flg &= ~RI_CURSOR; - } - scr->putchar(cookie, row, col, c, attr); + scr->putchar(cookie, row, col, c, attr); + } else if (need_draw) + scr->putchar(cookie, row, col, c, attr); #endif } vcons_unlock(scr); Index: src/sys/dev/wscons/wsdisplay_vconsvar.h diff -u src/sys/dev/wscons/wsdisplay_vconsvar.h:1.33 src/sys/dev/wscons/wsdisplay_vconsvar.h:1.33.4.1 --- src/sys/dev/wscons/wsdisplay_vconsvar.h:1.33 Sun Jul 17 20:23:17 2022 +++ src/sys/dev/wscons/wsdisplay_vconsvar.h Wed Jul 5 16:09:50 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: wsdisplay_vconsvar.h,v 1.33 2022/07/17 20:23:17 riastradh Exp $ */ +/* $NetBSD: wsdisplay_vconsvar.h,v 1.33.4.1 2023/07/05 16:09:50 martin Exp $ */ /*- * Copyright (c) 2005, 2006 Michael Lorenz @@ -70,6 +70,11 @@ struct vcons_screen { #define VCONS_LOADFONT 0x40 /* driver can load_font() */ #define VCONS_NO_CURSOR 0x80 /* use putchar() based cursor(), to * avoid fb reads */ +#define VCONS_FONT_BITS_R2L 0x100 /* request right-to-left bitorder in + * wsfont_find() */ +#define VCONS_FONT_BYTES_R2L 0x200 /* request right-to-left byteorder in + * wsfont_find() */ + /* status flags used by vcons */ uint32_t scr_status; #define VCONS_IS_VISIBLE 1 /* this screen is currently visible */