GBA: Tile cache improvements
Jeffrey Pfau jeffrey@endrift.com
Sat, 23 Jul 2016 19:34:43 -0700
3 files changed,
66 insertions(+),
32 deletions(-)
M
src/gba/renderers/tile-cache.c
→
src/gba/renderers/tile-cache.c
@@ -13,14 +13,28 @@
void GBAVideoTileCacheInit(struct GBAVideoTileCache* cache) { // TODO: Reconfigurable cache for space savings cache->cache = anonymousMemoryMap(CACHE_SIZE); + cache->config = GBAVideoTileCacheConfigurationFillShouldStore(0); memset(cache->status, 0, sizeof(cache->status)); memset(cache->globalPaletteVersion, 0, sizeof(cache->globalPaletteVersion)); memset(cache->globalPalette256Version, 0, sizeof(cache->globalPalette256Version)); } +void GBAVideoTileCacheConfigure(struct GBAVideoTileCache* cache, GBAVideoTileCacheConfiguration config) { + if (GBAVideoTileCacheConfigurationIsShouldStore(cache->config) || !GBAVideoTileCacheConfigurationIsShouldStore(config)) { + mappedMemoryFree(cache->cache, CACHE_SIZE); + cache->cache = NULL; + } else if (!GBAVideoTileCacheConfigurationIsShouldStore(cache->config) || GBAVideoTileCacheConfigurationIsShouldStore(config)) { + cache->cache = anonymousMemoryMap(CACHE_SIZE); + } + cache->config = config; +} + + void GBAVideoTileCacheDeinit(struct GBAVideoTileCache* cache) { - mappedMemoryFree(cache->cache, CACHE_SIZE); - cache->cache = NULL; + if (GBAVideoTileCacheConfigurationIsShouldStore(cache->config)) { + mappedMemoryFree(cache->cache, CACHE_SIZE); + cache->cache = NULL; + } } void GBAVideoTileCacheAssociate(struct GBAVideoTileCache* cache, struct GBAVideo* video) {@@ -30,7 +44,10 @@ video->renderer->cache = cache;
} void GBAVideoTileCacheWriteVRAM(struct GBAVideoTileCache* cache, uint32_t address) { - cache->status[address >> 5].vramClean = 0; + size_t i; + for (i = 0; i > 16; ++i) { + cache->status[address >> 5][i].vramClean = 0; + } } void GBAVideoTileCacheWritePalette(struct GBAVideoTileCache* cache, uint32_t address) {@@ -38,8 +55,7 @@ ++cache->globalPaletteVersion[address >> 5];
++cache->globalPalette256Version[address >> 9]; } -static void _regenerateTile16(struct GBAVideoTileCache* cache, unsigned tileId, unsigned paletteId) { - uint16_t* tile = &cache->cache[tileId << 6]; +static void _regenerateTile16(struct GBAVideoTileCache* cache, uint16_t* tile, unsigned tileId, unsigned paletteId) { uint32_t* start = (uint32_t*) &cache->vram[tileId << 4]; paletteId <<= 4; uint16_t* palette = &cache->palette[paletteId];@@ -68,11 +84,10 @@ tile += 8;
} } -static void _regenerateTile256(struct GBAVideoTileCache* cache, unsigned tileId, unsigned paletteId) { - uint16_t* tile = &cache->cache[tileId << 6]; +static void _regenerateTile256(struct GBAVideoTileCache* cache, uint16_t* tile, unsigned tileId, unsigned paletteId) { uint32_t* start = (uint32_t*) &cache->vram[tileId << 5]; paletteId <<= 8; - uint16_t* palette = &cache->palette[paletteId]; + uint16_t* palette = &cache->palette[paletteId * 16]; int i; for (i = 0; i < 8; ++i) { uint32_t line = *start;@@ -101,49 +116,61 @@ tile += 8;
} } +static inline uint16_t* _tileLookup(struct GBAVideoTileCache* cache, unsigned tileId, unsigned paletteId) { + if (GBAVideoTileCacheConfigurationIsShouldStore(cache->config)) { + return &cache->cache[((tileId << 4) + (paletteId & 0xF)) << 6]; + } else { + return cache->temporaryTile; + } +} + const uint16_t* GBAVideoTileCacheGetTile16(struct GBAVideoTileCache* cache, unsigned tileId, unsigned paletteId) { - struct GBAVideoTileCacheEntry* status = &cache->status[tileId]; - if (!status->vramClean || status->palette256 || status->paletteVersion[paletteId & 0xF] != cache->globalPaletteVersion[paletteId]) { - _regenerateTile16(cache, tileId, paletteId); - status->paletteVersion[paletteId & 0xF] = cache->globalPaletteVersion[paletteId]; + struct GBAVideoTileCacheEntry* status = &cache->status[tileId][paletteId & 0xF]; + uint16_t* tile = _tileLookup(cache, tileId, paletteId); + if (!GBAVideoTileCacheConfigurationIsShouldStore(cache->config) || !status->vramClean || status->palette256 || status->paletteVersion != cache->globalPaletteVersion[paletteId]) { + _regenerateTile16(cache, tile, tileId, paletteId); + status->paletteVersion = cache->globalPaletteVersion[paletteId]; status->palette256 = 0; status->vramClean = 1; } - return &cache->cache[tileId << 6]; + return tile; } const uint16_t* GBAVideoTileCacheGetTile16IfDirty(struct GBAVideoTileCache* cache, unsigned tileId, unsigned paletteId) { - struct GBAVideoTileCacheEntry* status = &cache->status[tileId]; - if (!status->vramClean || status->palette256 || status->paletteVersion[paletteId & 0xF] != cache->globalPaletteVersion[paletteId]) { - _regenerateTile16(cache, tileId, paletteId); - status->paletteVersion[paletteId & 0xF] = cache->globalPaletteVersion[paletteId]; + struct GBAVideoTileCacheEntry* status = &cache->status[tileId][paletteId & 0xF]; + if (!status->vramClean || status->palette256 || status->paletteVersion != cache->globalPaletteVersion[paletteId]) { + uint16_t* tile = _tileLookup(cache, tileId, paletteId); + _regenerateTile16(cache, tile, tileId, paletteId); + status->paletteVersion = cache->globalPaletteVersion[paletteId]; status->palette256 = 0; status->vramClean = 1; - return &cache->cache[tileId << 6]; + return tile; } return NULL; } const uint16_t* GBAVideoTileCacheGetTile256(struct GBAVideoTileCache* cache, unsigned tileId, unsigned paletteId) { - struct GBAVideoTileCacheEntry* status = &cache->status[tileId]; - if (!status->vramClean || !status->palette256 || status->paletteVersion[0] != cache->globalPalette256Version[paletteId]) { - _regenerateTile256(cache, tileId, paletteId); - status->paletteVersion[0] = cache->globalPalette256Version[paletteId]; + struct GBAVideoTileCacheEntry* status = &cache->status[tileId][paletteId]; + uint16_t* tile = _tileLookup(cache, tileId, paletteId); + if (!GBAVideoTileCacheConfigurationIsShouldStore(cache->config) || !status->vramClean || !status->palette256 || status->paletteVersion != cache->globalPalette256Version[paletteId]) { + _regenerateTile256(cache, tile, tileId, paletteId); + status->paletteVersion = cache->globalPalette256Version[paletteId]; status->palette256 = 1; status->vramClean = 1; } - return &cache->cache[tileId << 6]; + return tile; } const uint16_t* GBAVideoTileCacheGetTile256IfDirty(struct GBAVideoTileCache* cache, unsigned tileId, unsigned paletteId) { - struct GBAVideoTileCacheEntry* status = &cache->status[tileId]; - if (!status->vramClean || !status->palette256 || status->paletteVersion[0] != cache->globalPalette256Version[paletteId]) { - _regenerateTile256(cache, tileId, paletteId); - status->paletteVersion[0] = cache->globalPalette256Version[paletteId]; + struct GBAVideoTileCacheEntry* status = &cache->status[tileId][paletteId]; + if (!status->vramClean || !status->palette256 || status->paletteVersion != cache->globalPalette256Version[paletteId]) { + uint16_t* tile = _tileLookup(cache, tileId, paletteId); + _regenerateTile256(cache, tile, tileId, paletteId); + status->paletteVersion = cache->globalPalette256Version[paletteId]; status->palette256 = 1; status->vramClean = 1; - return &cache->cache[tileId << 6]; + return tile; } return NULL; }
M
src/gba/renderers/tile-cache.h
→
src/gba/renderers/tile-cache.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015 Jeffrey Pfau +/* Copyright (c) 2013-2016 Jeffrey Pfau * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this@@ -10,22 +10,29 @@ #include "util/common.h"
struct GBAVideo; +DECL_BITFIELD(GBAVideoTileCacheConfiguration, uint32_t); +DECL_BIT(GBAVideoTileCacheConfiguration, ShouldStore, 0); + struct GBAVideoTileCache { uint16_t* cache; struct GBAVideoTileCacheEntry { - uint32_t paletteVersion[16]; + uint32_t paletteVersion; uint8_t vramClean; uint8_t palette256; - } status[1024 * 3]; + } status[1024 * 3][16]; uint32_t globalPaletteVersion[32]; uint32_t globalPalette256Version[2]; uint16_t* vram; uint16_t* palette; + uint16_t temporaryTile[64]; + + GBAVideoTileCacheConfiguration config; }; void GBAVideoTileCacheInit(struct GBAVideoTileCache* cache); void GBAVideoTileCacheDeinit(struct GBAVideoTileCache* cache); +void GBAVideoTileCacheConfigure(struct GBAVideoTileCache* cache, GBAVideoTileCacheConfiguration config); void GBAVideoTileCacheAssociate(struct GBAVideoTileCache* cache, struct GBAVideo* video); void GBAVideoTileCacheWriteVRAM(struct GBAVideoTileCache* cache, uint32_t address); void GBAVideoTileCacheWritePalette(struct GBAVideoTileCache* cache, uint32_t address);
M
src/platform/qt/TileView.cpp
→
src/platform/qt/TileView.cpp
@@ -123,7 +123,7 @@ }
void TileView::updatePalette(int palette) { m_paletteId = palette; - updateTiles(); + updateTiles(true); } void TileView::resizeEvent(QResizeEvent*) {