Make DynOS texture lookup use a set for performance

This commit is contained in:
MysterD 2022-04-19 18:24:26 -07:00
parent cdb7701905
commit 8f773ea887
9 changed files with 52 additions and 44 deletions

View file

@ -12,7 +12,7 @@ void *dynos_swap_cmd(void *cmd);
void *dynos_update_cmd (void *cmd); void *dynos_update_cmd (void *cmd);
void dynos_update_gfx (); void dynos_update_gfx ();
void dynos_update_opt (void *pad); void dynos_update_opt (void *pad);
s32 dynos_gfx_import_texture (void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize); s32 dynos_tex_import (void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize);
void dynos_gfx_swap_animations(void *ptr); void dynos_gfx_swap_animations(void *ptr);
// -- warps -- // // -- warps -- //

View file

@ -672,8 +672,6 @@ void DynOS_Opt_DrawPrompt(DynosOption *aCurrentMenu, DynosOption *aOptionsMenu,
// Gfx // Gfx
// //
u8 *DynOS_Gfx_TextureConvertToRGBA32(const u8 *aData, u64 aLength, s32 aFormat, s32 aSize, const u8 *aPalette);
bool DynOS_Gfx_ImportTexture(void **aOutput, void *aPtr, s32 aTile, void *aGfxRApi, void **aHashMap, void *aPool, u32 *aPoolPos, u32 aPoolSize);
Array<ActorGfx> &DynOS_Gfx_GetActorList(); Array<ActorGfx> &DynOS_Gfx_GetActorList();
Array<PackData *> &DynOS_Gfx_GetPacks(); Array<PackData *> &DynOS_Gfx_GetPacks();
Array<bool> &DynOS_Gfx_GetPacksEnabled(); Array<bool> &DynOS_Gfx_GetPacksEnabled();
@ -759,13 +757,21 @@ const void *DynOS_Actor_GetLayoutFromName(const char *aActorName);
s32 DynOS_Actor_GetIndex(const void *aGeoLayout); s32 DynOS_Actor_GetIndex(const void *aGeoLayout);
bool DynOS_Actor_IsCustom(s32 aIndex); bool DynOS_Actor_IsCustom(s32 aIndex);
//
// Tex Manager
//
void DynOS_Tex_Valid(GfxData* aGfxData);
void DynOS_Tex_Invalid(GfxData* aGfxData);
u8 *DynOS_Tex_ConvertToRGBA32(const u8 *aData, u64 aLength, s32 aFormat, s32 aSize, const u8 *aPalette);
bool DynOS_Tex_Import(void **aOutput, void *aPtr, s32 aTile, void *aGfxRApi, void **aHashMap, void *aPool, u32 *aPoolPos, u32 aPoolSize);
// //
// Lvl Manager // Lvl Manager
// //
Array<Pair<const char*, GfxData*>> &DynOS_Lvl_GetArray(); Array<Pair<const char*, GfxData*>> &DynOS_Lvl_GetArray();
void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilePath, const char *aLevelName); void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilePath, const char *aLevelName);
DataNode<TexData>* DynOS_Lvl_GetTexture(void *aPtr);
GfxData* DynOS_Lvl_GetActiveGfx(void); GfxData* DynOS_Lvl_GetActiveGfx(void);
const char* DynOS_Lvl_GetToken(u32 index); const char* DynOS_Lvl_GetToken(u32 index);
DataNode<MovtexQC>* DynOS_Lvl_GetMovtexQuadCollection(s32 index); DataNode<MovtexQC>* DynOS_Lvl_GetMovtexQuadCollection(s32 index);

View file

