Shader Stage

Programmable Stage

State

TStateMonitor , TStateArrayMonitor

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;

}

ShaderStageState

对于可编程阶段而言,需要设置的资源或状态无非以下几种:
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 Stage

各可编程阶段的基类。用于绑定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;
};

Vertex Stage

继承自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);

}

Hull Stage

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);
}

Domain Stage

Geometry Stage

Pixel Stage

Compute Stage

以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;
}

Fixed Stage

Input Assembler Stage

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;

}

Rasterizer Stage

该阶段需要绑定的资源或状态: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;
}

Stream Out Stage

该阶段需要绑定的是:Buffer
可以绑定在多个slot

class StreamOutStageState
{
public:
    //----------------data member---------------
    TStateMonitor<int> StreamBufferCount;
    TStateArrayMonitor<unsigned int , 4> StreamOffsets;
}

Output Merger Stage

该阶段可以绑定: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;

}

你可能感兴趣的:(Hieroglyph)