all repos — mgba @ 54e4d914575be4ad901fa451a91305777c23fdf6

mGBA Game Boy Advance Emulator

GBA Video: Optimize mode 0 rendering
Jeffrey Pfau jeffrey@endrift.com
Tue, 16 Aug 2016 21:05:55 -0700
commit

54e4d914575be4ad901fa451a91305777c23fdf6

parent

63ed9bfe9138691759d3759364cb182ca09c0571

M CHANGESCHANGES

@@ -57,6 +57,7 @@ - GBA Video: Optimize sprite drawing

- GBA BIOS: Use custom ArcTan, not relying on OS - PSP2: Sync files per descriptor - GBA Savedata: Add realistic timing for EEPROM + - GBA Video: Optimize mode 0 rendering 0.4.1: (2016-07-11) Bugfixes:
M src/gba/renderers/software-bg.csrc/gba/renderers/software-bg.c

@@ -45,7 +45,7 @@ continue; \

} \ MOSAIC(COORD) \ if (pixelData) { \ - COMPOSITE_256_ ## OBJWIN (BLEND); \ + COMPOSITE_256_ ## OBJWIN (BLEND, 0); \ } \ }
M src/gba/renderers/software-mode0.csrc/gba/renderers/software-mode0.c

@@ -28,12 +28,12 @@ LOAD_32(tileData, charBase, vram); \

if (!GBA_TEXT_MAP_HFLIP(mapData)) { \ tileData >>= 4 * mod8; \ for (; outX < end; ++outX, ++pixel) { \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \ } \ } else { \ for (outX = end - 1; outX >= renderer->start; --outX) { \ uint32_t* pixel = &renderer->row[outX]; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \ } \ }

@@ -50,7 +50,7 @@ outX = renderer->start; \

pixel = &renderer->row[outX]; \ } \ for (; outX < renderer->end; ++outX, ++pixel) { \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \ } \ } else { \ tileData >>= 4 * (0x8 - mod8); \

@@ -61,7 +61,7 @@ } \

outX = renderer->end - 1; \ pixel = &renderer->row[outX]; \ for (; outX > end; --outX, --pixel) { \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \ } \ /* Needed for consistency checks */ \ if (VIDEO_CHECKS) { \

@@ -128,7 +128,7 @@ } \

mosaicWait = mosaicH; \ } \ --mosaicWait; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \ ++pixel; \ } \ x = 0; \

@@ -147,44 +147,26 @@ } \

LOAD_32(tileData, charBase, vram); \ if (tileData) { \ if (!GBA_TEXT_MAP_HFLIP(mapData)) { \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - ++pixel; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - ++pixel; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - ++pixel; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - ++pixel; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - ++pixel; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - ++pixel; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - ++pixel; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - ++pixel; \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 1); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 2); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 3); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 4); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 5); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 6); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 7); \ } else { \ - pixel += 7; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - --pixel; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - --pixel; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - --pixel; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - --pixel; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - --pixel; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - --pixel; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - --pixel; \ - BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ - pixel += 8; \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 7); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 6); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 5); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 4); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 3); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 2); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 1); \ + BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \ } \ - } else { \ - pixel += 8; \ } \ + pixel += 8; \ } #define DRAW_BACKGROUND_MODE_0_TILE_SUFFIX_256(BLEND, OBJWIN) \

@@ -198,7 +180,7 @@ LOAD_32(tileData, charBase, vram); \

tileData >>= 8 * shift; \ shift = 0; \ for (; outX < end2; ++outX, ++pixel) { \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ } \ } \

@@ -207,7 +189,7 @@ if (LIKELY(charBase < 0x10000)) { \

LOAD_32(tileData, charBase + 4, vram); \ tileData >>= 8 * shift; \ for (; outX < end; ++outX, ++pixel) { \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ } \ } else { \

@@ -218,7 +200,7 @@ if (LIKELY(charBase < 0x10000)) { \

if (end2 > start) { \ LOAD_32(tileData, charBase, vram); \ for (; outX >= end2; --outX, --pixel) { \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ charBase += 4; \ } \

@@ -227,7 +209,7 @@ \

if (LIKELY(charBase < 0x10000)) { \ LOAD_32(tileData, charBase, vram); \ for (; outX >= renderer->start; --outX, --pixel) { \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ } \ outX = end; \

@@ -245,14 +227,14 @@ if (!GBA_TEXT_MAP_HFLIP(mapData)) { \

if (end > 0) { \ LOAD_32(tileData, charBase, vram); \ for (; outX < renderer->end - end; ++outX, ++pixel) { \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ charBase += 4; \ } \ \ LOAD_32(tileData, charBase, vram); \ for (; outX < renderer->end; ++outX, ++pixel) { \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ } else { \ int shift = (8 - mod8) & 0x3; \

@@ -263,7 +245,7 @@ if (end > 0) { \

LOAD_32(tileData, charBase, vram); \ tileData >>= 8 * shift; \ for (; outX >= start + 4; --outX, --pixel) { \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ shift = 0; \ } \

@@ -271,7 +253,7 @@ \

LOAD_32(tileData, charBase + 4, vram); \ tileData >>= 8 * shift; \ for (; outX >= start; --outX, --pixel) { \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ /* Needed for consistency checks */ \ if (VIDEO_CHECKS) { \

@@ -291,53 +273,35 @@ } \

if (!GBA_TEXT_MAP_HFLIP(mapData)) { \ LOAD_32(tileData, charBase, vram); \ if (tileData) { \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ - ++pixel; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ - ++pixel; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ - ++pixel; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ - ++pixel; \ - } else { \ - pixel += 4; \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 1); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 2); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 3); \ } \ + pixel += 4; \ LOAD_32(tileData, charBase + 4, vram); \ if (tileData) { \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ - ++pixel; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ - ++pixel; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ - ++pixel; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ - ++pixel; \ - } else { \ - pixel += 4; \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 1); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 2); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 3); \ } \ + pixel += 4; \ } else { \ LOAD_32(tileData, charBase + 4, vram); \ if (tileData) { \ - pixel += 3; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ - --pixel; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ - --pixel; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ - --pixel; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 3); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 2); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 1); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ pixel += 4; \ LOAD_32(tileData, charBase, vram); \ if (tileData) { \ - pixel += 3; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ - --pixel; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ - --pixel; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ - --pixel; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 3); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 2); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 1); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ pixel += 4; \ } \

