Vinculación del sombreador de efectos

Direct2D usa una optimización denominada vinculación de sombreador de efectos que combina varios pasos de representación de gráficos de efectos en un solo paso.

Información general sobre la vinculación del sombreador de efectos

Las optimizaciones de vinculación del sombreador de efectos se basan en la vinculación del sombreador HLSL, una característica de Direct3D 11.2 que permite generar sombreadores de píxeles y vértices en tiempo de ejecución mediante la vinculación de funciones de sombreador compiladas previamente. En las ilustraciones siguientes se muestra el concepto de vinculación del sombreador de efectos en un gráfico de efectos. En la primera ilustración se muestra un gráfico de efectos direct2D típico con cuatro transformaciones de representación. Sin vinculación de sombreador, cada transformación consume un pase de representación y requiere una superficie intermedia; en total, este gráfico requiere 4 pases y 3 intermedios.

transformar gráfico sin vinculación de sombreador: 4 pases y 3 intermedios.

En la segunda ilustración se muestra el mismo gráfico de efectos en el que cada transformación de representación se ha reemplazado por una versión de función enlazable. Direct2D puede vincular todo el grafo y ejecutarlo en un paso sin necesidad de ningún intermedio. Esto puede proporcionar una disminución significativa en el tiempo de ejecución de GPU y reducir el consumo máximo de memoria de GPU.

transformar gráfico con vinculación de sombreador: 1 paso, 0 intermedios.

 

La vinculación del sombreador de efectos funciona en transformaciones individuales dentro de un efecto; Esto significa que incluso un gráfico con un único efecto puede beneficiarse de la vinculación del sombreador si ese efecto tiene varias transformaciones válidas.

Uso de la vinculación del sombreador de efectos

Si va a crear una aplicación direct2D que usa efectos, no es necesario hacer nada para aprovechar la vinculación del sombreador de efectos. Direct2D analiza automáticamente el gráfico de efectos para determinar la manera más óptima de vincular cada transformación.

Los autores de efectos son responsables de implementar su efecto de forma que admita la vinculación del sombreador de efectos; para obtener más información, consulte la sección Creación de un efecto personalizado compatible con la vinculación de sombreador a continuación. Todos los efectos integrados admiten la vinculación del sombreador.

Direct2D solo vinculará transformaciones de representación adyacentes en situaciones en las que sea beneficioso. Tiene en cuenta varios factores al determinar si vincular dos transformaciones. Por ejemplo, la vinculación del sombreador no se realiza si una de las transformaciones usa sombreadores de vértices o de proceso, ya que solo se pueden vincular sombreadores de píxeles. Además, si no se creó un efecto para ser compatible con la vinculación del sombreador, las transformaciones circundantes no se vincularán con él.

En caso de que exista este peligro de vinculación, Direct2D no vinculará ninguna transformación adyacente al peligro, pero intentará vincular el resto del gráfico.

transformar gráfico con un peligro de vinculación: 2 pases, 1 intermedio.

Creación de un efecto personalizado compatible con la vinculación del sombreador

Si va a crear su propio efecto personalizado de Direct2D, debe asegurarse de que sus transformaciones admiten la vinculación del sombreador de efectos. Esto requiere algunos cambios menores en la forma en que se implementaron los efectos personalizados anteriores. Si una transformación dentro del efecto personalizado no admite la vinculación del sombreador, Direct2D no la vinculará con ninguna transformación adyacente en el gráfico de efectos.

