The API introduces a wrapper for the concept of state blocks. Those using DirectX will be familiar with this concept already, but this could be something new for to those using OpenGL, especially for those using older version of this interface.
State blocks are logical groupings of state changes. Once created, these blocks are assumed to be immutable GPU resources.
GPU state blocks are reflected in the API via the following classes
As with other GPU resources, they are managed by the resource management system. The API interface for these resources is an MStateManager.
The process for using a state block is as follows:
The following diagram shows the logical connections between state and the overall rendering context. Blending is a property of a color target; depth and stencil state is a property of a depth+stencil target stage; sampling is a property per shader stage; and rasterization is a render context property.
Figure 33: Two blend states are shown for two different color targets and a depth+stencil state is shown for a depth+stencil target. Each shader could have a different sampler state and there is a per context rasterization state relationship.
The following is a simple code example to create a state block to perform alpha blending which is commonly done to render transparency. It demonstrates the first approach of creating a state block from scratch.
// Create a new blend state descriptor. Set it to be (alpha, 1-alpha) blending and enable // blending. MHWRender::MBlendStateDesc desc; unsigned int i=0; // Set state for first render target desc.targetBlends[i].blendEnable = true; desc.targetBlends[i].destinationBlend = MHWRender::MBlendState::kSourceAlpha; desc.targetBlends[i].alphaDestinationBlend = MHWRender::MBlendState::kInvSourceAlpha; desc.targetBlends[i] blendOperation = MHWRender::MBlendState::kAdd; desc.targetBlends[i].alphaSourceBlend = MHWRender::MBlendState::kOne; desc.targetBlends[i].alphaDestinationBlend = MHWRender::MBlendState::kInvSourceAlpha; desc.targetBlends[i].alphaBlendOperation = MHWRender::MBlendState::kAdd; // Use the state manager to acquire a new blend state and then enable it. MHWRender::MStateManager* stateMgr; const MHWRender::MBlendState* blendState = stateMgr->acquireBlendState(desc); stateMgr->setBlendState(blendState);
Though it is not necessary to use this API to control the state, the interface has a number of advantages due to the tight integration with the rendering framework. This includes:
Though these instances are easy to create and hold on to, it is recommended that due to the inherent performance cost on the GPU:
Any plug-ins which change state must follow the guideline that the previous state must be restored after the plug-in is finished drawing. This is due to the fact that state is persistent.
A resource handle can be retrieved when using DirectX11 as real GPU resources exist. They can be used as read-only resources – they should never be modified as the resource manager would not know of what has changed. For example an ID3D11RasterizerState could be retrieved from an MRasterizerState using its resourceHandle() method.