Liaison de nuanceurs d’effet

Direct2D utilise une optimisation appelée liaison de nuanceur d’effet qui combine plusieurs passes de rendu de graphe à effet en un seul passage.

Vue d’ensemble de la liaison du nuanceur d’effet

Les optimisations de liaison du nuanceur d’effet s’appuient sur la liaison de nuanceur HLSL, une fonctionnalité Direct3D 11.2 qui permet de générer des nuanceurs de pixels et de vertex au moment de l’exécution en liant des fonctions de nuanceur précompilées. Les figures suivantes illustrent le concept de liaison de nuanceur d’effet dans un graphique d’effet. La première figure montre un graphique d’effet Direct2D classique avec quatre transformations de rendu. Sans liaison de nuanceur, chaque transformation consomme une passe de rendu et nécessite une surface intermédiaire ; au total, ce graphique nécessite 4 passes et 3 intermédiaires.

transformer le graphe sans liaison de nuanceur : 4 passes et 3 intermédiaires.

La deuxième figure montre le même graphique d’effet où chaque transformation de rendu a été remplacée par une version de fonction pouvant être liée. Direct2D est en mesure de lier l’ensemble du graphe et de l’exécuter en une seule passe sans nécessiter d’intermédiaires. Cela peut entraîner une diminution significative du temps d’exécution du GPU et une réduction de la consommation maximale de mémoire GPU.

Graphe de transformation avec liaison de nuanceur : 1 pass, 0 intermédiaires.

 

La liaison du nuanceur d’effet fonctionne sur des transformations individuelles au sein d’un effet ; cela signifie que même un graphique avec un seul effet peut tirer parti de la liaison de nuanceur si cet effet a plusieurs transformations valides.

Utilisation de la liaison du nuanceur d’effet

Si vous créez une application Direct2D qui utilise des effets, vous n’avez pas besoin de faire quoi que ce soit pour tirer parti de la liaison du nuanceur d’effets. Direct2D analyse automatiquement le graphique d’effets pour déterminer la façon la plus optimale de lier chaque transformation.

Les auteurs d’effets sont responsables de l’implémentation de leur effet d’une manière qui prend en charge la liaison du nuanceur d’effet ; Pour plus d’informations, consultez la section Création d’un effet personnalisé compatible avec le nuanceur ci-dessous . Tous les effets intégrés prennent en charge la liaison de nuanceur.

Direct2D liera uniquement les transformations de rendu adjacentes dans les situations où il est bénéfique. Il prend en compte plusieurs facteurs pour déterminer s’il faut lier deux transformations. Par exemple, la liaison de nuanceur n’est pas effectuée si l’une des transformations utilise des nuanceurs de vertex ou de calcul, car seuls les nuanceurs de pixels peuvent être liés. En outre, si un effet n’a pas été créé pour être compatible avec la liaison de nuanceur, les transformations environnantes ne seront pas liées à celui-ci.

Dans le cas où un tel risque de liaison existe, Direct2D ne liera pas les transformations adjacentes au danger, mais tentera tout de même de lier le reste du graphique.

Graphe de transformation avec un risque de liaison : 2 passes, 1 intermédiaire.

Création d’un effet personnalisé compatible avec le nuanceur

Si vous créez votre propre effet Direct2D personnalisé, vous devez vous assurer que ses transformations prennent en charge la liaison de nuanceur d’effet. Cela nécessite des modifications mineures par rapport à la façon dont les effets personnalisés précédents ont été implémentés. Si une transformation dans votre effet personnalisé ne prend pas en charge la liaison de nuanceur, Direct2D ne la liera pas à des transformations adjacentes dans le graphique d’effet.

