Compartilhar via


Empacotando uma biblioteca de sombreadores

Aqui, mostramos como compilar o código do sombreador, carregar o código compilado em uma biblioteca de sombreadores e associar recursos de slots de origem a slots de destino.

Objetivo: Para empacotar uma biblioteca de sombreador a ser usada para vinculação de sombreador.

Pré-requisitos

Partimos do princípio de que você conhece C++. Você também precisa ter experiência básica com conceitos de programação de elementos gráficos.

Tempo de conclusão: 30 minutos.

Instruções

1. Compilando o código do sombreador

Compile o código do sombreador com uma das funções de compilação. Por exemplo, esse snippet de código usa 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
        );

A cadeia de caracteres de origem contém o código ASCII HLSL não compilado.

2. Carregue o código compilado em uma biblioteca de sombreador.

Chame a função D3DLoadModule para carregar o código compilado (ID3DBlob) em um módulo (ID3D11Module) que representa uma biblioteca de sombreadores.

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

3. Associar recursos de slots de origem a slots de destino.

Chame o método ID3D11Module::CreateInstance para criar uma instância (ID3D11ModuleInstance) da biblioteca para que você possa definir associações de recursos para a instância.

Chame os métodos de associação de ID3D11ModuleInstance para associar os recursos necessários dos slots de origem aos slots de destino. Os recursos podem ser texturas, buffers, exemplores, buffers constantes ou UAVs. Normalmente, você usará os mesmos slots que a biblioteca de origem.

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

Esse código HLSL mostra que a biblioteca de origem usa os mesmos slots (t0, s0, b0, b1 e b2) que os slots usados nos métodos de associação anteriores de ID3D11ModuleInstance.

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

Resumo e próximas etapas

Compilamos o código do sombreador, carregamos o código compilado em uma biblioteca de sombreador e associamos recursos de slots de origem a slots de destino.

Em seguida, construímos FLGs (function-linking-graphs) para sombreadores, vinculamos-os ao código compilado e produzimos blobs de sombreador que o runtime do Direct3D pode usar.

Construir um grafo de vinculação de função e vinculá-lo ao código compilado

Usando a vinculação do sombreador