@@ -377,7 +341,7 @@ mosaicWait = mosaicH; \

} \ tileData |= tileData << 8; \ --mosaicWait; \ - BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN); \ + BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ ++pixel; \ } \ }
M src/gba/renderers/software-private.hsrc/gba/renderers/software-private.h

@@ -34,7 +34,7 @@ static unsigned _mix(int weightA, unsigned colorA, int weightB, unsigned colorB);

// We stash the priority on the top bits so we can do a one-operator comparison -// The lower the number, the higher the priority, and sprites take precendence over backgrounds +// The lower the number, the higher the priority, and sprites take precedence over backgrounds // We want to do special processing if the color pixel is target 1, however static inline void _compositeBlendObjwin(struct GBAVideoSoftwareRenderer* renderer, uint32_t* pixel, uint32_t color, uint32_t current) {

@@ -83,45 +83,44 @@ }

*pixel = color; } -#define COMPOSITE_16_OBJWIN(BLEND) \ +#define COMPOSITE_16_OBJWIN(BLEND, IDX) \ if (objwinForceEnable || (!(current & FLAG_OBJWIN)) == objwinOnly) { \ unsigned color = (current & FLAG_OBJWIN) ? objwinPalette[paletteData | pixelData] : palette[pixelData]; \ unsigned mergedFlags = flags; \ if (current & FLAG_OBJWIN) { \ mergedFlags = objwinFlags; \ } \ - _composite ## BLEND ## Objwin(renderer, pixel, color | mergedFlags, current); \ + _composite ## BLEND ## Objwin(renderer, &pixel[IDX], color | mergedFlags, current); \ } -#define COMPOSITE_16_NO_OBJWIN(BLEND) \ - _composite ## BLEND ## NoObjwin(renderer, pixel, palette[pixelData] | flags, current); +#define COMPOSITE_16_NO_OBJWIN(BLEND, IDX) \ + _composite ## BLEND ## NoObjwin(renderer, &pixel[IDX], palette[pixelData] | flags, current); -#define COMPOSITE_256_OBJWIN(BLEND) \ +#define COMPOSITE_256_OBJWIN(BLEND, IDX) \ if (objwinForceEnable || (!(current & FLAG_OBJWIN)) == objwinOnly) { \ unsigned color = (current & FLAG_OBJWIN) ? objwinPalette[pixelData] : palette[pixelData]; \ unsigned mergedFlags = flags; \ if (current & FLAG_OBJWIN) { \ mergedFlags = objwinFlags; \ } \ - _composite ## BLEND ## Objwin(renderer, pixel, color | mergedFlags, current); \ + _composite ## BLEND ## Objwin(renderer, &pixel[IDX], color | mergedFlags, current); \ } -#define COMPOSITE_256_NO_OBJWIN(BLEND) \ - COMPOSITE_16_NO_OBJWIN(BLEND) +#define COMPOSITE_256_NO_OBJWIN COMPOSITE_16_NO_OBJWIN -#define BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN) \ +#define BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, IDX) \ pixelData = tileData & 0xF; \ - current = *pixel; \ + current = pixel[IDX]; \ if (pixelData && IS_WRITABLE(current)) { \ - COMPOSITE_16_ ## OBJWIN (BLEND); \ + COMPOSITE_16_ ## OBJWIN (BLEND, IDX); \ } \ tileData >>= 4; -#define BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN) \ +#define BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, IDX) \ pixelData = tileData & 0xFF; \ - current = *pixel; \ + current = pixel[IDX]; \ if (pixelData && IS_WRITABLE(current)) { \ - COMPOSITE_256_ ## OBJWIN (BLEND); \ + COMPOSITE_256_ ## OBJWIN (BLEND, IDX); \ } \ tileData >>= 8;