TStateArrayMonitor用于监视多slot的状态,我们可以最小化需要更新的slot状态,如Constant Buffer
TStateMonitor用于监视单状态 ,如shader program , rasterizer state等(每个阶段最多只能设置一个shader , rasterizer state也只能设置一个)
template< typename T >
class TStateMonitor
{
public:
void SetSister(TStateMonitor* pSister);
bool SameSister();
void SetState(T state);
T GetState() const;
bool IsUpdateNeeded();
void InitializeState();
void ResetTracking();
private:
bool m_UpdateNeed;
T m_InitializeState;
T m_State;
TStateMonitor* m_Sister;
}
m_UpdateNeed表示该对象是否需要更新(即该对象所表示的状态是否需要更新)
m_InitializeState:初始状态
m_State:目前状态
通过我们将Current State设为Desired State的m_Sister
Current State是目前的状态,Desired State是下一帧要使用的状态
我们可以通过对比二者,判断该状态是否发生了改变。
SetSister状态一般会在ShaderState对象创建时就调用。使得该阶段的所有状态变化都能及时捕捉到。
template<typename T , int N>
class TStateArrayMonitor
{
public:
void SetSister(TStateArrayMonitro* pSister);
// 索引为slot的通道的状态与之前是否一致
// 或者说是否发生了改变,未改变,则为true
bool SameSister(int slot);
// 为索引为slot的通道设置状态
void SetState(int slot , T State);
// 若N个slot的通道的状态,有任何一个发生了改变,
// 则返回true
bool IsUpdateNeeded();
// 用于获取状态发生改变的slot通道的范围
// 以及区间起点与区间终点
int GetStartSlot();
int GetEndSlot();
int GetRange();
// 用于获取指定slot通道的状态
T GetState(int slot) const;
T* GetFistSlotLocation();
T* GetSlotLocation();
void InitializeStates();
void ResetTracking();
private:
void SearchFromBelow();
void SearchFromAbove();
// 状态发生更改的slot范围
int m_uiStartSlot;
int m_uiEndSlot;
// 是否需要更新
// N个slot通道,单凡有一个通道的状态发生了改变
// 该值就为true
bool m_UpdateNeeded;
// 初始状态
// 可以用于清除状态,使之回到初始状态
//
T m_InitializeState;
// 目前的状态
T m_State[N];
// Current State对应的状态
// 用于我们判断到我们设置的状态与上一帧状态对比是否改变
TStateArrayMonitor m_Sister;
}
对于可编程阶段而言,需要设置的资源或状态无非以下几种:
shader object
constant buffer object
sampler state
shader resource view
unordered access view
shaderStateState封装了shader stage需要监视的主要状态和资源
class ShaderStateStage
{
public:
void SetFeatureLevel(D3D_FEATURE_LEVEL level);
// 清除该shader stage的所有状态,资源
void ClearState();
void SetSisterState(ShaderStageState* pSister);
// 该shader stage的所有状态,资源都重置为不更新
// 即更新区间重置为0,m_UpdateNeed为false
void ResetUpdateFlags();
public:
// shader stage需要监视的资源或者状态
TStateMonitor<int> shaderPrograms;
TStateArrayMonitor ConstantBuffers;
TStateArrayMonitor Samplers;
TStateArrayMonitor ShaderResourceViews;
TStateArraMonitor UnorderedAccessViews;
TStateArrayMonitor<int , D3D11_PS_CS_UAV_REGISTER_COUNT> UAVInitialCount;
private:
D3D_FEATURE_LEVEL m_FeatureLevel;
ShaderStageState* m_pSisterState;
}
各可编程阶段的基类。用于绑定shader object , 资源到相应的阶段
class ShaderStage
{
public:
void SetFeatureLevel(D3D_FEATURE_LEVEL FeatureLevel);
void ClearCurrentState();
void ClearDesiredState();
// 将Desired State应用到当前shader stage
void ApplyDesiredState(ID3D11DeviceContext* pContext);
// 绑定资源
virtual void BindConstantBuffer(ID3D11DeviceContext* pContext) = 0;
virtual void BindShaderProgram(ID3D11DeviceContext* pContext) = 0;
virtual void BindSamplerState(ID3D11DeviceContext* pContext) = 0;
virtual void BindShaderResourceView(ID3D11DeviceContext* pContext) = 0;
virtual void BindUnorderedAccessView(ID3D11DeviceContext* pContext) = 0;
virtual ShaderType GetType() = 0;
ShaderStageState DesiredState;
protected:
D3D_FEATURE_LEVEL m_FeatureLevel;
ShaderStageState CurrentState;
};
继承自Shader Stage,将基类的纯虚函数实现了一遍
class VertexStage : ShaderStage
{
protected:
virtual ShaderType GetType();
virtual void BindShaderProgram(ID3D11DeviceContext* pContext);
virtual void BindSamplerState(ID3D11DeviceContext* pContext);
virtual void BindShaderResourceView(ID3D11DeviceContext* pContext);
virtual void BindUnorderedAccessView(ID3D11DeviceContexet* pContext);
virtual void BindConstantBuffer(ID3D11DeviceContext* pContext);
}
class HullStage : ShaderStage
{
protected:
virtual ShaderType GetType();
virtual void BindShaderProgram(ID3D11DeviceContext* pContext);
virtual void BindSamplerState(ID3D11DeviceContext* pContext);
virtual void BindShaderResourceView(ID3D11DeviceContext* pContext);
virtual void BindUnorderedAccessView(ID3D11DeviceContext* pContext);
virtual void BindConstantBuffer(ID3D11DeviceContext* pContext);
}
略
略
略
略
以Vertex Stage为例,给出实现:
ShaderType VertexStage::GetType()
{
return VERTEX_SHADER;
}
void VertexStage::BindShaderProgram(ID3D11DeviceContext* pContext)
{
// 获取渲染器对象
Renderer* pRenderer = Renderer::Get();
// 获取shader基类对象
ShaderDX11* pShader = pRenderer->GetShader(DesiredState.ShaderPrograms.GetState());
ID3D11VertexShader* pVertexShader = nullptr;
if(pShader)
{
pVertexShader = reinterpret_cast(pShader)->GetResource();
}
pContext->VSSetShader(pVertexShader , nullptr , 0);
}
void VertexStage::BindShaderResourceView(ID3D11DeviceContext* pContext)
{
pContext->VSSetShaderResource(DesiredState.ShaderResourceViews.GetStartSlot() , DesiredState.ShaderResourceViews.GetRange() , DesiredState.ShaderResourceViews.GetFirstSlotLocation());
}
...
初始化通常是这样的:
class PipelineManager
{
ShaderStage* m_ShaderStage[6];
VertexStage m_VertexStage;
HullStage m_HullStage;
DomainStage m_DomainStage;
GeometryStage m_GeometryStage;
PixelStage m_PixelStage;
ComputeStage m_ComputeStage;
}
并且在PipelineManager的构造函数中实现如下操作:
PipelineManager::PipelineManager()
{
...
m_ShaderStage[VERTEX_SHADER] = &m_VertexStage;
m_ShaderStage[HULL_SHADER] = &m_HullStage;
m_ShaderStage[DOMAIN_SHADER] = &m_DomainStage;
m_ShaderStage[GEOMETRY_SHADER] = &m_GeometryStage;
m_ShaderStage[PIXEL_SHADER] = &m_PixelStage;
m_ShaderStage[COMPUTE_SHADER] = &m_ComputeStage;
}
Input Assembler Stage需要绑定的资源,状态为:Index Buffer , Vertex Buffer , InputLayout , PrimitiveTopology
Vertex Buffer可以绑定在多个slot上,我们需要监视每个slot上的变化
class InputAssemblerStageState
{
public:
//-------------------data member-------------------
// Index Buffer
TStateMonitor<int> IndexBufferCounts;
TStateMonitor<int> IndexBuffers;
// Vertex buffer
TStateArrayMonitor<int , D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> VertexBuffers;
TStateArrayMonitor<unsigned int , D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> VertexBufferStrides;
TStateArrayMonitor<unsigned int , D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> VertexBufferOffsets;
// Input Layouts
TStateMonitor<int> InputLayout;
// primitive topology
TStateMonitor<int> PrimitiveTopology;
}
该阶段需要绑定的资源或状态:ViewPort , ScissorRect , RasterizerState
ViewPort和ScissorRect可以绑定多个slot
class RasterzierStageState
{
public:
//-------------------data member------------------
// rasterizer state
TStateMonitor<int> RasterizerState;
// view port
TStateMonitor<int> ViewPorts;
TStateArrayMonitor<int , D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE> ViewPorts;
// Scissor Rect
TStateMonitor<int> ScissorRectCount;
TStateArrayMonitor ScissorRects;
}
该阶段需要绑定的是:Buffer
可以绑定在多个slot
class StreamOutStageState
{
public:
//----------------data member---------------
TStateMonitor<int> StreamBufferCount;
TStateArrayMonitor<unsigned int , 4> StreamOffsets;
}
该阶段可以绑定:Blend State , DepthStencilState , RenderTargetView , DepthStencilView , UnorderedAccessView
设置DpethStencilState还需要设置StencilRef
RenderTargetView , UnorederedAccessView可以绑定在多个slot
class OutputMergerStageState
{
public:
//------------------data member-----------------
// blend state
TStateMonitor<int> BlendState;
// depth stencil state
TStateMonitor<int> DepthStencilState;
TStateMonitor<unsigned int> StencilRef;
// Render Target View
TStateArrayMonitor<int , D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> RenderTargetViews;
// Depth Stencil View
TStateMonitor<int> DepthStencilViews;
// Unordered Access View
TStateArrayMonitor<int , D3D11_PS_CS_UAV_REGISTER_COUNT> UnorderedAccessViews;
TStateArrayMonitor<unsigned int , D3D11_PS_CS_UAV_REGISTER_COUNT> UAVInitialCounts;
}