[Perf] (MG_Backend/DirectVulkan): store the resolved TextureResource pointer in the per-draw sync memo so repeat SyncTextureAndGetDescriptor calls skip the resource-map lookup

This commit is contained in:
2026-07-13 06:53:37 -04:00
parent 37cd5b42de
commit e78eee972e
2 changed files with 16 additions and 9 deletions
@@ -705,11 +705,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
// transition path, so the short-circuited resource still reflects the truth. // transition path, so the short-circuited resource still reflects the truth.
const Bool memoActive = m_drawSyncScopeActive; const Bool memoActive = m_drawSyncScopeActive;
if (memoActive) { if (memoActive) {
for (const TextureIdentity& synced : m_drawSyncedThisDraw) { for (const DrawSyncedTexture& synced : m_drawSyncedThisDraw) {
if (synced == identity) { if (synced.identity == identity) {
auto cachedIt = m_textureResources.find(identity); if (synced.resource != nullptr && synced.resource->image != VK_NULL_HANDLE) {
if (cachedIt != m_textureResources.end() && cachedIt->second.image != VK_NULL_HANDLE) { return synced.resource;
return &(cachedIt->second);
} }
break; // resource unexpectedly gone -> fall through to a full sync break; // resource unexpectedly gone -> fall through to a full sync
} }
@@ -748,14 +747,14 @@ namespace MobileGL::MG_Backend::DirectVulkan {
if (memoActive) { if (memoActive) {
Bool recorded = false; Bool recorded = false;
for (const TextureIdentity& synced : m_drawSyncedThisDraw) { for (const DrawSyncedTexture& synced : m_drawSyncedThisDraw) {
if (synced == identity) { if (synced.identity == identity) {
recorded = true; recorded = true;
break; break;
} }
} }
if (!recorded) { if (!recorded) {
m_drawSyncedThisDraw.push_back(identity); m_drawSyncedThisDraw.push_back({identity, &(it->second)});
} }
} }
@@ -287,7 +287,15 @@ private:
// Active only between BeginDrawSyncScope/EndDrawSyncScope; identities of // Active only between BeginDrawSyncScope/EndDrawSyncScope; identities of
// textures already fully synced in the current draw (small N -> flat scan). // textures already fully synced in the current draw (small N -> flat scan).
Bool m_drawSyncScopeActive = false; Bool m_drawSyncScopeActive = false;
Vector<TextureIdentity> m_drawSyncedThisDraw; // Per-draw sync memo: the identity plus the resolved resource pointer. The pointer is stable
// across rehash in the node-based m_textureResources and stays valid for the draw (a texture
// synced this draw is alive and is not erased mid-draw), so a repeat sync of the same texture
// returns the resource without re-hashing the identity into m_textureResources.
struct DrawSyncedTexture {
TextureIdentity identity;
TextureResource* resource = nullptr;
};
Vector<DrawSyncedTexture> m_drawSyncedThisDraw;
std::unordered_map<TextureIdentity, WeakPtr<MG_State::GLState::ITextureObject>, TextureIdentityHash> m_aliveObjects; std::unordered_map<TextureIdentity, WeakPtr<MG_State::GLState::ITextureObject>, TextureIdentityHash> m_aliveObjects;
std::unordered_map<TextureIdentity, TextureResource, TextureIdentityHash> m_textureResources; std::unordered_map<TextureIdentity, TextureResource, TextureIdentityHash> m_textureResources;
Vector<Vector<TextureResource>> m_deferredReleases; Vector<Vector<TextureResource>> m_deferredReleases;