Clonage d’un effet

Le clonage d’un effet crée une deuxième copie presque identique de l’effet. Consultez le qualificateur unique suivant pour une explication de la raison pour laquelle il n’est pas exact. Une deuxième copie d’un effet est utile lorsque l’on souhaite utiliser l’infrastructure d’effets sur plusieurs threads, car le runtime d’effet n’est pas thread safe pour maintenir des performances élevées.

Étant donné que les contextes d’appareil ne sont pas non thread-safe, différents threads doivent passer différents contextes d’appareil à la méthode ID3DX11EffectPass::Apply.

Un effet peut être cloné avec la syntaxe suivante :

ID3DX11Effect* pClonedEffect = NULL;
UINT Flags = D3DX11_EFFECT_CLONE_FORCE_NONSINGLE;
HRESULT hr = pEffect->CloneEffect( Flags, &pClonedEffect );

Dans l’exemple ci-dessus, la copie cloné encapsule le même état que l’effet d’origine, quel que soit l’état dans lequel se trouve l’effet d’origine. En particulier :

  1. Si pEffect est optimisé, pCloned Effect est optimisé
  2. Si pEffect a des variables gérées par l’utilisateur, pCloned Effect aura les mêmes variables gérées par l’utilisateur (voir la description unique ci-dessous)
  3. Toutes les mises à jour de variables en attente (jusqu’à ce qu’un état d’appareil Appliquer l’appel met à jour) dans pEffect seront en attente dans pClonedEffect

Les objets d’appareil Direct3D 11 suivants étant immuables ou jamais mis à jour par l’infrastructure d’effets, l’effet cloné pointe vers les mêmes objets que l’effet d’origine :

  1. Objets de bloc d’état (ID3D11BlendState, ID3D11RasterizerState, ID3D11DepthStencilState, ID3D11SamplerState)
  2. Nuanceurs
  3. Instances de classe
  4. Textures (sans les tampons de texture)
  5. Vues d’accès non ordonnées

Les objets d’appareil Direct3D 11 suivants sont à la fois immuables et modifiés par le runtime d’effet (sauf si géré par l’utilisateur ou unique dans un effet cloné) ; de nouvelles copies de ces objets sont créées lorsqu’elles ne sont pas uniques :

  1. Mémoires tampons constantes
  2. Mémoires tampons de texture

Mémoires tampons de constante unique et mémoires tampons de texture

Notez que cette discussion s’applique à la fois aux mémoires tampons et aux textures constantes, mais que les mémoires tampons constantes sont supposées pour faciliter la lecture.

Dans certains cas, une mémoire tampon constante n’est mise à jour que par un seul thread, mais l’état de l’appareil défini par les effets cloné utilise ces données. Par exemple, l’effet main peut mettre à jour les matrices de monde et de vue référencées à partir de nuanceurs dans les effets clonés qui ne modifient pas les matrices de monde et de vue. Dans ce cas, les effets clonés doivent référencer la mémoire tampon constante actuelle au lieu d’en recréer une.

Il existe deux façons d’obtenir ce résultat souhaité :

  1. Utilisez ID3DX11EffectConstantBuffer::SetConstantBuffer sur l’effet cloné pour le rendre géré par l’utilisateur
  2. Marquer la mémoire tampon constante comme « unique » dans le code HLSL, forçant le runtime d’effet à traiter est géré par l’utilisateur après le clonage

Il existe deux différences entre les deux méthodes ci-dessus. Tout d’abord, dans la méthode 1, un nouvel ID3D11Buffer est créé et l’utilisateur est créé avant l’appel de SetConstantBuffer. En outre, après avoir appelé UndoSetConstantBuffer dans l’effet cloné, la variable dans la méthode 1 pointe vers la mémoire tampon nouvellement créée (dont les effets seront mis à jour sur Apply), tandis que la variable dans la méthode 2 continuera à pointer vers la mémoire tampon d’origine (sans la mettre à jour sur Apply).

Consultez l’exemple suivant dans HLSL :

cbuffer ObjectData
{
    float4 Position;
};
single cbuffer ViewData
{
    float4x4 ViewMatrix;
};

Lors du clonage, l’effet cloné crée un nouvel ID3D11Buffer pour ObjectData et renseigne son contenu sur Appliquer, mais référence l’ID3D11Buffer d’origine pour ViewData. Le qualificateur unique peut être ignoré dans le processus de clonage en définissant l’indicateur D3DX11_EFFECT_CLONE_FORCE_NONSINGLE.

Effets (Direct3D 11)