shithub: riscv

Download patch

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