-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Search the texture cache for small textures by address and hash #2097
Conversation
std::pair <TexCache::iterator, TexCache::iterator> iter_range = textures.equal_range(address); | ||
std::pair <TexCache::iterator, TexCache::iterator> iter_range; | ||
if (g_ActiveConfig.iSafeTextureCache_ColorSamples == 0 || | ||
(texture_size <= (u32)g_ActiveConfig.iSafeTextureCache_ColorSamples * 8 && palette_size <= (u32)g_ActiveConfig.iSafeTextureCache_ColorSamples * 8)) |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
@dolphin-emu-bot rebuild |
@@ -342,7 +342,20 @@ TextureCache::TCacheEntryBase* TextureCache::Load(const u32 stage) | |||
// | |||
// For efb copies, the entry created in CopyRenderTargetToTexture always has to be used, or else it was | |||
// done in vain. | |||
std::pair <TexCache::iterator, TexCache::iterator> iter_range = textures.equal_range(address); | |||
std::pair <TexCache::iterator, TexCache::iterator> iter_range; | |||
if (g_ActiveConfig.iSafeTextureCache_ColorSamples == 0 || |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
@dolphin-emu-bot rebuild Scanning the entire texture cache every time a small texture is bound is going to get really expensive in some cases. |
92c52d1
to
b8dca24
Compare
@dolphin-emu-bot rebuild |
Is there a better alternative than adding a 2nd map? Going through 500 entries for every texture is indeed bad. But keeping a 2nd map around for this special case bloats the code a bit. One alternative could be an option for this, but i want to avoid adding new options, unless it's really necessary. |
std::pair <TexCache::iterator, TexCache::iterator> iter_range = textures.equal_range(address); | ||
std::pair<TexCache::iterator, TexCache::iterator> iter_range; | ||
if (g_ActiveConfig.iSafeTextureCache_ColorSamples == 0 || | ||
(texture_size <= (u32)g_ActiveConfig.iSafeTextureCache_ColorSamples * 8 && palette_size <= (u32)g_ActiveConfig.iSafeTextureCache_ColorSamples * 8)) |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
b8dca24
to
c389915
Compare
36b233a
to
6dd2a3a
Compare
Ok, i've optimised searching the texture cache:
So in short, only if a texture is not found in the cache by address, the whole texture cache is searched. So the basic problem remains, and the worst case is still searching n entries n times each frame. But if a texture is not found in the cache, that's the general worst case already anyways. I'm not sure if this is really a big problem. One other problem on top of that is that if a texture is not at the same address, it will be found in the cache, but Dolphin will always do the long search for it. Is there a fast way to clone a texture cache entry? Or a good way to link from one to another? |
{ | ||
iter = textures.begin(); | ||
|
||
while (iter != textures.end()) |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
But this c++11 loop, LGTM |
6dd2a3a
to
98bc6f5
Compare
So, i've added the 2nd map to find cache entries by their hash. It seems to be working well, but there's some cleanup to be done. The comments needs to be reworked, the names with 2 in them can't obviously stay, and the code to remove entries from the 2nd map needs to be put in a function or something. Short: Do not review this yet, i'm still working on it. |
98bc6f5
to
18e384e
Compare
Ok, now the PR is in a reviewable state. |
// Remove the cache entry for normal textures from textures_by_hash and textures_by_address | ||
if (!t_iter->second->IsEfbCopy()) | ||
{ | ||
std::pair<TexCache::iterator, TexCache::iterator> iter_range = textures_by_hash.equal_range(t_iter->second->hash); |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
c418c9a
to
bf7a83b
Compare
How can i write "std::multimap<u64, TCacheEntryBase*>::iterator textures_by_hash_iter;" as "TexCache::iterator textures_by_hash_iter;" without changing too many lines? I think the performance can't be improved much further. So it's time to clean up the coding style and names, which i suck at, sorry. |
{ | ||
if (iter->second->textures_by_hash_iter != textures_by_address.end()) | ||
{ | ||
textures_by_hash.erase(iter->second->textures_by_hash_iter); |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
c3d4ff7
to
9bbeba7
Compare
This fixes issue 6563: https://code.google.com/p/dolphin-emu/issues/detail?id=6563 This PR adds a 2nd map to texture cache, which uses the hash as key. Cache entries from this new map are used only if the address matches or if the texture was fully hashed. This restriction avoids false positive cache hits. This results in a possible situation where safe texture cache accuracy could be faster than the fast one. Small textures means up to 1KB for fast texture cache accuracy, 4KB for medium, and all textures for safe accuracy. Since this adds a small overhead to all texture cache handling, some regression testing would be nice. Games, which use a lot of textures the same time, should be affected the most.
9bbeba7
to
3b9020d
Compare
So does this have a chance to be merged? Or is the lack of reviews related to how horrible the code is? Without the PR, in Tales of Symphonia gamecube, some menus are slower than the gameplay, world map, fights etc. So on low end machines that barely run the game, the menus will lag. Is avoiding this worth making the code more complicated? Or should the texture cache get a major overhaul of some kind anyways? Maybe something like allowing countless elements and only removing them when they haven't been used for a long time, and memory is getting low? |
@dolphin-emu-bot rebuild |
Search the texture cache for small textures by address and hash
Code cleanup for FreeTexture after merging PR #2097
This fixes issue 6563:
https://code.google.com/p/dolphin-emu/issues/detail?id=6563
This PR adds a 2nd map to texture cache, which uses the hash as key. Cache entries from this new map are used only if the address matches or if the texture was fully hashed. This restriction avoids false positive cache hits. This results in a possible situation where safe texture cache accuracy could be faster than the fast one.
Small textures means up to 1KB for fast texture cache accuracy, 4KB for medium, and all textures for safe accuracy.
Since this adds a small overhead to all texture cache handling, some regression testing would be nice. Games, which use a lot of textures the same time, should be affected the most.