打包着色器库

下面我们将介绍如何编译着色器代码、将编译的代码加载到着色器库中,以及如何将源槽中的资源绑定到目标槽。

目的: 打包用于着色器链接的着色器库。

先决条件

我们假定你熟悉 C++。 你还需要具有图形编程概念方面的基本经验。

完成时间: 30 分钟。

Instructions

1. 编译着色器代码

使用其中一个编译函数编译着色器代码。 例如,此代码片段使用 D3DCompile

    string source;
 
    ComPtr<ID3DBlob> codeBlob;
    ComPtr<ID3DBlob> errorBlob;
    HRESULT hr = D3DCompile(
        source.c_str(),
        source.size(),
        "ShaderModule",
        NULL,
        NULL,
        NULL,
        ("lib" + m_shaderModelSuffix).c_str(),
        D3DCOMPILE_OPTIMIZATION_LEVEL3,
        0,
        &codeBlob,
        &errorBlob
        );

源字符串包含未编译的 ASCII HLSL 代码。

2. 将编译的代码加载到着色器库中。

调用 D3DLoadModule 函数,将 ID3DBlob) (编译的代码加载到表示着色器库的 ID3D11Module) (模块中。

    // Load the compiled library code into a module object.
    ComPtr<ID3D11Module> shaderLibrary;
    DX::ThrowIfFailed(D3DLoadModule(codeBlob->GetBufferPointer(), codeBlob->GetBufferSize(), &shaderLibrary));

3. 将源槽中的资源绑定到目标槽。

调用 ID3D11Module::CreateInstance 方法以 (库的 ID3D11ModuleInstance) 创建实例,以便为该实例定义资源绑定。

调用 ID3D11ModuleInstance 的绑定方法,将源槽中所需的资源绑定到目标槽。 资源可以是纹理、缓冲区、采样器、常量缓冲区或 UAV。 通常,将使用与源库相同的槽。

    // Create an instance of the library and define resource bindings for it.
    // In this sample we use the same slots as the source library however this is not required.
    ComPtr<ID3D11ModuleInstance> shaderLibraryInstance;
    DX::ThrowIfFailed(shaderLibrary->CreateInstance("", &shaderLibraryInstance));
    // HRESULTs for Bind methods are intentionally ignored as compiler optimizations may eliminate the source
    // bindings. In these cases, the Bind operation will fail, but the final shader will function normally.
    shaderLibraryInstance->BindResource(0, 0, 1);
    shaderLibraryInstance->BindSampler(0, 0, 1);
    shaderLibraryInstance->BindConstantBuffer(0, 0, 0);
    shaderLibraryInstance->BindConstantBuffer(1, 1, 0);
    shaderLibraryInstance->BindConstantBuffer(2, 2, 0);

此 HLSL 代码显示,源库使用与 ID3D11ModuleInstance 的上述绑定方法中使用的槽相同的槽 (t0、s0、b0、b0、b1 和 b2) 。

// This is the default code in the fixed header section.
Texture2D<float3> Texture : register(t0);
SamplerState Anisotropic : register(s0);
cbuffer CameraData : register(b0)
{
    float4x4 Model;
    float4x4 View;
    float4x4 Projection;
};
cbuffer TimeVariantSignals : register(b1)
{
    float SineWave;
    float SquareWave;
    float TriangleWave;
    float SawtoothWave;
};

// This code is not displayed, but is used as part of the linking process.
cbuffer HiddenBuffer : register(b2)
{
    float3 LightDirection;
};

总结和后续步骤

我们编译了着色器代码,将编译的代码加载到着色器库中,并将源槽中的资源绑定到目标槽。

接下来,我们构造函数链接图 (着色器) 的 FLG,将它们链接到已编译的代码,并生成 Direct3D 运行时可以使用的着色器 Blob。

构造函数链接图并将其链接到编译的代码

使用着色器链接