En tant qu’auteur d’effets personnalisés, vous devez connaître plusieurs concepts et exigences clés :

  • Aucune modification apportée aux implémentations d’interface

    Vous n’avez pas besoin de modifier de code implémentant les différentes interfaces d’effet telles que ID2D1DrawTransform.

  • Fournir une version complète et une version de fonction d’exportation des nuanceurs

    Vous devez fournir une version de fonction d’exportation des nuanceurs de votre effet qui peuvent être liés par Direct2D. En outre, vous devez également continuer à fournir le nuanceur complet d’origine; En effet, Direct2D sélectionne au moment de l’exécution la version de nuanceur appropriée selon que la liaison de nuanceur doit être appliquée ou non à un lien particulier dans le graphe.

    Si une transformation fournit uniquement l’objet blob de nuanceur de pixels complets (via ID2D1EffectContext::LoadPixelShader), elle n’est pas liée aux transformations adjacentes.

  • Fonctions d’assistance

    Direct2D fournit des fonctions d’assistance HLSL et des macros qui généreront automatiquement les versions complètes et les versions de fonction d’exportation d’un nuanceur. Ces aides se trouvent dans d2d1effecthelpers.hlsli. En outre, le compilateur HLSL (FXC) vous permet d’insérer le nuanceur de fonction d’exportation dans un champ privé dans le nuanceur complet. De cette façon, vous ne devez créer un nuanceur qu’une seule fois et passer les deux versions à Direct2D simultanément. D2d1effecthelpers.hlsli et le compilateur FXC sont inclus dans le kit de développement logiciel (SDK) Windows.

    Les fonctions d’assistance :

    Vous pouvez également créer manuellement deux versions de chaque nuanceur et les compiler deux fois, tant que les spécifications décrites ci-dessous dans Spécifications de fonction d’exportation sont remplies .

  • Nuanceurs de pixels uniquement

    Direct2D ne prend pas en charge la liaison des nuanceurs de calcul ou de vertex. Toutefois, si votre effet utilise à la fois un nuanceur de vertex et de pixels, la sortie du nuanceur de pixels peut toujours être liée.

  • Échantillonnage simple ou complexe

    La liaison de la fonction nuanceur fonctionne en connectant la sortie d’une passe de nuanceur de pixels à l’entrée d’un passage de nuanceur de pixels suivant. Cela n’est possible que lorsque le nuanceur de pixels qui consomme ne nécessite qu’une seule valeur d’entrée pour effectuer son calcul ; cette valeur provient normalement de l’échantillonnage d’une texture d’entrée à la coordonnée de texture émise par le nuanceur de vertex. Un tel nuanceur de pixels est dit d’effectuer un échantillonnage simple.

    La conversion de nuances de gris est un exemple d’échantillonnage simple. la valeur d’un pixel de sortie particulier dépend uniquement de la valeur du pixel d’entrée correspondant.

    Certains nuanceurs de pixels, tels qu’un flou gaussien, calculent leur sortie à partir de plusieurs exemples d’entrée plutôt que d’un seul exemple. Un tel nuanceur de pixels est dit d’effectuer un échantillonnage complexe.

    Le flou gaussien est un exemple d’échantillonnage complexe. la valeur du pixel de sortie central dépend de plusieurs pixels d’entrée.

    Seules les fonctions de nuanceur avec des entrées simples peuvent avoir leur entrée fournie par une autre fonction de nuanceur. Les fonctions de nuanceur avec des entrées complexes doivent être fournies avec une texture d’entrée à échantillonner. Cela signifie que Direct2D ne lie pas un nuanceur avec des entrées complexes à son prédécesseur.

    Lorsque vous utilisez les assistances HLSL Direct2D, vous devez indiquer dans le HLSL si un nuanceur utilise des entrées complexes ou simples.

Exemple de nuanceur d’effet compatible avec la liaison

À l’aide des helpers D2D, l’extrait de code suivant représente un nuanceur d’effet simple compatible avec la liaison :

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

Dans cet exemple court, notez qu’aucun paramètre de fonction n’est déclaré, que le nombre d’entrées et le type de chaque entrée sont déclarés avant la fonction d’entrée, que l’entrée est récupérée en appelant D2DGetInput et que les directives de préprocesseur doivent être définies avant l’inclusion du fichier d’assistance.

Un nuanceur compatible avec la liaison doit fournir à la fois un nuanceur de pixels simple passage et une fonction de nuanceur d’exportation. La macro D2D_PS_ENTRY permet de générer chacun d’entre eux à partir du même code, lorsqu’il est utilisé conjointement avec le script de compilation du nuanceur.

Lors de la compilation d’un nuanceur complet, les macros sont développées dans le code suivant, qui a une signature d’entrée compatible avec les effets 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;
    }    

Lors de la compilation d’une version de fonction d’exportation du même code, le code suivant est généré :

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

Notez que l’entrée de texture, normalement récupérée par échantillonnage d’une Texture2D, a été remplacée par une entrée de fonction (input0).

Pour obtenir une description détaillée complète de ce que vous devez faire pour écrire un effet compatible avec la liaison, consultez le tutoriel Effets personnalisés et l’exemple d’effets d’image personnalisée Direct2D.

Compilation d’un nuanceur de liaison compatible

Pour pouvoir être lié, l’objet blob du nuanceur de pixels passé à D2D doit contenir à la fois les versions complète et de fonction d’exportation du nuanceur. Pour ce faire, incorporez la fonction d’exportation compilée dans la zone D3D_BLOB_PRIVATE_DATA.

Lorsque les nuanceurs sont créés avec les fonctions d’assistance D2D, une cible de compilation D2D doit être définie au moment de la compilation. Les types cibles de compilation sont D2D_FULL_SHADER et D2D_FUNCTION.

La compilation d’un nuanceur d’effets compatible avec la liaison est un processus en deux étapes :

