Performance problem about "createShaderCacheEntry"

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Post Reply
yisky
Gnoblar
Posts: 14
Joined: Tue Sep 17, 2013 12:06 pm

Performance problem about "createShaderCacheEntry"

Post by yisky »

Hi!

In Ogre 2.1 I use "HlmsPbs" to render models and I meet a performance problem that when ogre first time rendering an object, it will dynamically create shader through "createShaderCacheEntry", and I found that this function takes a little more time which low down the frame. Btw, I create mesh in background thread as this viewtopic.php?f=25&t=94764&p=543982#p543982 topic mentioned.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: Performance problem about "createShaderCacheEntry"

Post by dark_sylinc »

Hi!

You need to use the microcode cache so the shaders are saved to disk so the next time it is used, it won't cause a stutter. You can also use the HlmsDiskCache which complements it. See Starting my app takes forever! in the FAQ.

Recently this code was added to the samples to handle it. See GraphicsSystem::loadHlmsDiskCache and GraphicsSystem::saveHlmsDiskCache.

Cheers
yisky
Gnoblar
Posts: 14
Joined: Tue Sep 17, 2013 12:06 pm

Re: Performance problem about "createShaderCacheEntry"

Post by yisky »

Hi!
Thanks for your reply, I start to use the microcode cache and it works well. But there is still a problem confiuse me that how to handle lots of texture in Ogre 2.1. Currently, I use Image::load to load texutre in background thread and then pass the loaded image to HlmsTextureManager::createOrRetrieveTexture to create texture in main thread, but this still causes a stutter.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: Performance problem about "createShaderCacheEntry"

Post by dark_sylinc »

Creating a texture has multiple stages:

1. Loading from file (you're using Image for that in a worker thread)
2. Creating the internal GPU API handle/resource. This could cause a mini-stutter (that can add up). If the texture is a power of 2, it will be placed in a texture array. So if the texture array had already been created and has free available space, then this cost won't be paid.
3. Some preprocessing stuff. In certain cases Image::generateMipmaps or PixelUtil::convertForNormalMapping may end up getting called while inside HlmsTextureManager::createOrRetrieve. If you want to avoid stutter, make sure these are not getting called (i.e. mipmaps were already set, and format was already ideal for normal mapping).
4. Uploading from Image to the GPU RAM. This could take time (not much, but adds up).
5. Sometimes a shader needs to be recompiled. If it's cached, it's not a problem, but if it's new, it will add stutter. To minimize this issue if textures are loaded in the same order every time, it will maximize the cache efficiency (so that they always arrive in the same pool of texture arrays); if you can't do this, then it's just a matter of time until the cache has seen all variants.

There's little you can do for point 2, however you should monitor your texture batching efficiency.
You can do a lot for step 3.
There's not much you can do for step 4 (in Ogre 2.2 this also happens in a background thread, but in 2.1 it happens in the main thread)
As for step 5, that depends on your design.

If you're using D3D11, another issue that causes stutter is that texture uploads call 3D11RenderSystem::_clearStateAndFlushCommandBuffer because on NVIDIA drivers it is prone to OoM (Out of Memory situations), particularly 32-bit builds. But if you remove that call and it still works fine for you on NVIDIA cards, then you may see a boost in texture loading time.

Cheers
Matias
yisky
Gnoblar
Posts: 14
Joined: Tue Sep 17, 2013 12:06 pm

Re: Performance problem about "createShaderCacheEntry"

Post by yisky »

Thank you very much! I will try as you say!
yisky
Gnoblar
Posts: 14
Joined: Tue Sep 17, 2013 12:06 pm

Re: Performance problem about "createShaderCacheEntry"

Post by yisky »

dark_sylinc wrote: Wed Jan 23, 2019 3:52 am Creating a texture has multiple stages:

1. Loading from file (you're using Image for that in a worker thread)
2. Creating the internal GPU API handle/resource. This could cause a mini-stutter (that can add up). If the texture is a power of 2, it will be placed in a texture array. So if the texture array had already been created and has free available space, then this cost won't be paid.
3. Some preprocessing stuff. In certain cases Image::generateMipmaps or PixelUtil::convertForNormalMapping may end up getting called while inside HlmsTextureManager::createOrRetrieve. If you want to avoid stutter, make sure these are not getting called (i.e. mipmaps were already set, and format was already ideal for normal mapping).
4. Uploading from Image to the GPU RAM. This could take time (not much, but adds up).
5. Sometimes a shader needs to be recompiled. If it's cached, it's not a problem, but if it's new, it will add stutter. To minimize this issue if textures are loaded in the same order every time, it will maximize the cache efficiency (so that they always arrive in the same pool of texture arrays); if you can't do this, then it's just a matter of time until the cache has seen all variants.

There's little you can do for point 2, however you should monitor your texture batching efficiency.
You can do a lot for step 3.
There's not much you can do for step 4 (in Ogre 2.2 this also happens in a background thread, but in 2.1 it happens in the main thread)
As for step 5, that depends on your design.

If you're using D3D11, another issue that causes stutter is that texture uploads call 3D11RenderSystem::_clearStateAndFlushCommandBuffer because on NVIDIA drivers it is prone to OoM (Out of Memory situations), particularly 32-bit builds. But if you remove that call and it still works fine for you on NVIDIA cards, then you may see a boost in texture loading time.

Cheers
Matias
Sorry to trouble again! I had to call Image::generateMinmaps out the HlmsTextureManager::createOrRetrieve in a background thread and this improves the performance. But, I got an exception:
"OGRE EXCEPTION(3:RenderingAPIException): D3D11 device cannot Clear State
Error Description:ID3D11DeviceContext::Map: First parameter is corrupt or NULL. in D3D11RenderSystem::_setRenderTarget...."

And this exception does not happen every time.
Post Reply