i'm currently looking at the CEGUI-OgreRenderer and dedected problem with PsoCacheHelper (i'm using Ogre 2.1 branch but i have not found any updates to it in later branches which could solve this issue).
CEGUI uses the PsoCacheHelper like in the example in OgrePsoCacheHelper.h:
Code: Select all
Usage (example) "OK":
PsoCacheHelper psoCache( renderSystem ); //Save this variable (i.e. per class)
void render()
{
psoCache.clearState();
psoCache.setRenderTarget( renderTarget );
for( int i=0; i<numMaterials; ++i )
{
psoCache.setMacroblock( material[i].macroblock );
psoCache.setBlendblock( material[i].blendblock );
psoCache.setVertexShader( material[i].vertexShader );
psoCache.setPixelShader( material[i].pixelShader );
for( int j=0; j<numThingsToRenderPerMaterial; ++j )
{
v1::RenderOperation renderOp = renderables[j].renderOp;
//Consider caching 'vertexElements' somewhere as
//convertToV2 involves allocations
VertexElement2VecVec vertexElements = renderOp.vertexData->
vertexDeclaration->convertToV2();
psoCache.setVertexFormat( vertexElements,
renderOp.operationType,
enablePrimitiveRestart );
HlmsPso *pso = psoCache.getPso();
renderSystem->_setPipelineStateObject( pso );
}
}
}
"uint32 PsoCacheHelper::getRenderableHash(void)" fails to find an already used "setting/state" and incorrectly creates a new entry.
After some runtime of the application this issue causes an extremly large amount of pso created and cached, causing an extreme slowdown and in the end a crash of the application because the memory is full.
If i update "getRenderableHash" as following the issue seams to be solved and only in total 1 entry in mRenderableCache is created during runtime:
Code: Select all
uint32 PsoCacheHelper::getRenderableHash(void)
{
RenderableCacheEntry entry;
entry.psoRenderableKey = mCurrentState;
RenderableCacheEntryVec::iterator itor;
for(itor = mRenderableCache.begin(); itor != mRenderableCache.end(); ++itor)
{
if(entry.psoRenderableKey.equalExcludePassData(itor->psoRenderableKey))
return itor->hashToMainCache;
}
//nothing found in cache, create new entry
entry.hashToMainCache = mRenderableHashCounter++;
const size_t idx = itor - mRenderableCache.begin();
mRenderableCache.insert(itor, 1u, entry);
itor = mRenderableCache.begin() + idx;
return itor->hashToMainCache;
}
Code: Select all
uint32 PsoCacheHelper::getRenderableHash(void)
{
RenderableCacheEntry entry;
entry.psoRenderableKey = mCurrentState;
RenderableCacheEntryVec::iterator itor = std::lower_bound( mRenderableCache.begin(),
mRenderableCache.end(), entry );
if(itor == mRenderableCache.end() ||
itor->psoRenderableKey.equalExcludePassData(entry.psoRenderableKey))
{
entry.hashToMainCache = mRenderableHashCounter++;
const size_t idx = itor - mRenderableCache.begin();
mRenderableCache.insert(itor, 1u, entry);
itor = mRenderableCache.begin() + idx;
}
return itor->hashToMainCache;
}
Any idea? Have i missed a later fix for this which can be back-ported? or is this really a bug?