Combining PSO Precaching and Bundled PSOs

Hello,

We want to collect bundled PSOs for everything possible, compile them at startup, and use PSO precaching at runtime only for anything we missed. We’re using the default gray material delay strategy. However, when the player reaches a dense city area, many objects still show the default gray material, even though bundled PSOs should cover this area.

Shouldn’t PSO precaching skip jobs if the PSO already exists in the bundled cache? I couldn’t find any condition that checks for this. The behavior I see looks like if PSO Precaching is completely ignoring what Bundled PSOs prepared, as if it had its own separate cache.

Next game start then shows no gray materials on startup, presumably because PSO Precaching was able to load alraedy precached materials very fast.

We tried to run the game with r.PSOPrecaching=0, to identify if these objects which we see as gray are really missing from the bundled PSO and need to handled by the precaching but it does not seem to be the case. There seem to be no logs about finding them as new graphics PSO.

Hi there,

Shouldn’t PSO precaching skip jobs if the PSO already exists in the bundled cache?

Yes, as far as I know, that is the intended behavior. If you suspect you are still missing PSOs in your bundled cache, then you can try the following the steps in from our public documentation validate your PSO collection process: https://dev.epicgames.com/documentation/en\-us/unreal\-engine/manually\-creating\-bundled\-pso\-caches\-in\-unreal\-engine\#testingpsocoverage.

Once you have established that all of the required PSOs have been bundled, you can also validate what PSOs are being picked up by the precaching. For this, I would suggest not turning off the system and instead follow the guide we have laid out under the following link to log what you are missing: https://dev.epicgames.com/documentation/en\-us/unreal\-engine/pso\-precaching\-for\-unreal\-engine\#validationandtracking. Following those two steps should get you a clear overview of what PSOs you might be missing and implement steps to pick up the missing ones. Please let me know if you have any questions about this.

Cheers,

Tim

Hi Ondrej,

Those do sound like good strategies to try out. I know other licensees have gone the same route of displaying a loading screen, which is generally worth falling back to in case tweaking the PSO precaching system via platform configs does not work. Do let me know if you have any further questions.

Hi Tim,

I was able to identify the issue.

The PSOs I’m investigating—those appearing gray—are included in the bundled PSO. I’m testing the first game startup after using -clearPSODriverCache, which is when the issue occurs. Subsequent startups are fine.

What’s happening is that everything in the level has PSO precaching scheduled on PostLoad(). PSO Precaching schedules many tasks some of which may not actually be needed atm. I haven’t yet investigated exactly what they are—it’s also possible the list is inflated due to our enabled settings like r.PSOPrecache.Resources=1 and similar.

Components with bundled PSOs aren’t aware of the PSO being ready and are also added to the precaching queue. Because of everything else in the queue, these tasks end up waiting in the PSO precompile pool. Given our current priority settings and thread count, it takes about 8 seconds from the start of the map to reach the shader I’m looking at—only to find in 18 microseconds that the PSOs already exist in the low-level cache.

In the attached image, you can see in the bottom right corner the task that simply loads the shaders from the low-level cache. Once this completes, the component finishes its PSO precaching job and stops showing the gray material.

[Image Removed]

I will need to think what we can do to mitigate this. In ideal case, component would know that everything needed for current frame is already in low level cache and it would allow drawing it without gray material. Alternatively, I will see if we can tweak PSO thread count & priority and lower precached PSO count. Readding our shader compilation loading screen would also help for initial location but not the others coming from World Partition. I think I saw in 5.5 or ue5-main some code around r.PSOPrecache.DrawnComponentBoostStrategy for boosting priority of specific PSO, it could help too.