Pipeline System - Shader Reflection

前端之家收集整理的这篇文章主要介绍了Pipeline System - Shader Reflection前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Shader Reflection

Shader的信息可以通过轮询ID3D11ShaderReflection接口获取,该接口也可以获取用于轮询Constant Buffer,Variable,Type信息的接口。通过D3DReflect()函数可以从shader获取其ID3D11ShaderReflection接口

以下为从shader中获取ID3D11ShaderReflection的方法

  1. ID3DBlob* pCompiledShader;
  2.  
  3. // call D3DCompile Compile Shader
  4. ...
  5.  
  6. Microsoft::WRL::ComPtr<ID3D11ShaderReflection> pReflector;
  7.  
  8. D3DReflect(pCompiledShader->GetBufferPointer(),pCompiledShader->GetBufferSize(),IID_ID3D11ShaderReflection,reinterpret_cast<void**>(pReflector.GetAddressOf()));

我们可以通过该接口获取D3D11_SHADER_DESC,该结构体用于描述shader
其成员ConstantBuffes表示shader constant buffer数目,InputParameters,OutputParameters,BoundResources分别描述了输入签名数,输出签名数,shader绑定资源数。

获取D3D11_SHADER_DESC结构体方法如下:

  1. D3D11_SHADRE_DESC ShaderDesc;
  2. pReflector->GetDesc(&ShaderDesc);

Input Signature

我们可以通过ID3D11ShaderReflection调用GetInputParameterDesc()获取shader的输入参数描述
原型如下:

  1. HRESULT GetInputParameterDesc(
  2. [in] int ParameterIndex,[out] D3D11_SIGNATURE_PARAMETER_DESC *pDesc
  3. );

因此我们可以获取shader所有的输入描述

  1. // 用于保存输入参数描述
  2. std::vector<D3D11_SIGNATURE_PARAMETER_DESC> InputSignatures;
  3. for(int i = 0; i < ShaderDesc.InputParameters; i++)
  4. {
  5. D3D11_SIGNATURE_PARAMETER_DESC InputDesc;
  6. pReflector->GetInputParameterDesc(i,&InputDesc);
  7. InputSignatures.push_back(InputDesc);
  8. }

Output Signature

与InputSignature类似,我们可以通过GetOutputParameterDesc()获取shader的输出参数描述。
函数原型如下:

  1. HRESULT GetOutputParameterDesc(
  2. [in] UINT ParameterIndex,[out] D3D11_SIGNATURE_PARAMETER_DESC *pDesc
  3. );

因此我们可以获取shader所有的输出描述

  1. // 保存shader所有的输出描述
  2. std::vector<D3D11_SIGNATURE_PARAMETER_DESC> OutputSignatures;
  3. for(int i = 0; i < ShaderDesc.OutputParameters; i++)
  4. {
  5. D3D11_SIGNATURE_PARAMETER_DESC OutputDesc;
  6. pReflector->GetOutputParameterDesc(i,&OutputDesc);
  7. OutputSignatures.push_back(OutputDesc);
  8. }

Constant Buffer

ID3D11ShaderReflection接口还可以获取ID3D11ShaderReflectionConstantBuffer接口,该接口包含shader的constant buffer的信息,该接口可以通过调用GetConstantBufferByName()或者GetConstantBufferByIndex()获取

我们可以通过如下方式获取shader中constant buffer的信息

  1. // ConstantBuffers保存所有的Constant Buffer描述
  2. for(int i = 0; i < ShaderDesc.ConstantBuffers; i++)
  3. {
  4. ID3D11ShaderReflectionConstantBuffer* pCBReflecion = nullptr;
  5. pCBReflection = pReflector->GetConstantBufferByIndex(i);
  6.  
  7. D3D11_SHADER_BUFFER_DESC ShaderBuferDesc;
  8. pCBReflection->GetDesc(&ShaderBufferDesc);
  9.  
  10. if(ShaderBufferDesc.Type == D3D_CT_CBUFFER || ShaderBufferDesc.Type == D3D_CT_TBUFFER)
  11. {
  12. ConstantBuffers.push_back(ShaderBufferDesc);
  13.  
  14. // 查询constant buffer接口信息
  15. ...
  16. }
  17. }

ID3D11ShaderReflectionConstantBuffer接口也提供一个GetDesc() 方法,该方法返回一个包含constant buffer信息的结构体,结构体为D3D11_SHADER_BUFFE_DESC,声明如下:

  1. typedef struct D3D11_SHADER_BUFFER_DESC
  2. {
  3. LPCSTR Name;
  4. D3D_CBUFFER_TYPE Type;
  5. UINT Variables;
  6. UINT Size;
  7. UINT uFlags;
  8.  
  9. }D3D11_SHADER_BUFFER_DESC;

我们感兴趣的部分主要是Size和Variables,Size表示Constant Buffer的总大小,可以用于初始化ID3D11ConstantBuffer,Variables表示Constant Buffer中常量数,Variables结合GetVariableByIndex可以枚举constant buffer中的所有常量

