Shader load has waiting by BamCache in async model load


I am trying to load model asynchronously in Render Pipeline. (I enabled thread-support)
However, while models are loading, a screen has freeze until the load is finished.

I found the waiting is caused by locking in BamCache::lookup when a GLSL shader is loaded.
So, if the models are loading after Render Pipeline is initialized completely, then the waiting is gone.
Also, if I use noCache option when loading, it is gone.

I want to fix this issue properly. What approach is better?

  1. Developers should be care about this?
  • Separate model loading and shader loading
  • OR, use noCache option
  1. Fix the locking? (this needs to patch Panda3D)
  • Use another lock for each file extension
  • OR, fix the locking perfectly (very hard…)

p.s. I wonder the cache is very useful for Bam model files.
I know it is very useful and effective for egg files, but I don’t know about Bam files.
If it is not very effective, then I will try to use noCache option.

If I understand you correctly, the problem is that BamCache::lookup is taking significant time to complete, and blocking other threads from accessing the BamCache?

One solution that comes to mind is simply side-stepping the issue by doing the shader loading asynchronously as well, so that it is done on the loader thread as well, so there won’t be contention. We don’t currently support async shader loading at present, but we probably should.

Having a separate BamCache per resource type (ie. shader or model) is not an entirely bad idea, although it is an incomplete solution since it could still cause contention when loading two resources of the same type on different threads.

The most ideal approach in my mind is to reengineer the BamCache not to hold the lock while reading the files, but this would be somewhat complex since it would need to take into account any changes to the cache that occur while the file is being read from disk.

All that said, you’re right that the model-cache is not terribly useful when loading .bam files. Note that noCache disables both the on-disk and in-memory cache—you can disable only the on-disk cache specifically using something like:

# Disable the disk cache
opts = LoaderOptions()
opts.flags |= LoaderOptions.LF_no_disk_cache

# Now load the model using either asynchronous mechanism
model = await loader.loadModel(..., loaderOptions=opts, blocking=False)
loader.loadModel(..., loaderOptions=opts, callback=myCallback)

Thank you very much for details and about no_disk_cache.

I thought solving the blocking is not easy.
So, I decided to use a little delay to load the models with no_disk_cache.