ref: a0a3bf21bc9fce5a0b2bdb435524ed1a7b334d0d
parent: a523ce1282d2fff6d4d052a71e3f32baa0e18a67
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Fri Sep 15 14:04:25 EDT 2023
doom: faster palette→rgb conversion for arm64; fix convproc channel handling
--- a/sys/src/games/doom/i_video.c
+++ b/sys/src/games/doom/i_video.c
@@ -20,7 +20,7 @@
static void kbdproc(void *);
static void mouseproc(void *);
-static uchar cmap[3*256];
+static u32int cmap[256];
static int kbdpid = -1;
static int mousepid = -1;
@@ -70,9 +70,11 @@
{
uchar *c;
- c = cmap;
- while(c < cmap+3*256)
- *c++ = gammatable[usegamma][*palette++];
+ for(c = (uchar*)cmap; c < (uchar*)cmap+sizeof(cmap); c += 4){
+ c[2] = gammatable[usegamma][*palette++];
+ c[1] = gammatable[usegamma][*palette++];
+ c[0] = gammatable[usegamma][*palette++];
+ }
}
void I_UpdateNoBlit(void)
@@ -80,6 +82,8 @@
// DELETEME?
}
+void pal2xrgb(u32int *pal, u8int *s, u32int *d, int n, int scale);
+
static int screenconvi;
static uchar screenconv[2][SCREENWIDTH*SCREENHEIGHT];
@@ -86,11 +90,11 @@
static void
convproc(void *p)
{
- static uchar buf[SCREENWIDTH*3*12];
- int i, y, scale, oldscale;
+ static u32int buf[SCREENWIDTH*12];
+ int y, scale, oldscale;
Image *rowimg;
Rectangle r;
- uchar *s, *e, *d, *m;
+ uchar *s;
oldscale = 0;
rowimg = nil;
@@ -111,7 +115,7 @@
if(scale != oldscale){
if(rowimg != nil)
freeimage(rowimg);
- rowimg = allocimage(display, Rect(0, 0, scale*SCREENWIDTH, 1), RGB24, scale > 1, DNofill);
+ rowimg = allocimage(display, Rect(0, 0, scale*SCREENWIDTH, 1), XRGB32, scale > 1, DNofill);
if(rowimg == nil)
sysfatal("allocimage: %r");
oldscale = scale;
@@ -118,26 +122,18 @@
}
for(y = 0; y < SCREENHEIGHT; y++){
- d = buf;
- e = s + SCREENWIDTH;
- for(; s < e; s++){
- m = &cmap[*s * 3];
- for(i = 0; i < scale; i++, d += 3){
- d[0] = m[2];
- d[1] = m[1];
- d[2] = m[0];
- }
- }
- loadimage(rowimg, rowimg->r, buf, d - buf);
+ pal2xrgb(cmap, s, buf, SCREENWIDTH, scale);
+ s += SCREENWIDTH;
+ loadimage(rowimg, rowimg->r, (uchar*)buf, 4*scale*SCREENWIDTH);
draw(screen, r, rowimg, nil, ZP);
r.min.y += scale;
r.max.y += scale;
}
-
flushimage(display, 1);
}
if(rowimg != nil)
freeimage(rowimg);
+ chanfree(p);
threadexits(nil);
}
@@ -145,8 +141,7 @@
{
if(resized){
if(conv != nil){
- sendp(conv, nil);
- chanfree(conv);
+ chanclose(conv);
conv = nil;
}
resized = 0;
--- a/sys/src/games/doom/mkfile
+++ b/sys/src/games/doom/mkfile
@@ -4,6 +4,7 @@
TARG=doom
OFILES=\
+ pal`{test -f pal_$objtype.s && echo -n _$objtype}.$O\
doomdef.$O\
doomstat.$O\
dstrings.$O\
--- /dev/null
+++ b/sys/src/games/doom/pal.c
@@ -1,0 +1,15 @@
+#include <u.h>
+#include <libc.h>
+
+void
+pal2xrgb(u32int *pal, u8int *s, u32int *d, int n, int scale)
+{
+ int i;
+ u32int c;
+
+ while(n-- > 0){
+ c = pal[*s++];
+ for(i = 0; i < scale; i++)
+ *d++ = c;
+ }
+}
--- /dev/null
+++ b/sys/src/games/doom/pal_arm64.s
@@ -1,0 +1,46 @@
+TEXT pal2xrgb+0(SB), 1, $-4
+ MOV s+8(FP), R1
+ MOV d+16(FP), R2
+ MOVWU n+24(FP), R3
+ MOVWU scale+32(FP), R4
+ MOVWU $4, R5
+ MULW R5, R4, R6 // 4*scale
+ MULW R5, R6, R5
+ SUBW R6, R5, R5 // 3*4*scale
+ ADD R3, R1, R7 // s+n
+
+ SUB R5, R2, R8
+ ADD R6, R8, R9
+ ADD R6, R9, R10
+ ADD R6, R10, R11
+
+_l:
+ CMP R1, R7
+ BEQ _end
+
+ MOVWU (R1)4!, R3
+ UBFXW $8, $8, R3, R4
+ UBFXW $16, $8, R3, R12
+ UBFXW $24, $8, R3, R13
+ MOVBU R3, R3
+ MOVWU (R0)[R3], R3
+ ADD R5, R8
+ ADD R5, R10
+ MOVWU (R0)[R4], R4
+ ADD R5, R9
+ ADD R5, R11
+ MOVWU (R0)[R12], R12
+ ADD R6, R8, R18
+ MOVWU (R0)[R13], R13
+
+_s1:
+ CMP R8, R18
+ BEQ _l
+ MOVWU R3, (R8)4!
+ MOVWU R4, (R9)4!
+ MOVWU R12, (R10)4!
+ MOVWU R13, (R11)4!
+ B _s1
+
+_end:
+ RETURN