Como autor de efectos personalizados, debe tener en cuenta varios conceptos y requisitos clave:

  • No hay cambios en las implementaciones de interfaz de efecto

    No es necesario modificar ningún código que implemente las distintas interfaces de efecto, como ID2D1DrawTransform.

  • Proporcione una versión completa y exportada de funciones de sombreadores.

    Debe proporcionar una versión de función de exportación de los sombreadores del efecto que direct2D puede vincular. Además, también debe seguir proporcionando el sombreador original y completo; Esto se debe a que Direct2D selecciona en tiempo de ejecución la versión del sombreador correcto en función de si la vinculación del sombreador se va a aplicar a un vínculo determinado del gráfico.

    Si una transformación solo proporciona el blob de sombreador de píxeles completo (a través de ID2D1EffectContext::LoadPixelShader), no se vinculará a transformaciones adyacentes.

  • Funciones auxiliares

    Direct2D proporciona funciones auxiliares y macros de HLSL que generarán automáticamente las versiones completas y exportadas de funciones de un sombreador. Estos asistentes se pueden encontrar en d2d1effecthelpers.hlsli. Además, el compilador HLSL (FXC) permite insertar el sombreador de funciones de exportación en un campo privado en el sombreador completo. De este modo, solo tienes que crear un sombreador una vez y pasar ambas versiones a Direct2D simultáneamente. Tanto d2d1effecthelpers.hlsli como el compilador FXC se incluyen como parte del SDK de Windows.

    Las funciones auxiliares:

    También puede crear manualmente dos versiones de cada sombreador y compilarlas dos veces, siempre y cuando se cumplan las especificaciones descritas a continuación en Exportar especificaciones de función .

  • Solo sombreadores de píxeles

    Direct2D no admite la vinculación de sombreadores de proceso o vértices. Sin embargo, si el efecto usa un sombreador de vértices y píxeles, la salida del sombreador de píxeles todavía se puede vincular.

  • Muestreo simple frente a complejo

    La vinculación de funciones de sombreador funciona conectando la salida de un paso de sombreador de píxeles a la entrada de un paso de sombreador de píxeles posterior. Esto solo es posible cuando el sombreador de píxeles consumido solo requiere un único valor de entrada para realizar su cálculo; este valor normalmente provenía del muestreo de una textura de entrada en la coordenada de textura emitida por el sombreador de vértices. Se dice que un sombreador de píxeles realiza un muestreo simple.

    La conversión de escala de grises es un ejemplo de muestreo simple. El valor de un píxel de salida determinado depende solo del valor del píxel de entrada correspondiente.

    Algunos sombreadores de píxeles, como un desenfoque gaussiano, calculan su salida de varias muestras de entrada en lugar de una sola muestra. Se dice que un sombreador de píxeles realiza un muestreo complejo.

    El desenfoque gaussiano es un ejemplo de muestreo complejo. el valor del píxel de salida central depende de varios píxeles de entrada.

    Solo las funciones de sombreador con entradas simples pueden tener su entrada proporcionada por otra función de sombreador. Las funciones de sombreador con entradas complejas se deben proporcionar con una textura de entrada para realizar una muestra. Esto significa que Direct2D no vinculará un sombreador con entradas complejas a su predecesor.

    Al usar los asistentes de HLSL de Direct2D, debe indicar en HLSL si un sombreador usa entradas complejas o simples.

Sombreador de efectos compatibles con la vinculación de ejemplo

Con los asistentes D2D, el siguiente fragmento de código representa un sombreador de efectos compatible con la vinculación simple:

#define D2D_INPUT_COUNT 1
#define D2D_INPUT0_SIMPLE
#include “d2d1effecthelpers.hlsli”

D2D_PS_ENTRY(LinkingCompatiblePixelShader)
{
    float4 input = D2DGetInput(0);
    input.rgb *= input.a;
    return input;
}          

En este breve ejemplo, tenga en cuenta que no se declara ningún parámetro de función, que el número de entradas y el tipo de cada entrada se declara antes de la función de entrada, la entrada se recupera llamando a D2DGetInput y que las directivas de preprocesador deben definirse antes de que se incluya el archivo auxiliar.

Un sombreador compatible con la vinculación debe proporcionar un sombreador de píxeles de paso único normal y una función de sombreador de exportación. La macro D2D_PS_ENTRY permite que cada uno de estos se genere a partir del mismo código, cuando se usa junto con el script de compilación del sombreador.

Al compilar un sombreador completo, las macros se expanden en el código siguiente, que tiene una firma de entrada compatible con efectos D2D.

Texture2D<float4> InputTexture0;
SamplerState InputSampler0;

float4 LinkingCompatiblePixelShader(
    float4 pos   : SV_POSITION,
    float4 posScene : SCENE_POSITION,
    float4 uv0  : TEXCOORD0
    ) : SV_Target
    {
        float4 input = InputTexture0.Sample(InputSampler0, uv0.xy);
        input.rgb *= input.a;
        return input;
    }    

Al compilar una versión de función de exportación del mismo código, se genera el código siguiente:

// Shader function version
export float4 LinkingCompatiblePixelShader_Function(
    float4 input0 : INPUT0)
    {
        input.rgb *= input.a;
        return input;
    }      

Tenga en cuenta que la entrada de textura, que normalmente se recupera mediante el muestreo de una Texture2D, se ha reemplazado por una entrada de función (input0).

Para ver una descripción completa paso a paso de lo que necesita hacer para escribir un efecto compatible con la vinculación, consulte el tutorial Efectos personalizados y el ejemplo de efectos de imagen personalizados de Direct2D.

Compilación de un sombreador compatible de vinculación

Para poder vincularse, el blob de sombreador de píxeles pasado a D2D debe contener las versiones completas y de exportación de la función del sombreador. Esto se logra insertando la función de exportación compilada en el área de D3D_BLOB_PRIVATE_DATA.

Cuando los sombreadores se crean con las funciones auxiliares D2D, se debe definir un destino de compilación D2D en tiempo de compilación. Los tipos de destino de compilación se D2D_FULL_SHADER y D2D_FUNCTION.

La compilación de un sombreador de efectos compatible con la vinculación es un proceso de dos pasos:

Nota