@ -37,7 +37,7 @@ void DynOS_Tex_ConvertTextureDataToPng(GfxData *aGfxData, TexData* aTexture) {
// Convert to RGBA32 // Convert to RGBA32
const u8 *_Palette = (aGfxData->mGfxContext.mCurrentPalette ? aGfxData->mGfxContext.mCurrentPalette->mData->mRawData.begin() : NULL); const u8 *_Palette = (aGfxData->mGfxContext.mCurrentPalette ? aGfxData->mGfxContext.mCurrentPalette->mData->mRawData.begin() : NULL);
u8 *_Buffer = DynOS_Gfx_TextureConvertToRGBA32(aTexture->mRawData.begin(), aTexture->mRawData.Count(), aTexture->mRawFormat, aTexture->mRawSize, _Palette); u8 *_Buffer = DynOS_Tex_ConvertToRGBA32(aTexture->mRawData.begin(), aTexture->mRawData.Count(), aTexture->mRawFormat, aTexture->mRawSize, _Palette);
if (_Buffer == NULL) { if (_Buffer == NULL) {
PrintError(" ERROR: Unknown texture format"); PrintError(" ERROR: Unknown texture format");
return; return;

View file

@ -20,8 +20,8 @@ void dynos_update_opt(void *pad) {
return DynOS_UpdateOpt(pad); return DynOS_UpdateOpt(pad);
} }
s32 dynos_gfx_import_texture(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize) { s32 dynos_tex_import(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize) {
return DynOS_Gfx_ImportTexture(output, ptr, tile, grapi, hashmap, pool, (u32 *) poolpos, (u32) poolsize); return DynOS_Tex_Import(output, ptr, tile, grapi, hashmap, pool, (u32 *) poolpos, (u32) poolsize);
} }
void dynos_gfx_swap_animations(void *ptr) { void dynos_gfx_swap_animations(void *ptr) {

View file

@ -147,6 +147,7 @@ void DynOS_Gfx_Update() {
_ActorGfx->mGfxData = _GfxData; _ActorGfx->mGfxData = _GfxData;
_ActorGfx->mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode((*(_GfxData->mGeoLayouts.end() - 1))->mData, true); _ActorGfx->mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode((*(_GfxData->mGeoLayouts.end() - 1))->mData, true);
_ActorGfx->mGraphNode->georef = DynOS_Actor_GetLayoutFromIndex(_ActorIndex); _ActorGfx->mGraphNode->georef = DynOS_Actor_GetLayoutFromIndex(_ActorIndex);
DynOS_Tex_Valid(_GfxData);
break; break;
} }
} }
@ -154,6 +155,7 @@ void DynOS_Gfx_Update() {
// If disabled and this pack is the one selected // If disabled and this pack is the one selected
// replace the actor's model by the default one // replace the actor's model by the default one
else if (!_Enabled[i] && _ActorGfx->mPackIndex == i) { else if (!_Enabled[i] && _ActorGfx->mPackIndex == i) {
DynOS_Tex_Invalid(_ActorGfx->mGfxData);
_ActorGfx->mPackIndex = -1; _ActorGfx->mPackIndex = -1;
_ActorGfx->mGfxData = NULL; _ActorGfx->mGfxData = NULL;
_ActorGfx->mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(DynOS_Actor_GetLayoutFromIndex(_ActorIndex), true); _ActorGfx->mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(DynOS_Actor_GetLayoutFromIndex(_ActorIndex), true);

View file

@ -49,6 +49,7 @@ void DynOS_Actor_AddCustom(const SysPath &aFilename, const char *aActorName) {
pActorGfxList[index].mPackIndex = 99; pActorGfxList[index].mPackIndex = 99;
pActorGfxList[index].mGfxData = _GfxData; pActorGfxList[index].mGfxData = _GfxData;
pActorGfxList[index].mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(geoLayout, false); pActorGfxList[index].mGraphNode = (GraphNode *) DynOS_Geo_GetGraphNode(geoLayout, false);
DynOS_Tex_Valid(_GfxData);
} }
s32 DynOS_Actor_GetCount() { s32 DynOS_Actor_GetCount() {

View file

@ -55,20 +55,7 @@ void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilename, const char *aLev
DynOS_Level_Override((void*)originalScript, newScriptNode->mData); DynOS_Level_Override((void*)originalScript, newScriptNode->mData);
sDynosOverrideLevelScripts.Add({ originalScript, newScriptNode->mData, _Node}); sDynosOverrideLevelScripts.Add({ originalScript, newScriptNode->mData, _Node});
} DynOS_Tex_Valid(_Node);
DataNode<TexData> *DynOS_Lvl_GetTexture(void *aPtr) {
for (s32 i = 0; i < sDynosCustomLevelScripts.Count(); ++i) {
auto &mTextures = sDynosCustomLevelScripts[i].second->mTextures;
for (s32 j = 0; j < mTextures.Count(); j++) {
auto &texture = mTextures[j];
if (texture == aPtr) {
return texture;
}
}
}
return NULL;
} }
GfxData* DynOS_Lvl_GetActiveGfx(void) { GfxData* DynOS_Lvl_GetActiveGfx(void) {

View file

@ -1,8 +1,11 @@
#include <set>
#include "dynos.cpp.h" #include "dynos.cpp.h"
extern "C" { extern "C" {
#include "pc/gfx/gfx_rendering_api.h" #include "pc/gfx/gfx_rendering_api.h"
} }
static std::set<DataNode<TexData> *> sDynosValidTextures;
// //
// Conversion // Conversion
// //
@ -162,7 +165,7 @@ static u8 *I8_RGBA32(const u8 *aData, u64 aLength) {
return _Buffer; return _Buffer;
} }
u8 *DynOS_Gfx_TextureConvertToRGBA32(const u8 *aData, u64 aLength, s32 aFormat, s32 aSize, const u8 *aPalette) { u8 *DynOS_Tex_ConvertToRGBA32(const u8 *aData, u64 aLength, s32 aFormat, s32 aSize, const u8 *aPalette) {
switch ((aFormat << 8) | aSize ) { switch ((aFormat << 8) | aSize ) {
case ((G_IM_FMT_RGBA << 8) | G_IM_SIZ_16b): return RGBA16_RGBA32(aData, aLength); case ((G_IM_FMT_RGBA << 8) | G_IM_SIZ_16b): return RGBA16_RGBA32(aData, aLength);
case ((G_IM_FMT_RGBA << 8) | G_IM_SIZ_32b): return RGBA32_RGBA32(aData, aLength); case ((G_IM_FMT_RGBA << 8) | G_IM_SIZ_32b): return RGBA32_RGBA32(aData, aLength);
@ -182,7 +185,7 @@ u8 *DynOS_Gfx_TextureConvertToRGBA32(const u8 *aData, u64 aLength, s32 aFormat,
// //
typedef struct GfxRenderingAPI GRAPI; typedef struct GfxRenderingAPI GRAPI;
static void DynOS_Gfx_UploadTexture(DataNode<TexData> *aNode, GRAPI *aGfxRApi, s32 aTile, s32 aTexId) { static void DynOS_Tex_Upload(DataNode<TexData> *aNode, GRAPI *aGfxRApi, s32 aTile, s32 aTexId) {
aGfxRApi->select_texture(aTile, aTexId); aGfxRApi->select_texture(aTile, aTexId);
aGfxRApi->upload_texture(aNode->mData->mRawData.begin(), aNode->mData->mRawWidth, aNode->mData->mRawHeight); aGfxRApi->upload_texture(aNode->mData->mRawData.begin(), aNode->mData->mRawWidth, aNode->mData->mRawHeight);
aNode->mData->mUploaded = true; aNode->mData->mUploaded = true;
@ -201,7 +204,7 @@ struct THN {
bool mLInf; bool mLInf;
}; };
static bool DynOS_Gfx_CacheTexture(THN **aOutput, DataNode<TexData> *aNode, s32 aTile, GRAPI *aGfxRApi, THN **aHashMap, THN *aPool, u32 *aPoolPos, u32 aPoolSize) { static bool DynOS_Tex_Cache(THN **aOutput, DataNode<TexData> *aNode, s32 aTile, GRAPI *aGfxRApi, THN **aHashMap, THN *aPool, u32 *aPoolPos, u32 aPoolSize) {
// Find texture in cache // Find texture in cache
uintptr_t _Hash = ((uintptr_t) aNode) & ((aPoolSize * 2) - 1); uintptr_t _Hash = ((uintptr_t) aNode) & ((aPoolSize * 2) - 1);
@ -210,7 +213,7 @@ static bool DynOS_Gfx_CacheTexture(THN **aOutput, DataNode<TexData> *aNode, s32
if ((*_Node)->mAddr == (const void *) aNode) { if ((*_Node)->mAddr == (const void *) aNode) {
aGfxRApi->select_texture(aTile, (*_Node)->mTexId); aGfxRApi->select_texture(aTile, (*_Node)->mTexId);
if (!aNode->mData->mUploaded) { if (!aNode->mData->mUploaded) {
DynOS_Gfx_UploadTexture(aNode, aGfxRApi, aTile, (*_Node)->mTexId); DynOS_Tex_Upload(aNode, aGfxRApi, aTile, (*_Node)->mTexId);
} }
(*aOutput) = (*_Node); (*aOutput) = (*_Node);
return true; return true;
@ -242,37 +245,46 @@ static bool DynOS_Gfx_CacheTexture(THN **aOutput, DataNode<TexData> *aNode, s32
return false; return false;
} }
//
// Make textures valid/invalid
//
void DynOS_Tex_Valid(GfxData* aGfxData) {
for (auto &_Texture : aGfxData->mTextures) {
sDynosValidTextures.insert(_Texture);
}
}
void DynOS_Tex_Invalid(GfxData* aGfxData) {
for (auto &_Texture : aGfxData->mTextures) {
sDynosValidTextures.erase(_Texture);
}
}
// //
// Import // Import
// //
static DataNode<TexData> *DynOS_Gfx_RetrieveNode(void *aPtr) { static DataNode<TexData> *DynOS_Tex_RetrieveNode(void *aPtr) {
Array<ActorGfx> &pActorGfxList = DynOS_Gfx_GetActorList(); if (sDynosValidTextures.find((DataNode<TexData>*)aPtr) != sDynosValidTextures.end()) {
for (auto& _ActorGfx : pActorGfxList) { return (DataNode<TexData>*)aPtr;
if (_ActorGfx.mGfxData) {
for (auto &_Node : _ActorGfx.mGfxData->mTextures) {
if ((void*) _Node == aPtr) {
return _Node;
} }
} return NULL;
}
}
return DynOS_Lvl_GetTexture(aPtr);
} }
static bool DynOS_Gfx_ImportTexture_Typed(THN **aOutput, void *aPtr, s32 aTile, GRAPI *aGfxRApi, THN **aHashMap, THN *aPool, u32 *aPoolPos, u32 aPoolSize) { static bool DynOS_Tex_Import_Typed(THN **aOutput, void *aPtr, s32 aTile, GRAPI *aGfxRApi, THN **aHashMap, THN *aPool, u32 *aPoolPos, u32 aPoolSize) {
DataNode<TexData> *_Node = DynOS_Gfx_RetrieveNode(aPtr); DataNode<TexData> *_Node = DynOS_Tex_RetrieveNode(aPtr);
if (_Node) { if (_Node) {
if (!DynOS_Gfx_CacheTexture(aOutput, _Node, aTile, aGfxRApi, aHashMap, aPool, aPoolPos, aPoolSize)) { if (!DynOS_Tex_Cache(aOutput, _Node, aTile, aGfxRApi, aHashMap, aPool, aPoolPos, aPoolSize)) {
DynOS_Gfx_UploadTexture(_Node, aGfxRApi, aTile, (*aOutput)->mTexId); DynOS_Tex_Upload(_Node, aGfxRApi, aTile, (*aOutput)->mTexId);
} }
return true; return true;
} }
return false; return false;
} }
bool DynOS_Gfx_ImportTexture(void **aOutput, void *aPtr, s32 aTile, void *aGfxRApi, void **aHashMap, void *aPool, u32 *aPoolPos, u32 aPoolSize) { bool DynOS_Tex_Import(void **aOutput, void *aPtr, s32 aTile, void *aGfxRApi, void **aHashMap, void *aPool, u32 *aPoolPos, u32 aPoolSize) {
return DynOS_Gfx_ImportTexture_Typed( return DynOS_Tex_Import_Typed(
(THN **) aOutput, (THN **) aOutput,
(void *) aPtr, (void *) aPtr,
(s32) aTile, (s32) aTile,

View file

@ -602,8 +602,8 @@ static bool preload_texture(UNUSED void *user, const char *path) {
#endif // EXTERNAL_DATA #endif // EXTERNAL_DATA
static void import_texture(int tile) { static void import_texture(int tile) {
extern s32 dynos_gfx_import_texture(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize); extern s32 dynos_tex_import(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize);
if (dynos_gfx_import_texture((void **) &rendering_state.textures[tile], (void *) rdp.loaded_texture[tile].addr, tile, gfx_rapi, (void **) gfx_texture_cache.hashmap, (void *) gfx_texture_cache.pool, (int *) &gfx_texture_cache.pool_pos, MAX_CACHED_TEXTURES)) { return; } if (dynos_tex_import((void **) &rendering_state.textures[tile], (void *) rdp.loaded_texture[tile].addr, tile, gfx_rapi, (void **) gfx_texture_cache.hashmap, (void *) gfx_texture_cache.pool, (int *) &gfx_texture_cache.pool_pos, MAX_CACHED_TEXTURES)) { return; }
uint8_t fmt = rdp.texture_tile.fmt; uint8_t fmt = rdp.texture_tile.fmt;
uint8_t siz = rdp.texture_tile.siz; uint8_t siz = rdp.texture_tile.siz;