Support loading TLUT from two different memory locations

This commit is contained in:
Emil Lenngren 2022-04-02 01:19:02 +02:00
parent f709ffa99a
commit adf3b064ca
7 changed files with 56 additions and 12 deletions

View File

@ -4223,6 +4223,17 @@ _DW({ \
gDPPipeSync(pkt); \
})
#define gDPLoadTLUT_pal128(pkt, pal, dram) \
_DW({ \
gDPSetTextureImage(pkt, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram); \
gDPTileSync(pkt); \
gDPSetTile(pkt, 0, 0, 0, 256 + ((pal)&1)*128, \
G_TX_LOADTILE, 0 , 0, 0, 0, 0, 0, 0); \
gDPLoadSync(pkt); \
gDPLoadTLUTCmd(pkt, G_TX_LOADTILE, 127); \
gDPPipeSync(pkt); \
})
#else /* **** WORKAROUND hardware 1 load_tlut bug ****** */
#define gDPLoadTLUT_pal256(pkt, dram) \

View File

@ -125,7 +125,7 @@ static struct RSP {
} rsp;
static struct RDP {
const uint8_t *palette;
const uint8_t *palettes[2];
struct {
const uint8_t *addr;
uint8_t siz;
@ -145,6 +145,7 @@ static struct RDP {
uint8_t cms, cmt;
uint8_t shifts, shiftt;
uint16_t uls, ult, lrs, lrt; // U10.2
uint16_t tmem; // 0-511, in 64-bit word units
uint32_t line_size_bytes;
uint8_t palette;
uint8_t tmem_index; // 0 or 1 for offset 0 kB or offset 2 kB, respectively
@ -490,8 +491,22 @@ void gfx_texture_cache_clear()
gfx_texture_cache.lru.clear();
}
static bool gfx_texture_cache_lookup(int i, TextureCacheNode **n, const uint8_t *orig_addr, const uint8_t *palette_addr, uint32_t fmt, uint32_t siz, uint32_t palette_index) {
TextureCacheKey key = { orig_addr, palette_addr, fmt, siz, palette_index };
static bool gfx_texture_cache_lookup(int i, int tile) {
uint8_t fmt = rdp.texture_tile[tile].fmt;
uint8_t siz = rdp.texture_tile[tile].siz;
uint32_t tmem_index = rdp.texture_tile[tile].tmem_index;
TextureCacheNode** n = &rendering_state.textures[i];
const uint8_t* orig_addr = rdp.loaded_texture[tmem_index].addr;
uint8_t palette_index = rdp.texture_tile[tile].palette;
TextureCacheKey key;
if (fmt == G_IM_FMT_CI) {
key = { orig_addr, { rdp.palettes[0], rdp.palettes[1] }, fmt, siz, palette_index };
} else {
key = { orig_addr, { }, fmt, siz, palette_index };
}
auto it = gfx_texture_cache.map.find(key);
if (it != gfx_texture_cache.map.end()) {
@ -735,7 +750,8 @@ static void import_texture_ci4(int tile) {
uint32_t size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].size_bytes;
uint32_t full_image_line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].full_image_line_size_bytes;
uint32_t line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].line_size_bytes;
const uint8_t *palette = rdp.palette + rdp.texture_tile[tile].palette * 16 * 2; // 16 pixel entries, 16 bits each
uint32_t pal_idx = rdp.texture_tile[tile].palette; // 0-15
const uint8_t *palette = rdp.palettes[pal_idx / 8] + (pal_idx % 8) * 16 * 2; // 16 pixel entries, 16 bits each
SUPPORT_CHECK(full_image_line_size_bytes == line_size_bytes);
for (uint32_t i = 0; i < size_bytes * 2; i++) {
@ -770,7 +786,7 @@ static void import_texture_ci8(int tile) {
{
for (uint32_t k = 0; k < line_size_bytes; i++, k++, j++) {
uint8_t idx = addr[j];
uint16_t col16 = (rdp.palette[idx * 2] << 8) | rdp.palette[idx * 2 + 1]; // Big endian load
uint16_t col16 = (rdp.palettes[idx / 128][(idx % 128) * 2] << 8) | rdp.palettes[idx / 128][(idx % 128) * 2 + 1]; // Big endian load
uint8_t a = col16 & 1;
uint8_t r = col16 >> 11;
uint8_t g = (col16 >> 6) & 0x1f;
@ -815,7 +831,7 @@ static void import_texture(int i, int tile) {
// if (ModInternal::callBindHook(0))
// return;
if (gfx_texture_cache_lookup(i, &rendering_state.textures[i], rdp.loaded_texture[tmem_index].addr, fmt == G_IM_FMT_CI ? rdp.palette : nullptr, fmt, siz, rdp.texture_tile[tile].palette))
if (gfx_texture_cache_lookup(i, tile))
{
return;
}
@ -1638,6 +1654,7 @@ static void gfx_dp_set_tile(uint8_t fmt, uint32_t siz, uint32_t line, uint32_t t
int bp = 0;
}
rdp.texture_tile[tile].tmem = tmem;
//rdp.texture_tile[tile].tmem_index = tmem / 256; // tmem is the 64-bit word offset, so 256 words means 2 kB
rdp.texture_tile[tile].tmem_index = tmem != 0; // assume one texture is loaded at address 0 and another texture at any other address
rdp.textures_changed[0] = true;
@ -1654,10 +1671,19 @@ static void gfx_dp_set_tile_size(uint8_t tile, uint16_t uls, uint16_t ult, uint1
}
static void gfx_dp_load_tlut(uint8_t tile, uint32_t high_index) {
//SUPPORT_CHECK(tile == G_TX_LOADTILE);
//SUPPORT_CHECK(rdp.texture_to_load.siz == G_IM_SIZ_16b);
SUPPORT_CHECK(tile == G_TX_LOADTILE);
SUPPORT_CHECK(rdp.texture_to_load.siz == G_IM_SIZ_16b);
rdp.palette = rdp.texture_to_load.addr;
SUPPORT_CHECK((rdp.texture_tile[tile].tmem == 256 && (high_index <= 127 || high_index == 255)) || (rdp.texture_tile[tile].tmem == 384 && high_index == 127));
if (rdp.texture_tile[tile].tmem == 256) {
rdp.palettes[0] = rdp.texture_to_load.addr;
if (high_index == 255) {
rdp.palettes[1] = rdp.texture_to_load.addr + 2 * 128;
}
} else {
rdp.palettes[1] = rdp.texture_to_load.addr;
}
}
static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t lrs, uint32_t dxt) {

View File

@ -17,7 +17,7 @@ struct GfxDimensions
struct TextureCacheKey {
const uint8_t* texture_addr;
const uint8_t* palette_addr;
const uint8_t* palette_addrs[2];
uint8_t fmt, siz;
uint8_t palette_index;

View File

@ -80,7 +80,7 @@ namespace Ship {
if (!this->TextureCache.contains(path)) this->TextureCache[path].resize(10);
TextureCacheKey key = { orig_addr, nullptr, static_cast<uint8_t>(fmt), static_cast<uint8_t>(siz), static_cast<uint8_t>(palette) };
TextureCacheKey key = { orig_addr, { }, static_cast<uint8_t>(fmt), static_cast<uint8_t>(siz), static_cast<uint8_t>(palette) };
TextureCacheValue value = { api->new_texture(), 0, 0, false };
const auto entry = new TextureCacheNode(key, value);
api->select_texture(tile, entry->second.texture_id);

View File

@ -340,6 +340,7 @@ typedef struct {
s16 skyboxId;
void* textures[2][6];
void* palettes[6];
u16 palette_size;
Gfx (*dListBuf)[150];
Gfx* unk_138;
Vtx* roomVtx;

View File

@ -457,6 +457,7 @@ void LoadSkyboxTexAtOffset(SkyboxContext* skyboxCtx, int segmentIndex, int image
void LoadSkyboxPalette(SkyboxContext* skyboxCtx, int paletteIndex, char* palTex, int width,
int height) {
skyboxCtx->palettes[paletteIndex] = palTex;
skyboxCtx->palette_size = width * height;
}
static const char* sSBVRFine0Tex[] =

View File

@ -38,7 +38,12 @@ void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyb
gDPSetColorDither(POLY_OPA_DISP++, G_CD_MAGICSQ);
gDPSetTextureFilter(POLY_OPA_DISP++, G_TF_BILERP);
gDPLoadTLUT_pal256(POLY_OPA_DISP++, skyboxCtx->palettes[0]);
if (skyboxCtx->palette_size == 256) {
gDPLoadTLUT_pal256(POLY_OPA_DISP++, skyboxCtx->palettes[0]);
} else {
gDPLoadTLUT_pal128(POLY_OPA_DISP++, 0, skyboxCtx->palettes[0]);
gDPLoadTLUT_pal128(POLY_OPA_DISP++, 1, skyboxCtx->palettes[1]);
}
gDPSetTextureLUT(POLY_OPA_DISP++, G_TT_RGBA16);
gDPSetTextureConvert(POLY_OPA_DISP++, G_TC_FILT);