Al compilar un efecto mediante Visual Studio, debe crear un archivo por lotes que ejecute los comandos FXC y ejecute este archivo por lotes como un paso de compilación personalizado que se ejecute antes del paso de compilación.

 

Paso 1: Compilación de la función de exportación

fxc /T <shadermodel> <MyShaderFile>.hlsl /D D2D_FUNCTION /D D2D_ENTRY=<entry> /Fl <MyShaderFile>.fxlib           

Para compilar la versión de la función de exportación del sombreador, debe pasar las siguientes marcas a FXC.

Marca Descripción
/T <ShaderModel> Establezca <ShaderModel> en el perfil de sombreador de píxeles adecuado, tal como se define en Sintaxis FXC. Debe ser uno de los perfiles enumerados en "Vinculación del sombreador HLSL".
<MyShaderFile.hlsl> Establezca <MyShaderFile> en el nombre del archivo HLSL.
/D D2D_FUNCTION Esta definición indica a FXC que compile la versión de la función de exportación del sombreador.
/D D2D_ENTRY=<entry> Establezca <la entrada> en el nombre del punto de entrada HLSL que definió dentro de la macro D2D_PS_ENTRY .
/Fl <MyShaderFile.fxlib> Establezca <MyShaderfile en> donde quiera almacenar la versión de la función de exportación del sombreador. Tenga en cuenta que la extensión .fxlib solo es para facilitar la identificación.

Paso 2: Compilar el sombreador completo e insertar la función de exportación

fxc /T ps_<shadermodel> <MyShaderFile>.hlsl /D D2D_FULL_SHADER /D D2D_ENTRY=<entry> /E <entry> /setprivate <MyShaderFile>.fxlib /Fo <MyShader>.cso /Fh <MyShader>.h           

Para compilar la versión completa del sombreador con la versión de exportación insertada, debe pasar las marcas siguientes a FXC.

Marca Descripción
/T <ShaderModel> Establezca <ShaderModel> en el perfil de sombreador de píxeles adecuado, tal como se define en Sintaxis FXC. Debe ser el perfil del sombreador de píxeles correspondiente al perfil de vinculación especificado en el paso 1.
<MyShaderFile.hlsl> Establezca <MyShaderFile> en el nombre del archivo HLSL.
/D D2D_FULL_SHADER Esta definición indica a FXC que compile la versión completa del sombreador.
/D D2D_ENTRY=<entry> Establezca <la entrada> en el nombre del punto de entrada HLSL que definió dentro de la macro D2D_PS_ENTRY().
Entrada /E <> Establezca <la entrada> en el nombre del punto de entrada HLSL que definió dentro de la macro D2D_PS_ENTRY().
/setprivate <MyShaderFile.fxlib> Este argumento indica a FXC que inserte el sombreador de funciones de exportación generado en el paso 1 en el área D3D_BLOB_PRIVATE_DATA.
/Fo <MyShader.cso> Establezca <MyShader> en donde quiera almacenar el sombreador compilado final y combinado.
/Fh <MyShader.h> Establezca <MyShader> en donde quiera almacenar el encabezado combinado final.

Exportar especificaciones de función

Aunque no se recomienda, es posible crear un sombreador de efectos compatible sin usar los asistentes proporcionados por D2D. Se debe tener cuidado para asegurarse de que tanto el sombreador completo como las firmas de entrada de función de exportación cumplan las especificaciones D2D.

Las especificaciones de los sombreadores completos son las mismas que las versiones anteriores de Windows. Brevemente, los parámetros de entrada del sombreador de píxeles deben ser SV_POSITION, SCENE_POSITION y una entrada de TEXCOORD por efecto.

Para la función de exportación, la función debe devolver un float4 y sus entradas deben ser uno de los siguientes tipos:

  • Entrada simple

    float4 d2d_inputN : INPUTN         
    

    Para entradas sencillas, D2D insertará una función Sample entre la textura de entrada y la función de sombreador, o la entrada la proporcionará la salida de otra función de sombreador.

  • Entrada compleja

    float4 d2d_uvN  : TEXCOORDN                
    

    En el caso de las entradas complejas, D2D solo pasará una coordenada de textura, como se describe en Windows 8 documentación.

  • Ubicación del resultado

    float4 d2d_posScene : SCENE_POSITION                
    

    Solo se puede definir una entrada de SCENE_POSITION. Este parámetro solo debe incluirse cuando sea necesario, ya que solo una función por sombreador vinculado puede usar este parámetro.

La semántica debe definirse como antes, ya que D2D inspeccionará la semántica para decidir cómo vincular funciones juntas. Si alguna entrada de función no coincide con uno de los tipos anteriores, se rechazará la función para la vinculación del sombreador.

Asistentes de HLSL

Interfaz ID3D11Linker

Interfaz ID3D11FunctionLinkingGraph