Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc/dev - implement buttom-up copies in cg14_bitb...
details: https://anonhg.NetBSD.org/src/rev/1ec70cd60625
branches: trunk
changeset: 784723:1ec70cd60625
user: macallan <macallan%NetBSD.org@localhost>
date: Thu Feb 07 16:14:30 2013 +0000
description:
- implement buttom-up copies in cg14_bitblt() so scrolling down works now
- use more registers when copying
- use hardware to draw the cursor
- use putchar() for horizontal scrolling since byte-wise overlapping copy
ops wouldn't be any faster anyway
diffstat:
sys/arch/sparc/dev/cgfourteen.c | 176 ++++++++++++++++++++++++++++++---------
1 files changed, 136 insertions(+), 40 deletions(-)
diffs (truncated from 310 to 300 lines):
diff -r 0b387d0a441d -r 1ec70cd60625 sys/arch/sparc/dev/cgfourteen.c
--- a/sys/arch/sparc/dev/cgfourteen.c Thu Feb 07 15:38:42 2013 +0000
+++ b/sys/arch/sparc/dev/cgfourteen.c Thu Feb 07 16:14:30 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cgfourteen.c,v 1.70 2013/02/06 04:10:54 macallan Exp $ */
+/* $NetBSD: cgfourteen.c,v 1.71 2013/02/07 16:14:30 macallan Exp $ */
/*
* Copyright (c) 1996
@@ -151,12 +151,13 @@
#if NSX > 0
static void cg14_wait_idle(struct cgfourteen_softc *);
static void cg14_rectfill(struct cgfourteen_softc *, int, int, int, int, uint32_t);
+static void cg14_invert(struct cgfourteen_softc *, int, int, int, int);
static void cg14_bitblt(void *, int, int, int, int, int, int, int);
#if 0
-static void cg14_cursor(void *, int, int, int);
static void cg14_putchar_aa(void *, int, int, u_int, long);
#endif
+static void cg14_cursor(void *, int, int, int);
static void cg14_putchar(void *, int, int, u_int, long);
static void cg14_copycols(void *, int, int, int, int);
static void cg14_erasecols(void *, int, int, int, long);
@@ -360,14 +361,13 @@
sc->sc_fbaddr, 0, 0, 0) & 0xfffff000;
aprint_normal_dev(sc->sc_dev, "using %s\n",
device_xname(sc->sc_sx->sc_dev));
- aprint_normal_dev(sc->sc_dev, "fb paddr: %08x\n",
+ aprint_debug_dev(sc->sc_dev, "fb paddr: %08x\n",
sc->sc_fb_paddr);
-#if 0
sx_write(sc->sc_sx, SX_PAGE_BOUND_LOWER, sc->sc_fb_paddr);
sx_write(sc->sc_sx, SX_PAGE_BOUND_UPPER,
sc->sc_fb_paddr + 0x03ffffff);
-#endif
}
+ cg14_wait_idle(sc);
#endif
cg14_setup_wsdisplay(sc, isconsole);
#endif
@@ -1012,7 +1012,13 @@
ri->ri_bits = (char *)sc->sc_fb.fb_pixels;
#if NSX > 0
- if (sc->sc_sx == NULL)
+ /*
+ * unaligned copies with horizontal overlap are slow, so don't bother
+ * handling them in cg14_bitblt() and use putchar() instead
+ */
+ if (sc->sc_sx != NULL) {
+ scr->scr_flags |= VCONS_NO_COPYCOLS;
+ } else
#endif
scr->scr_flags |= VCONS_DONT_READ;
@@ -1034,8 +1040,8 @@
ri->ri_ops.copycols = cg14_copycols;
ri->ri_ops.eraserows = cg14_eraserows;
ri->ri_ops.erasecols = cg14_erasecols;
+ ri->ri_ops.cursor = cg14_cursor;
#if 0
- ri->ri_ops.cursor = cg14_cursor;
if (FONT_IS_ALPHA(ri->ri_font)) {
ri->ri_ops.putchar = cg14_putchar_aa;
} else
@@ -1184,25 +1190,112 @@
uint32_t colour)
{
uint32_t addr, pptr;
- int line, cnt;
+ int line, cnt, pre, words;
int stride = sc->sc_fb.fb_type.fb_width;
addr = sc->sc_fb_paddr + x + stride * y;
sx_write(sc->sc_sx, SX_QUEUED(8), colour);
sx_write(sc->sc_sx, SX_QUEUED(9), colour);
+ /*
+ * Calculate the number of pixels we need to do one by one
+ * until we're 32bit aligned, then do the rest in 32bit
+ * mode. Assumes that stride is always a multiple of 4.
+ */
+ pre = addr & 3;
+ if (pre != 0) pre = 4 - pre;
for (line = 0; line < he; line++) {
pptr = addr;
cnt = wi;
- while(cnt > 32) {
- sta(pptr, ASI_SX, SX_STBS(8, 31, pptr & 7));
- pptr += 32;
- cnt -= 32;
+ if (pre) {
+ sta(pptr, ASI_SX, SX_STBS(8, pre - 1, pptr & 7));
+ pptr += pre;
+ cnt -= pre;
}
+ /* now do the aligned pixels in 32bit chunks */
+ while(cnt > 31) {
+ words = min(32, cnt >> 2);
+ sta(pptr, ASI_SX, SX_STS(8, words - 1, pptr & 7));
+ pptr += words << 2;
+ cnt -= words << 2;
+ }
+ /* do any remaining pixels byte-wise again */
if (cnt > 0)
sta(pptr, ASI_SX, SX_STBS(8, cnt - 1, pptr & 7));
addr += stride;
}
- cg14_wait_idle(sc);
+}
+
+static void
+cg14_invert(struct cgfourteen_softc *sc, int x, int y, int wi, int he)
+{
+ uint32_t addr, pptr;
+ int line, cnt, pre, words;
+ int stride = sc->sc_fb.fb_type.fb_width;
+
+ addr = sc->sc_fb_paddr + x + stride * y;
+ sx_write(sc->sc_sx, SX_ROP_CONTROL, 0x33); /* ~src a */
+ /*
+ * Calculate the number of pixels we need to do one by one
+ * until we're 32bit aligned, then do the rest in 32bit
+ * mode. Assumes that stride is always a multiple of 4.
+ */
+ pre = addr & 3;
+ if (pre != 0) pre = 4 - pre;
+ for (line = 0; line < he; line++) {
+ pptr = addr;
+ cnt = wi;
+ if (pre) {
+ sta(pptr, ASI_SX, SX_LDB(8, pre - 1, pptr & 7));
+ sx_write(sc->sc_sx, SX_INSTRUCTIONS,
+ SX_ROP(8, 8, 32, pre - 1));
+ sta(pptr, ASI_SX, SX_STB(32, pre - 1, pptr & 7));
+ pptr += pre;
+ cnt -= pre;
+ }
+ /* now do the aligned pixels in 32bit chunks */
+ while(cnt > 15) {
+ words = min(16, cnt >> 2);
+ sta(pptr, ASI_SX, SX_LD(8, words - 1, pptr & 7));
+ sx_write(sc->sc_sx, SX_INSTRUCTIONS,
+ SX_ROP(8, 8, 32, words - 1));
+ sta(pptr, ASI_SX, SX_ST(32, words - 1, pptr & 7));
+ pptr += words << 2;
+ cnt -= words << 2;
+ }
+ /* do any remaining pixels byte-wise again */
+ if (cnt > 0)
+ sta(pptr, ASI_SX, SX_LDB(8, cnt - 1, pptr & 7));
+ sx_write(sc->sc_sx, SX_INSTRUCTIONS,
+ SX_ROP(8, 8, 32, cnt - 1));
+ sta(pptr, ASI_SX, SX_STB(32, cnt - 1, pptr & 7));
+ addr += stride;
+ }
+}
+
+static inline void
+cg14_slurp(int reg, uint32_t addr, int cnt)
+{
+ int num;
+ while (cnt > 0) {
+ num = min(32, cnt);
+ sta(addr, ASI_SX, SX_LD(reg, num - 1, addr & 7));
+ cnt -= num;
+ reg += num;
+ addr += (num << 2);
+ }
+}
+
+static inline void
+cg14_spit(int reg, uint32_t addr, int cnt)
+{
+ int num;
+ while (cnt > 0) {
+ num = min(32, cnt);
+ sta(addr, ASI_SX, SX_ST(reg, num - 1, addr & 7));
+ cnt -= num;
+ reg += num;
+ addr += (num << 2);
+ }
}
static void
@@ -1212,9 +1305,19 @@
struct cgfourteen_softc *sc = cookie;
uint32_t saddr, daddr, sptr, dptr;
int line, cnt, stride = sc->sc_fb.fb_type.fb_width;
+ int num, words, skip;
- saddr = sc->sc_fb_paddr + xs + stride * ys;
- daddr = sc->sc_fb_paddr + xd + stride * yd;
+ if (ys < yd) {
+ /* need to go bottom-up */
+ saddr = sc->sc_fb_paddr + xs + stride * (ys + he - 1);
+ daddr = sc->sc_fb_paddr + xd + stride * (yd + he - 1);
+ skip = -stride;
+ } else {
+ saddr = sc->sc_fb_paddr + xs + stride * ys;
+ daddr = sc->sc_fb_paddr + xd + stride * yd;
+ skip = stride;
+ }
+
if ((saddr & 3) == (daddr & 3)) {
int pre = saddr & 3; /* pixels to copy byte-wise */
if (pre != 0) pre = 4 - pre;
@@ -1229,27 +1332,21 @@
sptr += pre;
dptr += pre;
}
- while(cnt > 128) {
- sta(sptr, ASI_SX, SX_LD(32, 31, sptr & 7));
- sta(dptr, ASI_SX, SX_ST(32, 31, dptr & 7));
- sptr += 128;
- dptr += 128;
- cnt -= 128;
- }
- if (cnt > 3) {
- int words = cnt >> 2;
- sta(sptr, ASI_SX, SX_LD(32, words - 1, sptr & 7));
- sta(dptr, ASI_SX, SX_ST(32, words - 1, dptr & 7));
- sptr += words << 2;
- dptr += words << 2;
- cnt -= words << 2;
+ words = cnt >> 2;
+ while(cnt > 3) {
+ num = min(120, words);
+ cg14_slurp(8, sptr, num);
+ cg14_spit(8, dptr, num);
+ sptr += num << 2;
+ dptr += num << 2;
+ cnt -= num << 2;
}
if (cnt > 0) {
sta(sptr, ASI_SX, SX_LDB(32, cnt - 1, sptr & 7));
sta(dptr, ASI_SX, SX_STB(32, cnt - 1, dptr & 7));
}
- saddr += stride;
- daddr += stride;
+ saddr += skip;
+ daddr += skip;
}
} else {
/* unaligned, have to use byte mode */
@@ -1257,7 +1354,7 @@
sptr = saddr;
dptr = daddr;
cnt = wi;
- while(cnt > 32) {
+ while(cnt > 31) {
sta(sptr, ASI_SX, SX_LDB(32, 31, sptr & 7));
sta(dptr, ASI_SX, SX_STB(32, 31, dptr & 7));
sptr += 32;
@@ -1268,11 +1365,10 @@
sta(sptr, ASI_SX, SX_LDB(32, cnt - 1, sptr & 7));
sta(dptr, ASI_SX, SX_STB(32, cnt - 1, dptr & 7));
}
- saddr += stride;
- daddr += stride;
+ saddr += skip;
+ daddr += skip;
}
}
- cg14_wait_idle(sc);
}
@@ -1342,13 +1438,12 @@
}
}
-#if 0
static void
-r128fb_cursor(void *cookie, int on, int row, int col)
+cg14_cursor(void *cookie, int on, int row, int col)
{
struct rasops_info *ri = cookie;
struct vcons_screen *scr = ri->ri_hw;
- struct r128fb_softc *sc = scr->scr_cookie;
+ struct cgfourteen_softc *sc = scr->scr_cookie;
int x, y, wi, he;
wi = ri->ri_font->fontwidth;
@@ -1358,7 +1453,7 @@
x = ri->ri_ccol * wi + ri->ri_xorigin;
y = ri->ri_crow * he + ri->ri_yorigin;
if (ri->ri_flg & RI_CURSOR) {
- r128fb_bitblt(sc, x, y, x, y, wi, he, R128_ROP3_Dn);
+ cg14_invert(sc, x, y, wi, he);
ri->ri_flg &= ~RI_CURSOR;
}
ri->ri_crow = row;
@@ -1366,7 +1461,7 @@
if (on) {
x = ri->ri_ccol * wi + ri->ri_xorigin;
y = ri->ri_crow * he + ri->ri_yorigin;
- r128fb_bitblt(sc, x, y, x, y, wi, he, R128_ROP3_Dn);
+ cg14_invert(sc, x, y, wi, he);
ri->ri_flg |= RI_CURSOR;
Home |
Main Index |
Thread Index |
Old Index