Notes

Lors de la compilation d’un effet à l’aide de Visual Studio, vous devez créer un fichier batch qui exécute les deux commandes FXC et exécuter ce fichier batch comme une étape de génération personnalisée qui s’exécute avant l’étape de compilation.

 

Étape 1 : Compiler la fonction d’exportation

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

Pour compiler la version de la fonction d’exportation de votre nuanceur, vous devez passer les indicateurs suivants à FXC.

Indicateur Description
/T <ShaderModel> Définissez <ShaderModel> sur le profil de nuanceur de pixels approprié, comme défini dans la syntaxe FXC. Il doit s’agir de l’un des profils répertoriés sous « Liaison de nuanceur HLSL ».
<MyShaderFile.hlsl> Définissez <MyShaderFile> sur le nom du fichier HLSL.
/D D2D_FUNCTION Cette définition indique à FXC de compiler la version de la fonction d’exportation du nuanceur.
/D D2D_ENTRY=<entry> Définissez <l’entrée> sur le nom du point d’entrée HLSL que vous avez défini à l’intérieur de la macro D2D_PS_ENTRY .
/Fl <MyShaderFile.fxlib> Définissez <MyShaderfile> sur l’emplacement où vous souhaitez stocker la version de la fonction d’exportation du nuanceur. Notez que l’extension .fxlib est uniquement pour faciliter l’identification.

Étape 2 : Compiler le nuanceur complet et incorporer la fonction d’exportation

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           

Pour compiler la version complète de votre nuanceur avec la version d’exportation incorporée, vous devez passer les indicateurs suivants à FXC.

Indicateur Description
/T <ShaderModel> Définissez <ShaderModel> sur le profil de nuanceur de pixels approprié, comme défini dans la syntaxe FXC. Il doit s’agir du profil de nuanceur de pixels correspondant au profil de liaison spécifié à l’étape 1.
<MyShaderFile.hlsl> Définissez <MyShaderFile> sur le nom du fichier HLSL.
/D D2D_FULL_SHADER Cette définition indique à FXC de compiler la version complète du nuanceur.
/D D2D_ENTRY=<entry> Définissez <l’entrée> sur le nom du point d’entrée HLSL que vous avez défini à l’intérieur de la macro D2D_PS_ENTRY().
Entrée /E <> Définissez <l’entrée> sur le nom du point d’entrée HLSL que vous avez défini à l’intérieur de la macro D2D_PS_ENTRY().
/setprivate <MyShaderFile.fxlib> Cet argument indique à FXC d’incorporer le nuanceur de fonction d’exportation généré à l’étape 1 dans la zone D3D_BLOB_PRIVATE_DATA.
/Fo <MyShader.cso> Définissez <MyShader> sur l’emplacement où vous souhaitez stocker le nuanceur compilé final et combiné.
/Fh <MyShader.h> Définissez <MyShader> sur l’emplacement où vous souhaitez stocker l’en-tête final combiné.

Spécifications des fonctions d’exportation

Il est possible, bien que non recommandé, de créer un nuanceur d’effets compatible sans utiliser les aides fournies par D2D. Veillez à ce que les signatures d’entrée du nuanceur complet et de la fonction d’exportation soient conformes aux spécifications D2D.

Les spécifications des nuanceurs complets sont les mêmes que les versions antérieures de Windows. Brièvement, les paramètres d’entrée du nuanceur de pixels doivent être SV_POSITION, SCENE_POSITION et un TEXCOORD par entrée d’effet.

Pour la fonction d’exportation, la fonction doit retourner un float4 et ses entrées doivent être de l’un des types suivants :

  • Entrée simple

    float4 d2d_inputN : INPUTN         
    

    Pour les entrées simples, D2D insère une fonction d’exemple entre la fonction de texture d’entrée et de nuanceur, ou l’entrée est fournie par la sortie d’une autre fonction de nuanceur.

  • Entrée complexe

    float4 d2d_uvN  : TEXCOORDN                
    

    Pour les entrées complexes, D2D transmet uniquement une coordonnée de texture comme décrit dans Windows 8 documentation.

  • Emplacement de sortie

    float4 d2d_posScene : SCENE_POSITION                
    

    Une seule entrée SCENE_POSITION peut être définie. Ce paramètre ne doit être inclus que si nécessaire, car une seule fonction par nuanceur lié peut utiliser ce paramètre.

La sémantique doit être définie comme ci-dessus, car D2D inspectera la sémantique pour décider comment lier des fonctions entre elles. Si une entrée de fonction ne correspond pas à l’un des types ci-dessus, la fonction est rejetée pour la liaison du nuanceur.

HLSL Helpers

Interface ID3D11Linker

Interface ID3D11FunctionLinkingGraph