mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-22 08:08:53 -05:00
Tweak: Improve pause menu dungeon map performance (#3773)
* add map palettes per pulse to leverage shader caching * use unregister blended with kaleido maps * use Gfx_TextureCacheDelete for KD lava * bump lus * add miss tex clears for KD
This commit is contained in:
parent
db02870a05
commit
1da1b1a2bb
@ -1 +1 @@
|
||||
Subproject commit b4abd7c366b1fb38b2cd80ffb91e129035bee0ea
|
||||
Subproject commit 96c8a8929c18c1bffd7d92a35a589f74cf16fc59
|
@ -744,7 +744,6 @@ typedef struct {
|
||||
/* 0x0134 */ char** doActionSegment;
|
||||
/* 0x0138 */ u8* iconItemSegment;
|
||||
/* 0x013C */ char** mapSegment;
|
||||
char** mapSegmentName;
|
||||
/* 0x0140 */ u8 mapPalette[32];
|
||||
/* 0x0160 */ DmaRequest dmaRequest_160;
|
||||
/* 0x0180 */ DmaRequest dmaRequest_180;
|
||||
@ -815,6 +814,10 @@ typedef struct {
|
||||
/* 0x026C */ u8 dinsNayrus; // "m_magic"; din's fire and nayru's love
|
||||
/* 0x026D */ u8 all; // "another"; enables all item restrictions
|
||||
} restrictions;
|
||||
// #region SOH [General]
|
||||
/* */ char* mapSegmentName[2]; // Tracks the map segment texture by OTR sig name
|
||||
/* */ u8 mapPalettesPulse[40][32]; // Used to have unique pointers per map pulse color for the shader backend. 40 for map pulse timer x2
|
||||
// #endregion
|
||||
} InterfaceContext; // size = 0x270
|
||||
|
||||
typedef struct {
|
||||
|
@ -2598,6 +2598,24 @@ extern "C" void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* repla
|
||||
gfx_register_blended_texture(name, mask, replacement);
|
||||
}
|
||||
|
||||
extern "C" void Gfx_UnregisterBlendedTexture(const char* name) {
|
||||
gfx_unregister_blended_texture(name);
|
||||
}
|
||||
|
||||
extern "C" void Gfx_TextureCacheDelete(const uint8_t* texAddr) {
|
||||
char* imgName = (char*)texAddr;
|
||||
|
||||
if (texAddr == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ResourceMgr_OTRSigCheck(imgName)) {
|
||||
texAddr = (const uint8_t*)GetResourceDataByNameHandlingMQ(imgName);
|
||||
}
|
||||
|
||||
gfx_texture_cache_delete(texAddr);
|
||||
}
|
||||
|
||||
void SoH_ProcessDroppedFiles(std::string filePath) {
|
||||
try {
|
||||
std::ifstream configStream(filePath);
|
||||
|
@ -173,6 +173,8 @@ void Entrance_InitEntranceTrackingData(void);
|
||||
void EntranceTracker_SetCurrentGrottoID(s16 entranceIndex);
|
||||
void EntranceTracker_SetLastEntranceOverride(s16 entranceIndex);
|
||||
void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* replacement);
|
||||
void Gfx_UnregisterBlendedTexture(const char* name);
|
||||
void Gfx_TextureCacheDelete(const uint8_t* addr);
|
||||
void SaveManager_ThreadPoolWait();
|
||||
void CheckTracker_OnMessageClose();
|
||||
|
||||
|
@ -524,7 +524,6 @@ void Map_Init(PlayState* play) {
|
||||
interfaceCtx->unk_25A = -1;
|
||||
|
||||
interfaceCtx->mapSegment = GAMESTATE_ALLOC_MC(&play->state, 2 * sizeof(char*));
|
||||
interfaceCtx->mapSegmentName = GAMESTATE_ALLOC_MC(&play->state, 2 * sizeof(char*));
|
||||
// "MAP texture initialization scene_data_ID=%d mapSegment=%x"
|
||||
osSyncPrintf("\n\n\nMAP テクスチャ初期化 scene_data_ID=%d\nmapSegment=%x\n\n", play->sceneNum,
|
||||
interfaceCtx->mapSegment, play);
|
||||
|
@ -10,10 +10,6 @@
|
||||
#include <stdlib.h> // malloc
|
||||
#include <string.h> // memcpy
|
||||
|
||||
// OTRTODO: Replace usage of this method when we can clear the cache
|
||||
// for a single texture without the need of a DL opcode in the render code
|
||||
void gfx_texture_cache_clear();
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED)
|
||||
|
||||
#define LAVA_TEX_WIDTH 32
|
||||
@ -123,7 +119,9 @@ void BossDodongo_RegisterBlendedLavaTextureUpdate() {
|
||||
sMaskTexLava[i] = maskVal;
|
||||
}
|
||||
}
|
||||
|
||||
Gfx_RegisterBlendedTexture(gDodongosCavernBossLavaFloorTex, sMaskTexLava, NULL);
|
||||
Gfx_TextureCacheDelete(sMaskTexLava);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -165,7 +163,9 @@ void BossDodongo_RegisterBlendedLavaTextureUpdate() {
|
||||
}
|
||||
}
|
||||
|
||||
gfx_texture_cache_clear();
|
||||
Gfx_TextureCacheDelete(sMaskTexLava);
|
||||
Gfx_TextureCacheDelete(sLavaWavyTex);
|
||||
Gfx_TextureCacheDelete(sLavaFloorModifiedTex);
|
||||
}
|
||||
|
||||
void func_808C12C4(u8* arg1, s16 arg2) {
|
||||
@ -228,6 +228,7 @@ void func_808C1554_Raw(void* arg0, void* floorTex, s32 arg2, f32 arg3) {
|
||||
}
|
||||
|
||||
free(sp54);
|
||||
Gfx_TextureCacheDelete(sLavaWavyTexRaw);
|
||||
}
|
||||
|
||||
// Modified to support CPU modified texture with the resource system
|
||||
@ -255,6 +256,8 @@ void func_808C1554(void* arg0, void* floorTex, s32 arg2, f32 arg3) {
|
||||
temp_s3[i + temp2] = sp54[i + i2];
|
||||
}
|
||||
}
|
||||
|
||||
Gfx_TextureCacheDelete(sLavaWavyTex);
|
||||
}
|
||||
|
||||
void func_808C17C8(PlayState* play, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f32 arg4, s16 arg5) {
|
||||
@ -373,6 +376,13 @@ void BossDodongo_Init(Actor* thisx, PlayState* play) {
|
||||
Gfx_RegisterBlendedTexture(object_kingdodongo_Tex_016990, sMaskTex32x16, NULL);
|
||||
Gfx_RegisterBlendedTexture(object_kingdodongo_Tex_016E10, sMaskTex32x16, NULL);
|
||||
|
||||
// Clear cache for masks
|
||||
Gfx_TextureCacheDelete(sMaskTex8x16);
|
||||
Gfx_TextureCacheDelete(sMaskTex8x32);
|
||||
Gfx_TextureCacheDelete(sMaskTex16x16);
|
||||
Gfx_TextureCacheDelete(sMaskTex16x32);
|
||||
Gfx_TextureCacheDelete(sMaskTex32x16);
|
||||
|
||||
BossDodongo_RegisterBlendedLavaTextureUpdate();
|
||||
|
||||
// Register alt listener to update the blended lava for the replacement texture based on alt path
|
||||
@ -1206,6 +1216,7 @@ void BossDodongo_Update(Actor* thisx, PlayState* play2) {
|
||||
}
|
||||
} else {
|
||||
sMaskTexLava[new_var] = 1;
|
||||
Gfx_TextureCacheDelete(sMaskTexLava);
|
||||
}
|
||||
|
||||
this->unk_1C2 += 37;
|
||||
@ -1345,18 +1356,6 @@ void BossDodongo_Draw(Actor* thisx, PlayState* play) {
|
||||
gSPInvalidateTexCache(POLY_OPA_DISP++, sMaskTex32x16);
|
||||
}
|
||||
|
||||
gSPInvalidateTexCache(POLY_OPA_DISP++, sMaskTexLava);
|
||||
|
||||
// Using WORK_DISP to invalidate these textures as they are used in drawing the scene textures which happens
|
||||
// before actors are drawn. WORK_DISP comes before POLAY_OPA_DISP. It is probably not meant for this, but it
|
||||
// at least works for now.
|
||||
// Alternatively, having a way to invalidate just these pointers from the Update func should be sufficient.
|
||||
if (sLavaFloorModifiedTexRaw != NULL) {
|
||||
gSPInvalidateTexCache(WORK_DISP++, sLavaWavyTexRaw);
|
||||
} else {
|
||||
gSPInvalidateTexCache(WORK_DISP++, sLavaWavyTex);
|
||||
}
|
||||
|
||||
if ((this->unk_1C0 >= 2) && (this->unk_1C0 & 1)) {
|
||||
POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 255, 255, 0, 900, 1099);
|
||||
} else {
|
||||
|
@ -312,6 +312,9 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
KaleidoScope_DrawQuadTextureRGBA32(gfxCtx, gQuestIconGoldSkulltulaTex, 24, 24, 8);
|
||||
}
|
||||
|
||||
// Unique index for both pulse phases
|
||||
uint8_t palettePulseIdx = (mapBgPulseStage ? 40 : 20) - mapBgPulseTimer;
|
||||
|
||||
if ((play->sceneNum >= SCENE_DEKU_TREE) && (play->sceneNum <= SCENE_TREASURE_BOX_SHOP)) {
|
||||
stepR = (mapBgPulseR - mapBgPulseColors[mapBgPulseStage][0]) / mapBgPulseTimer;
|
||||
stepG = (mapBgPulseG - mapBgPulseColors[mapBgPulseStage][1]) / mapBgPulseTimer;
|
||||
@ -324,6 +327,9 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
interfaceCtx->mapPalette[28] = (rgba16 & 0xFF00) >> 8;
|
||||
interfaceCtx->mapPalette[29] = rgba16 & 0xFF;
|
||||
|
||||
interfaceCtx->mapPalettesPulse[palettePulseIdx][28] = (rgba16 & 0xFF00) >> 8;
|
||||
interfaceCtx->mapPalettesPulse[palettePulseIdx][29] = rgba16 & 0xFF;
|
||||
|
||||
mapBgPulseTimer--;
|
||||
if (mapBgPulseTimer == 0) {
|
||||
mapBgPulseStage ^= 1;
|
||||
@ -335,7 +341,8 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
gDPSetTextureFilter(POLY_KAL_DISP++, G_TF_POINT);
|
||||
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 255, pauseCtx->alpha);
|
||||
|
||||
gDPLoadTLUT_pal16(POLY_KAL_DISP++, 0, interfaceCtx->mapPalette);
|
||||
// Use a unique palette address per frame so the renderer/shader can cache all variations
|
||||
gDPLoadTLUT_pal16(POLY_KAL_DISP++, 0, interfaceCtx->mapPalettesPulse[palettePulseIdx]);
|
||||
gDPSetTextureLUT(POLY_KAL_DISP++, G_TT_RGBA16);
|
||||
|
||||
u8 mirroredWorld = CVarGetInteger("gMirroredWorld", 0);
|
||||
@ -349,10 +356,6 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
|
||||
gSPVertex(POLY_KAL_DISP++, &pauseCtx->mapPageVtx[60], 8, 0);
|
||||
|
||||
// The dungeon map textures are recreated each frame, so always invalidate them
|
||||
gSPInvalidateTexCache(POLY_KAL_DISP++, interfaceCtx->mapSegment[0]);
|
||||
gSPInvalidateTexCache(POLY_KAL_DISP++, interfaceCtx->mapSegment[1]);
|
||||
|
||||
gDPLoadTextureBlock_4b(POLY_KAL_DISP++, interfaceCtx->mapSegmentName[0], G_IM_FMT_CI, MAP_48x85_TEX_WIDTH,
|
||||
MAP_48x85_TEX_HEIGHT, 0, G_TX_WRAP | mirrorMode, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK,
|
||||
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
@ -1205,8 +1205,6 @@ Gfx* KaleidoScope_DrawPageSections(Gfx* gfx, Vtx* vertices, void** textures) {
|
||||
return gfx;
|
||||
}
|
||||
|
||||
static uint8_t mapBlendMask[MAP_48x85_TEX_WIDTH * MAP_48x85_TEX_HEIGHT];
|
||||
|
||||
void KaleidoScope_DrawPages(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
static Color_RGB8 D_8082ACF4[12] = {
|
||||
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 255, 255, 0 }, { 0, 0, 0 },
|
||||
@ -1375,10 +1373,6 @@ void KaleidoScope_DrawPages(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
// Need to invalidate the blend mask every frame. Ideally this would be done in KaleidoScope_DrawDungeonMap
|
||||
// but the reference is not shared between files
|
||||
gSPInvalidateTexCache(POLY_KAL_DISP++, mapBlendMask);
|
||||
|
||||
if (pauseCtx->pageIndex) { // pageIndex != PAUSE_ITEM
|
||||
gDPPipeSync(OVERLAY_DISP++);
|
||||
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA, G_CC_MODULATEIA);
|
||||
@ -3326,6 +3320,7 @@ static uint8_t mapLeftTexModified[MAP_48x85_TEX_SIZE];
|
||||
static uint8_t mapRightTexModified[MAP_48x85_TEX_SIZE];
|
||||
static uint8_t* mapLeftTexModifiedRaw = NULL;
|
||||
static uint8_t* mapRightTexModifiedRaw = NULL;
|
||||
static uint8_t mapBlendMask[MAP_48x85_TEX_WIDTH * MAP_48x85_TEX_HEIGHT];
|
||||
|
||||
// Load dungeon maps into the interface context
|
||||
// SoH [General] - Modified to account for our resource system and HD textures
|
||||
@ -3357,19 +3352,16 @@ void KaleidoScope_LoadDungeonMap(PlayState* play) {
|
||||
size_t size = (width * height) / 2; // account for CI4 size
|
||||
|
||||
// Resource size being larger than the calculated CI size means it is most likely not a CI4 texture
|
||||
// Abort early end undo the blended effect by clearing the mask to avoid crashing
|
||||
// Abort early and unregister the blended effect to avoid crashing
|
||||
if (size < ResourceGetTexSizeByName(interfaceCtx->mapSegmentName[0])) {
|
||||
if (mapBlendMask[0] != 0) {
|
||||
for (size_t i = 0; i < ARRAY_COUNT(mapBlendMask); i++) {
|
||||
mapBlendMask[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
interfaceCtx->mapSegment[0] = NULL;
|
||||
interfaceCtx->mapSegment[1] = NULL;
|
||||
|
||||
Gfx_RegisterBlendedTexture(interfaceCtx->mapSegmentName[0], mapBlendMask, NULL);
|
||||
Gfx_RegisterBlendedTexture(interfaceCtx->mapSegmentName[1], mapBlendMask, NULL);
|
||||
Gfx_UnregisterBlendedTexture(interfaceCtx->mapSegmentName[0]);
|
||||
Gfx_UnregisterBlendedTexture(interfaceCtx->mapSegmentName[1]);
|
||||
|
||||
Gfx_TextureCacheDelete(interfaceCtx->mapSegmentName[0]);
|
||||
Gfx_TextureCacheDelete(interfaceCtx->mapSegmentName[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3404,6 +3396,11 @@ void KaleidoScope_LoadDungeonMap(PlayState* play) {
|
||||
|
||||
Gfx_RegisterBlendedTexture(interfaceCtx->mapSegmentName[0], mapBlendMask, interfaceCtx->mapSegment[0]);
|
||||
Gfx_RegisterBlendedTexture(interfaceCtx->mapSegmentName[1], mapBlendMask, interfaceCtx->mapSegment[1]);
|
||||
|
||||
Gfx_TextureCacheDelete(interfaceCtx->mapSegmentName[0]);
|
||||
Gfx_TextureCacheDelete(interfaceCtx->mapSegmentName[1]);
|
||||
Gfx_TextureCacheDelete(interfaceCtx->mapSegment[0]);
|
||||
Gfx_TextureCacheDelete(interfaceCtx->mapSegment[1]);
|
||||
}
|
||||
|
||||
static uint8_t registeredDungeonMapTextureHook = false;
|
||||
@ -3444,6 +3441,11 @@ void KaleidoScope_UpdateDungeonMap(PlayState* play) {
|
||||
KaleidoScope_LoadDungeonMap(play);
|
||||
Map_SetFloorPalettesData(play, pauseCtx->dungeonMapSlot - 3);
|
||||
|
||||
// Copy the map palette values to all pulse palettes
|
||||
for (uint8_t i = 0; i < ARRAY_COUNT(interfaceCtx->mapPalettesPulse); i++) {
|
||||
memcpy(interfaceCtx->mapPalettesPulse[i], interfaceCtx->mapPalette, sizeof(interfaceCtx->mapPalette));
|
||||
}
|
||||
|
||||
s32 size = MAP_48x85_TEX_SIZE;
|
||||
|
||||
if (ResourceMgr_TexIsRaw(interfaceCtx->mapSegmentName[0])) {
|
||||
|
Loading…
Reference in New Issue
Block a user