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
CustomTexture: prefetch all available textures #2162
Conversation
@BigheadSMZ Do you want to try the new option? It shall load all custom textures non-blocking (at least a bit) on startup. |
Why is the prefetcher on a separate thread? Does it really take so long that we can't block startup on it? Would parallelizing it help? Could we maybe consider adding support for some format that loads faster instead (like .dds)? Also, how much memory are we talking about? Gigabytes? |
Here, it's about 35 seconds. So it is worth in my opinion. Parallelizing would help, but soil isn't thread safe as written somewhere as comment... .dds is supported by soil already. The current xenoblade pack + environment are 3.6 GB, so it should never ever be enabled by default. |
Oh, another alternative: maybe we could track textures which are used together, so when one texture is used, we prefetch the others which are expected to be used soon. |
.dds might technically be supported, but it would be a heck of a lot faster if we could just memmap() the file and pass the pointer directly to the backend. |
How fast do the textures load if they are the in the cache of the OS? I mean like, copy the textures from Dolphin's folder to anywhere, and then start Dolphin and let it load the textures? |
{ | ||
const std::string& base_filename = entry.first; | ||
|
||
if (!strstr(base_filename.c_str(), "_mip")) |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
mimimi: It's more about png decoding than disk loading, at least here for me on my hard drive. |
@@ -40,6 +42,9 @@ class HiresTexture | |||
std::vector<Level> m_levels; | |||
|
|||
private: | |||
static HiresTexture* Load(std::string base_filename, u32 width, u32 height); |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
Sorry for the delay, didn't notice this until now. Gave it run and it seems to work as intended! This route turned out to be a lot better than I thought it would, my impression was the game would need to be paused or no textures would show up until after preloaded. At first I wasn't sure if it was working because I immediately seen custom textures, then a little message popped up "Custom Textures loaded, 3338.2 MB in 22.5 s". Ran around the known trouble spots and to my surprise not a single hiccup. |
It is working pretty well, but i did notice a couple of slowdowns here and there. Unfortunately it is also a ram killer, it makes pngs about 10 times bigger in memory than what they are. Tried two packs i have and 50 mb pngs became about 500 mb in memory and 70 mb about 800 mb. Big packs like the rogue squadron one which is 500mb will probably bring even a 8gb system to it's limits. |
@lioncash fixed |
I can see that being a concern. What would happen if the limit is breached, as in it tries to preload 8GB of textures and only 4GB is available? And would dds files be smaller in RAM than png and be worth using? Or how about even jpg if it could be added (if it isn't already)? |
@BigheadSMZ dds can be smaller, but in the current implementation, they aren't. And if you're out of ram, dolphin may just crash if you're lucky, else the system will freeze. |
So any opinions about merging? |
While I think this is an awesome feature especially since I can probably take full advantage of it without worry, I don't know if it is safe in the hands of the masses if it has a chance to freeze their system. I imagine it will create panic when someone's 2006 laptop with 2GB RAM deadlocks using Dolphin and texture packs and they don't know why. I'm fine either way. But if there is no way to prevent a random meltdown then maybe it should have a "may cause system instability" warning. |
This seems like an awesome feature, but can't we at least warn users with less than 8GB of ram not to use it? Or disable it altogether? |
This patch needs a proper host memory manager to be sensibly merged. Enabling options should not make it possible to destroy a stable emulation experience. |
This should only be an issue for big texture packs. Most packs aren't that big. |
@@ -138,6 +138,7 @@ static wxString xfb_virtual_desc = wxTRANSLATE("Emulate XFBs using GPU texture o | |||
static wxString xfb_real_desc = wxTRANSLATE("Emulate XFBs accurately.\nSlows down emulation a lot and prohibits high-resolution rendering but is necessary to emulate a number of games properly.\n\nIf unsure, check virtual XFB emulation instead."); | |||
static wxString dump_textures_desc = wxTRANSLATE("Dump decoded game textures to User/Dump/Textures/<game_id>/.\n\nIf unsure, leave this unchecked."); | |||
static wxString load_hires_textures_desc = wxTRANSLATE("Load custom textures from User/Load/Textures/<game_id>/.\n\nIf unsure, leave this unchecked."); | |||
static wxString cache_hires_textures_desc = wxTRANSLATE("Load custom textures on startup.\nThis may require much of RAM but fixes some stutter.\n\nIf unsure, leave this unchecked."); |
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.
@StripTheSoulwhostolemydamnname "What does it matter, it only happens when using X anyway" is a terrible way to make decisions affecting software quality. |
Maybe disable this option on configurations without much ram for now? or just make sure it doesn't max out ram and tell it to stop/abort/notload any more textures? |
Some texture packs are not very big, 50-100 small textures will not take much RAM so disabling the option based on a set value wouldn't really be fair to those who could technically use one pack but not another. Maybe a dynamic limit could be imposed like....
I imagine this would also have a problem if the limit is nearly reached, loading Firefox, WinAMP, etc, could deliver a final blow that Dolphin wouldn't have reached on its own if only like 3MB was free after preloading. So maybe leave some overhead, fail to preload if at least (example random number: 512MB) is not calculated to be free. Such as... 8GB RAM in system This way the OS still has at least 512MB free (or whatever value works best) to manage so hopefully the limit won't be breached. I don't know many details of how things work on the software level, so I don't know if this could be an actual approach or if I'm just spouting nonsense. Maybe other options could be to remove some textures from RAM or not load some on start, but that kind of defeats the purpose. |
Checking for the size of all textures without loading them still takes quite a long time. So I suggest to just try to load them and when you hit the ram limitation, stop it. atm I'm thinking to just use 50% or the global system memory. Free memory isn't good as it may change while playing. So we still can get slowdown because of out-of-ram, but no system freezes any more. |
e499ea3
to
d1190c4
Compare
Updated to fix the remaining GUI issues and when to restart the prefetcher thread. |
8eb8adc
to
82ff988
Compare
6e94ccc
to
562b9d4
Compare
There is no nice way to correctly "detect" the "used" memory, so we just say we're fine to use 50% of the physical memory for custom textures. This will fix out-of-memory crashes, but we still might run into swapping issues.
The last commit now aborts the loading if not enough memory is available. It's only tested on linux, so may anyone please check it on osx and windows? It shall abort if the physical memory is smaller than 2 times the decoded texture pack. |
Here in windows it loaded textures up to half the physical memory in RAM (2 gbytes were used by dolphin). It didn't abort loading them altogether though. |
In my opinion, this PR is ready. Are there still any suggestions or questions? |
Testing wise no problems here. |
No issues here using the Rogue Squadron tex pack. |
CustomTexture: prefetch all available textures
This PR tries to prefetch and to decode all available custom textures if possible. This behavior can be enabled with a GUI option.
The goal is to reduce the stuttering on png decoding while playing, but it will require lots of memoy. eg the biggest texture pack I've found is the xenoblade one which requires additional 4GB. As this may crash smaller systems, the prefetcher will abort if more than half of the physical RAM is used.