Various questions about PSO Precaching misses.

Hello everyone,

Our project uses both bundled and PSO precaching.

Recently we audited our most frequent PSO Precaching misses and some questions emerged, so we would appreaciate some deeper clarification on the following points (for each you can find an example from the logs in the attached file):

  1. We get various “Too Late” misses during early gameplay even though we already wait until FShaderPipelineCache::NumPrecompilesRemaining() <= 0. According to this thread, this method should account for both the bundled and precached PSOs. If that’s true, what could be the reason these "Too Late"s after NumPrecompilesRemaining() <= 0?
  2. For certain SMs in the level we force their last LOD during gameplay which contains their own material which are not precached. Does PSO precaching not account for all LOD levels of the static meshes in the level?
  3. We get several Landscape Material Instances misses, but shouldn’t PSO precaching catch them as they are part of the level, or is the landscape not supported with precaching?
  4. When we trigger chaos destruction (GeometryCollection) we get misses for WorldGridMaterial, even though we are not using it and have no references to it. Is this behavior expected?
  5. In the loaded level we have translucent materials assigned to Static Meshes and they will always miss, even after enabling r.PSOPrecache.TranslucencyAllPass 1. Isn’t this cvar supposed to deal with those cases? It’s also interesting that in mobile devices, these same materials will have PassName = Unknown.

[Attachment Removed]

Steps to Reproduce[Attachment Removed]

Hi Joao,

Let me try and answer these questions as best as I can:

We get various “Too Late” misses during early gameplay even though we already wait until FShaderPipelineCache::NumPrecompilesRemaining() <= 0. According tothis thread, this method should account for both the bundled and precached PSOs. If that’s true, what could be the reason these "Too Late"s after NumPrecompilesRemaining() <= 0?

This could be due to several factors. Do you have an Insights trace for these logs? It might be easier to tell from them when and why the PSO failed to compile in time.

For certain SMs in the level we force their last LOD during gameplay which contains their own material which are not precached. Does PSO precaching not account for all LOD levels of the static meshes in the level?

We should be precaching the materials for all LoDs (see FStaticMeshComponentHelper::CollectPSOPrecacheDataImp line 209).

We get several Landscape Material Instances misses, but shouldn’t PSO precaching catch them as they are part of the level, or is the landscape not supported with precaching?

It’s tough to tell why your Landscape MIs got missed there, but you can debug the misses by setting r.PSOPrecache.BreakOnMaterialName=<Material Name> and r.PSOPrecache.Set UseBackgroundThreadForCollection=0and run your game with a debugger attached. That should give you a call stack that goes up to the Landscape Component level, which can help you verify which PSOPrecacheParamData and subsequently.

When we trigger chaos destruction (GeometryCollection) we get misses for WorldGridMaterial, even though we are not using it and have no references to it. Is this behavior expected?

We use WorldGridMaterial as the default material for passes that don’t require material evaluation. In your case, this is the CSMShadowDepth pass. It’s strange that it is missed here, since I know we tend to compile that first as part of global shaders precaching. Do you have precaching of global shaders enabled in your project?

In the loaded level we have translucent materials assigned to Static Meshes and they will always miss, even after enabling r.PSOPrecache.TranslucencyAllPass 1. Isn’t this cvar supposed to deal with those cases? It’s also interesting that in mobile devices, these same materials will have PassName = Unknown.

If you are referring to your last miss in the logs, it says that the mesh pass processor does not support PSO precaching, so yes, that is expected. Do you have separate translucency enabled? There is a comment in MobileBassePass::CollectPSOInitializers about this around line 1095.

[Attachment Removed]