Variable

ID3D11ShaderReflectionVariable接口包含了Constant Buffer中Constant的信息,该接口可以由ID3D11ShaderReflectionConstantBuffer接口调用GetVariableByName()或者GetVariableByIndex()获取,ID3D11ShaderReflection接口调用GetVariableByName()或者GetVariableByIndex()可以获取shader中的全局变量全局变量不仅包含constants,而且还有resource object , samplers , interface instance。ID3D11ShaderReflectionVariable接口的GetDesc()方法返回一个D3D11_SHADER_VARIABLE_DESC结构体。该结构体包含变量的总说明。

  1. typedef struct D3D11_SHADER_VARIABLE_DESC
  2. {
  3. LPCSTR Name;
  4. UINT StartOffset;
  5. UINT Size;
  6. UINT uFlags;
  7. LPVOID DefaultValue;
  8. UINT StartTexture;
  9. UINT TextureSize;
  10. UINT StartSampler;
  11. UINT SamplerSize;
  12. }D3D11_SHADER_VARIABLE_DESC;

Name为HLSL中变量的名字,StartOffset,Size包含了Constant Buffer开始出的字节偏移和该值的字节大小。

Type

ID3D11ShaderReflectionType接口包含了变量的类型信息,可以由变量的ID3D11ShaderReflectionVariable接口调用GetType()得到。调用该接口的GetDesc方法将会返回一个结构体D3D11_SHADER_TYPE_DESC

  1. typedef struct D3D11_SHADER_TYPE_DESC
  2. {
  3. D3D_SHADER_VARIABLE_CLASS Class;
  4. D3D_SHADER_VARIABLE_TYPE Type;
  5. UINT Rows;
  6. UINT Columns;
  7. UINT Elements;
  8. UINT Members;
  9. UINT Offset;
  10. LPCSTR Name;
  11. }D3D11_SHADER_TYPE_DESC;

该结构体的Class成员表明了该变量是个标量,向量,矩阵,资源对象,结构体,类或者接口指针。Type成员指明了标量,向量,矩阵的原始类型,如float,int , double等等。若该变量为资源对象,则Type指明的是资源类型,如Texture2D,Buffer等等。Rows,Columns表明了矩阵的行和列数,其他的数值类型为1。Elements表明了数组类型的元素数。Members表明Structure或者class类型的成员数。Offset表示相对于父结构的偏移。

  1. // 查询constant buffer 接口信息
  2.  
  3. // Variables保存Constant Buffer中所有变量信息
  4. // VariableTypes保存Constant Buffer中所有变量的类型信息
  5. for(int j = 0; j < ShaderBufferDesc.Variable; j++)
  6. {
  7. ID3D11ShaderReflectionVariable* pShaderReflectionVariable = GetVariableByIndex(i);
  8.  
  9. D3D11_SHADER_VARIABLE_DESC VariableDesc;
  10. pShaderReflectionVariable->GetDesc(VariableDesc);
  11.  
  12. Variables.push_back(VariableDesc);
  13.  
  14. // ------------Type--------------
  15. ID3D11ShaderReflectionType* pShaderReflectionType = pShaderReflectionVariable->GetType();
  16.  
  17. D3D11_SHADER_TYPE_DESC ShaderTypeDesc;
  18. pShaderReflectionType->GetDesc(&ShaderTypeDesc);
  19.  
  20. VariableTypes.push_back(ShaderTypeDesc);
  21. }

Resource Bind

ID3D11ShaderReflection接口通过调用GetResourceBindingDesc方法将会返回一个D3D11_SHADER_INPUT_BIND_DESC结构体,该结构体描述了资源绑定信息:

  1. typedef struct D3D11_SHADER_INPUT_BIND_DESC
  2. {
  3. LPCSTR Name; // Name of the resource
  4. D3D_SHADER_INPUT_TYPE Type; // Type of resource (e.g. texture,cbuffer,etc.)
  5. UINT BindPoint; // Starting bind point
  6. UINT BindCount; // Number of contiguous bind points (for arrays)
  7.  
  8. UINT uFlags; // Input binding flags
  9. D3D_RESOURCE_RETURN_TYPE ReturnType; // Return type (if texture)
  10. D3D_SRV_DIMENSION Dimension; // Dimension (if texture)
  11. UINT NumSamples; // Number of samples (0 if not MS texture)
  12. }D3D11_SHADER_INPUT_BIND_DESC;
  1. // ResourceBinds:
  2. // std::vector<D3D11_SHADER_INPUT_BIND_DESC>保存绑定资源信息
  3. for(int i = 0; i < ShaderDesc.BoundResources; i++)
  4. {
  5. D3D11_SHADRE_INPUT_BIND_DESC ResourceBindDesc;
  6. pReflector->GetResourceBinding(i,&ResourceBindDesc);
  7.  
  8. ResourceBinds.push_back(ResourceBindDesc);
  9. }

猜你在找的设计模式相关文章