OGRE-Next  4.0.0unstable
Object-Oriented Graphics Rendering Engine
Ogre::PsoCacheHelper Class Reference

Utility class to cache PSOs. More...

#include <OgrePsoCacheHelper.h>

+ Inheritance diagram for Ogre::PsoCacheHelper:

Public Member Functions

 PsoCacheHelper (RenderSystem *renderSystem)
 
 ~PsoCacheHelper ()
 
void clearState ()
 
HlmsPsogetPso ()
 Returns an HlmsPso you can set via renderSystem->_setPipelineStateObject based on all past calls to setRenderTarget + setVertexFormat + setMacroblock + etc. More...
 
HlmsPsogetPso (uint32 renderableHash, bool renderableCacheAlreadySet=false)
 Returns an HlmsPso you can set via renderSystem->_setPipelineStateObject based on the input hash calculated via getRenderableHash. More...
 
uint32 getRenderableHash ()
 Returns a hash value you can cache into a Renderable (or whatever you're rendering). More...
 
void setBlendblock (const HlmsBlendblock *blendblock)
 Calls to this function cannot be skipped unless you have a renderableHash. More...
 
void setMacroblock (const HlmsMacroblock *macroblock)
 Calls to this function cannot be skipped unless you have a renderableHash. More...
 
void setPixelShader (GpuProgramPtr &shader)
 Calls to this function can be skipped if it's valid to not have a shader set at this stage, or if you have a renderableHash. More...
 
void setRenderTarget (const RenderPassDescriptor *renderPassDesc)
 You must call this function every frame, and every time the RenderTarget changes. More...
 
void setVertexFormat (const VertexElement2VecVec &vertexElements, OperationType operationType, bool enablePrimitiveRestart)
 This function can be skipped if no vertex buffer is used (e.g. More...
 
void setVertexShader (GpuProgramPtr &shader)
 Calls to this function can be skipped if it's valid to not have a shader set at this stage, or if you have a renderableHash. More...
 

Detailed Description

Utility class to cache PSOs.

Useful for porting v1 libraries (eg. Gorilla) that render in "immediate mode" style and weren't build with PSOs in mind. Ideally a PSO would be created ahead of time and its pointer stored alongside the renderable you need to render.

Almost all functions already do redundant state checking unless explicitly stated, thus there is no need for you to do it yourself.
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 ); } } }

Usage "MUCH better": PsoCacheHelper psoCache( renderSystem ); //Save this variable (i.e. per class)

Outside rendering, just ONCE at loading time or when the material changes (or the vertex layout changes): psoCache.clearState(); 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 );

renderables[j].customSavedValue = psoCache.getRenderableHash(); }

During render: void render() { psoCache.clearState(); setRenderTarget still needs to be called. psoCache.setRenderTarget( renderTarget ); for( int i=0; i<numMaterials; ++i ) { for( int j=0; j<numThingsToRenderPerMaterial; ++j ) { HlmsPso *pso = psoCache.getPso( renderables[j].customSavedValue ); renderSystem->_setPipelineStateObject( pso ); } } }

Constructor & Destructor Documentation

◆ PsoCacheHelper()

Ogre::PsoCacheHelper::PsoCacheHelper ( RenderSystem renderSystem)

◆ ~PsoCacheHelper()

Ogre::PsoCacheHelper::~PsoCacheHelper ( )

Member Function Documentation

◆ clearState()

void Ogre::PsoCacheHelper::clearState ( )

◆ getPso() [1/2]

HlmsPso* Ogre::PsoCacheHelper::getPso ( )

Returns an HlmsPso you can set via renderSystem->_setPipelineStateObject based on all past calls to setRenderTarget + setVertexFormat + setMacroblock + etc.

Use this version if for architecture reasons (i.e. legacy code, time constraints) you can't store the hash at loading time into the Renderable for later reuse.

Returns
The HlmsPso to use. Do NOT persistently store this pointer. It may be invalidated if the next getPso call needs to create a new PSO.

◆ getPso() [2/2]

HlmsPso* Ogre::PsoCacheHelper::getPso ( uint32  renderableHash,
bool  renderableCacheAlreadySet = false 
)

Returns an HlmsPso you can set via renderSystem->_setPipelineStateObject based on the input hash calculated via getRenderableHash.

Remarks
Don't call getRenderableHash for every object every frame and then this function. That's inefficient. If you can't save the hash at loading time / when materials are set, just call the other getPso overload directly.
Parameters
renderableHashThe hash obtained from getRenderableHash which you should've saved in the Renderable.
renderableCacheAlreadySetInternal parameter. Leave the default. Used by the other getPso overload to tell there is no need to perform a linear O(N) search in mRenderableCache because mCurrentState is up to date (this search only happens if the PSO hadn't been already cached).
Returns
The HlmsPso to use. Do NOT persistently store this pointer. It may be invalidated if the next getPso call needs to create a new PSO.

◆ getRenderableHash()

uint32 Ogre::PsoCacheHelper::getRenderableHash ( )

Returns a hash value you can cache into a Renderable (or whatever you're rendering).

This hash will contain VertexFormat, Macroblock, Blendblock information and shaders set, but nothing that is part of the pass (RenderTargets attached, RTT formats, stencil parameters, etc). You would later insert this value to getPso( renderableHash ); See examples in the class description.

Remarks
The hash is deterministic, but depends on the order in which they're created. The hash is immune to collisions (unless you overflow 2^RenderableBits).
Do NOT call this function every frame per object. The goal is that you only call this function when the object is being loaded (i.e. once) or when the object has changed (e.g. new material, vertex definition information was changed).
If you can't perform this optimization, just set every state for every object every frame (like in the first example) and call getPso.
Returns
The hash containing all the information.

◆ setBlendblock()

void Ogre::PsoCacheHelper::setBlendblock ( const HlmsBlendblock blendblock)

Calls to this function cannot be skipped unless you have a renderableHash.

◆ setMacroblock()

void Ogre::PsoCacheHelper::setMacroblock ( const HlmsMacroblock macroblock)

Calls to this function cannot be skipped unless you have a renderableHash.

◆ setPixelShader()

void Ogre::PsoCacheHelper::setPixelShader ( GpuProgramPtr shader)

Calls to this function can be skipped if it's valid to not have a shader set at this stage, or if you have a renderableHash.

◆ setRenderTarget()

void Ogre::PsoCacheHelper::setRenderTarget ( const RenderPassDescriptor renderPassDesc)

You must call this function every frame, and every time the RenderTarget changes.

Remarks
Warning: This function will not check for redundant state changes (there's a lot that could've changed: stencil settings, depth buffer, etc)

This function is a PASS state changing function, and its information is not part of getRenderableHash.

◆ setVertexFormat()

void Ogre::PsoCacheHelper::setVertexFormat ( const VertexElement2VecVec vertexElements,
OperationType  operationType,
bool  enablePrimitiveRestart 
)

This function can be skipped if no vertex buffer is used (e.g.

you use gl_VertexID or other trickery) or if you have a renderableHash.

◆ setVertexShader()

void Ogre::PsoCacheHelper::setVertexShader ( GpuProgramPtr shader)

Calls to this function can be skipped if it's valid to not have a shader set at this stage, or if you have a renderableHash.


The documentation for this class was generated from the following file: