From: notaz Date: Tue, 20 Dec 2011 00:38:53 +0000 (+0200) Subject: gpu_unai: add 4bpp asm sprite blitter X-Git-Tag: r12~16 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=commitdiff_plain;h=b3db94096d7e5b4f60d610a441e370d639b3fd06;ds=inline gpu_unai: add 4bpp asm sprite blitter --- diff --git a/plugins/gpu_neon/Makefile b/plugins/gpu_neon/Makefile index f2277522..66a2bd5c 100644 --- a/plugins/gpu_neon/Makefile +++ b/plugins/gpu_neon/Makefile @@ -6,6 +6,9 @@ ARCH = $(shell $(CC) -v 2>&1 | grep -i 'target:' | awk '{print $$2}' | awk -F '- CFLAGS += -ggdb -Wall -fPIC -O2 CFLAGS += -fno-strict-aliasing +ifdef MAEMO +CFLAGS += -DMAEMO +endif SRC += gpu.c ifeq "$(ARCH)" "arm" @@ -38,7 +41,7 @@ gpu_neon.$(EXT): SRC += psx_gpu_if.c gpu_neon.$(EXT): CFLAGS += -fno-strict-aliasing gpu_peops.$(EXT): SRC += peops_if.c gpu_peops.$(EXT): CFLAGS += -fno-strict-aliasing -gpu_unai.$(EXT): SRC += unai_if.cpp +gpu_unai.$(EXT): SRC += unai_if.cpp ../gpu_unai/gpu_arm.s gpu_unai.$(EXT): CC_ = $(CXX) all: $(TARGETS) diff --git a/plugins/gpu_unai/Makefile b/plugins/gpu_unai/Makefile index 531c9fb6..e4b6e6b9 100644 --- a/plugins/gpu_unai/Makefile +++ b/plugins/gpu_unai/Makefile @@ -16,7 +16,7 @@ CFLAGS += -mcpu=arm926ej-s -mtune=arm926ej-s SRC += ../../frontend/cspace.c endif -SRC += gpu.cpp +SRC += gpu.cpp gpu_arm.s TARGET = gpuPCSX4ALL.so LDFLAGS += -shared -Wl,-soname,$(TARGET) diff --git a/plugins/gpu_unai/gpu_arm.h b/plugins/gpu_unai/gpu_arm.h new file mode 100644 index 00000000..a0b22487 --- /dev/null +++ b/plugins/gpu_unai/gpu_arm.h @@ -0,0 +1,9 @@ +#ifdef __cplusplus +extern "C" { +#endif + +void draw_spr16_full(u16 *d, void *s, u16 *pal, int lines); + +#ifdef __cplusplus +} +#endif diff --git a/plugins/gpu_unai/gpu_arm.s b/plugins/gpu_unai/gpu_arm.s new file mode 100644 index 00000000..a2fa1741 --- /dev/null +++ b/plugins/gpu_unai/gpu_arm.s @@ -0,0 +1,55 @@ +/* + * (C) Gražvydas "notaz" Ignotas, 2011 + * + * This work is licensed under the terms of GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + + +.text +.align 2 + +@ in: r0=dst, r2=pal, r12=0x1e +@ trashes r6-r8,lr,flags +.macro do_4_pixels rs ibase obase +.if \ibase - 1 < 0 + and r6, r12, \rs, lsl #1 +.else + and r6, r12, \rs, lsr #\ibase-1 +.endif + and r7, r12, \rs, lsr #\ibase+3 + and r8, r12, \rs, lsr #\ibase+7 + and lr, r12, \rs, lsr #\ibase+11 + ldrh r6, [r2, r6] + ldrh r7, [r2, r7] + ldrh r8, [r2, r8] + ldrh lr, [r2, lr] + tst r6, r6 + strneh r6, [r0, #\obase+0] + tst r7, r7 + strneh r7, [r0, #\obase+2] + tst r8, r8 + strneh r8, [r0, #\obase+4] + tst lr, lr + strneh lr, [r0, #\obase+6] +.endm + +.global draw_spr16_full @ (u16 *d, void *s, u16 *pal, int lines) +draw_spr16_full: + stmfd sp!, {r4-r8,lr} + mov r12, #0x1e @ empty pixel + +0: + ldmia r1, {r4,r5} + do_4_pixels r4, 0, 0 + do_4_pixels r4, 16, 8 + do_4_pixels r5, 0, 16 + do_4_pixels r5, 16, 24 + subs r3, #1 + add r0, #2048 + add r1, #2048 + bgt 0b + + ldmfd sp!, {r4-r8,pc} + +@ vim:filetype=armasm diff --git a/plugins/gpu_unai/gpu_command.h b/plugins/gpu_unai/gpu_command.h index d380daec..049b1462 100644 --- a/plugins/gpu_unai/gpu_command.h +++ b/plugins/gpu_unai/gpu_command.h @@ -352,6 +352,16 @@ void gpuSendPacketFunction(const int PRIM) break; case 0x7C: case 0x7D: +#ifdef __arm__ + if ((GPU_GP1 & 0x180) == 0 && (Masking | PixelMSB) == 0) + { + gpuSetCLUT (PacketBuffer.U4[2] >> 16); + gpuSetTexture (GPU_GP1); + gpuDrawS16(); + break; + } + // fallthrough +#endif case 0x7E: case 0x7F: if (!isSkip) diff --git a/plugins/gpu_unai/gpu_raster_sprite.h b/plugins/gpu_unai/gpu_raster_sprite.h index 041fcbdc..5075227e 100644 --- a/plugins/gpu_unai/gpu_raster_sprite.h +++ b/plugins/gpu_unai/gpu_raster_sprite.h @@ -84,6 +84,47 @@ void gpuDrawS(const PS gpuSpriteSpanDriver) } } +#ifdef __arm__ +#include "gpu_arm.h" + +void gpuDrawS16(void) +{ + s32 x0, y0; + s32 u0, v0; + s32 xmin, xmax; + s32 ymin, ymax; + u32 h = 16; + + x0 = GPU_EXPANDSIGN_SPRT(PacketBuffer.S2[2]) + DrawingOffset[0]; + y0 = GPU_EXPANDSIGN_SPRT(PacketBuffer.S2[3]) + DrawingOffset[1]; + + xmin = DrawingArea[0]; xmax = DrawingArea[2]; + ymin = DrawingArea[1]; ymax = DrawingArea[3]; + u0 = PacketBuffer.U1[8]; + v0 = PacketBuffer.U1[9]; + + if (x0 > xmax - 16 || x0 < xmin || + ((u0 | v0) & 15) || !(TextureWindow[2] & TextureWindow[3] & 8)) { + // send corner cases to general handler + PacketBuffer.U4[3] = 0x00100010; + gpuDrawS(gpuSpriteSpanFn<0x20>); + return; + } + + if (y0 >= ymax || y0 <= ymin - 16) + return; + if (y0 < ymin) { + h -= ymin - y0; + v0 += ymin - y0; + y0 = ymin; + } + else if (ymax - y0 < 16) + h = ymax - y0; + + draw_spr16_full(&GPU_FrameBuffer[FRAME_OFFSET(x0, y0)], &TBA[FRAME_OFFSET(u0/4, v0)], CBA, h); +} +#endif // __arm__ + /////////////////////////////////////////////////////////////////////////////// void gpuDrawT(const PT gpuTileSpanDriver) {