Constantes de nuanceur (HLSL)

Dans le modèle de nuanceur 4, les constantes de nuanceur sont stockées dans une ou plusieurs ressources de mémoire tampon. Ils peuvent être organisés en deux types de mémoires tampons : les mémoires tampons constantes (cbuffers) et les tampons de texture (tbuffers). Les mémoires tampons constantes sont optimisées pour l’utilisation des variables constantes, qui est caractérisée par un accès à faible latence et une mise à jour plus fréquente à partir du processeur. Pour cette raison, des restrictions supplémentaires de taille, de disposition et d’accès s’appliquent à ces ressources. Les mémoires tampons de texture sont accessibles comme les textures et s’effectuent mieux pour les données indexées arbitrairement. Quel que soit le type de ressource que vous utilisez, il n’existe aucune limite au nombre de mémoires tampons constantes ou de mémoires tampons de texture qu’une application peut créer.

La déclaration d’une mémoire tampon constante ou d’une mémoire tampon de texture ressemble beaucoup à une déclaration de structure en C, avec l’ajout des mots clés register et packoffset pour affecter manuellement des registres ou des données d’empaquetage.

BufferTypeName [: register(b#)] { VariableDeclaration [: packoffset(c#.xyzw)]; ... };

Paramètres

BufferType

[in] Type de mémoire tampon.

BufferType Description
cbuffer mémoire tampon constante
tbuffer mémoire tampon de texture

Nom

[in] Chaîne ASCII contenant un nom de mémoire tampon unique.

register(b#)

[in] Mot clé facultatif, utilisé pour empaqueter manuellement des données constantes. Les constantes peuvent être empaquetées dans un registre uniquement dans une mémoire tampon constante, où le registre de départ est donné par le numéro de registre (#).

VariableDeclaration

[in] Déclaration de variable, similaire à une déclaration de membre de structure. Il peut s’agir de n’importe quel type HLSL ou objet d’effet (à l’exception d’une texture ou d’un objet sampler).

packoffset(c#.xyzw)

[in] Mot clé facultatif, utilisé pour empaqueter manuellement des données constantes. Les constantes peuvent être empaquetées dans n’importe quelle mémoire tampon constante, où le numéro d’inscription est donné par (#). L’empaquetage des sous-composants (à l’aide du swizzling xyzw) est disponible pour les constantes dont la taille correspond à un seul registre (ne franchissent pas une limite de registre). Par exemple, un float4 n’a pas pu être empaqueté dans un registre unique commençant par le composant y, car il ne serait pas adapté à un registre à quatre composants.

Notes

Les mémoires tampons constantes réduisent la bande passante requise pour mettre à jour les constantes de nuanceur en permettant à celles-ci d’être regroupées et validées en même temps plutôt que d’effectuer des appels individuels pour valider chaque constante séparément.

Une mémoire tampon constante est une ressource de mémoire tampon spécialisée accessible comme une mémoire tampon. Chaque mémoire tampon constante peut contenir jusqu’à 4 096 vecteurs ; chaque vecteur contient jusqu’à quatre valeurs de 32 bits. Vous pouvez lier jusqu’à 14 mémoires tampons constantes par étape de pipeline (2 emplacements supplémentaires sont réservés pour une utilisation interne).

Une mémoire tampon de texture est une ressource de mémoire tampon spécialisée accessible comme une texture. L’accès de texture (par rapport à l’accès à la mémoire tampon) peut avoir de meilleures performances pour les données indexées arbitrairement. Vous pouvez lier jusqu’à 128 mémoires tampons de texture par étape de pipeline.

Une ressource de mémoire tampon est conçue pour réduire la surcharge de définition des constantes de nuanceur. L’infrastructure d’effet (consultez Interface ID3D10Effect) gère la mise à jour des mémoires tampons constantes et de texture, ou vous pouvez utiliser l’API Direct3D pour mettre à jour les mémoires tampons (voir Copier les données de ressources (Direct3D 10) et y accéder pour plus d’informations). Une application peut également copier des données à partir d’une autre mémoire tampon (par exemple, une cible de rendu ou une cible de sortie de flux) dans une mémoire tampon constante.

Pour plus d’informations sur l’utilisation de mémoires tampons constantes dans une application D3D10, consultez Types de ressources (Direct3D 10) et Créer des ressources de mémoire tampon (Direct3D 10).

Pour plus d’informations sur l’utilisation de mémoires tampons constantes dans une application D3D11, consultez Présentation des mémoires tampons dans Direct3D 11 et Guide pratique : Créer une mémoire tampon constante.

Une mémoire tampon constante ne nécessite pas qu’une vue soit liée au pipeline. Toutefois, une mémoire tampon de texture nécessite une vue et doit être liée à un emplacement de texture (ou doit être liée avec SetTextureBuffer lors de l’utilisation d’un effet).

Il existe deux façons d’empaqueter des données de constantes : à l’aide des mots clés register (DirectX HLSL) et packoffset (DirectX HLSL).

Différences entre Direct3D 9 et Direct3D 10 et 11 :

  • Contrairement à l’allocation automatique de constantes dans Direct3D 9, qui n’a pas effectué d’empaquetage et a affecté chaque variable à un ensemble de registres float4, les variables constantes HLSL suivent les règles d’empaquetage dans Direct3D 10 et 11.

Organiser des mémoires tampons constantes

Les mémoires tampons constantes réduisent la bande passante requise pour mettre à jour les constantes de nuanceur en permettant à celles-ci d’être regroupées et validées en même temps plutôt que d’effectuer des appels individuels pour valider chaque constante séparément.

La meilleure façon d’utiliser efficacement des mémoires tampons constantes consiste à organiser les variables de nuanceur en mémoires tampons constantes en fonction de leur fréquence de mise à jour. Cela permet à une application de réduire la bande passante requise pour mettre à jour les constantes du nuanceur. Par exemple, un nuanceur peut déclarer deux mémoires tampons constantes et organiser les données dans chacune d’elles en fonction de leur fréquence de mise à jour : les données qui doivent être mises à jour par objet (comme une matrice mondiale) sont regroupées en mémoire tampon constante pouvant être mises à jour pour chaque objet. Cela est distinct des données qui caractérisent une scène et qui sont donc susceptibles d’être mises à jour beaucoup moins souvent (lorsque la scène change).

cbuffer myObject
{       
    float4x4 matWorld;
    float3   vObjectPosition;
    int      arrayIndex;
}
 
cbuffer myScene
{
    float3   vSunPosition;
    float4x4 matView;
}
        

Mémoires tampons constantes par défaut

Il existe deux mémoires tampons constantes par défaut disponibles $Global et $Param. Les variables placées dans l’étendue globale sont ajoutées implicitement à cbuffer $Global, à l’aide de la même méthode d’empaquetage que celle utilisée pour les cbuffers. Les paramètres uniformes dans la liste des paramètres d’une fonction apparaissent dans la mémoire tampon constante $Param lorsqu’un nuanceur est compilé en dehors de l’infrastructure d’effets. Lorsqu’ils sont compilés à l’intérieur du framework d’effets, tous les uniformes doivent être résolus en variables définies dans l’étendue globale.

Exemples

Voici un exemple de Skinning10 Sample qui est une mémoire tampon de texture composée d’un tableau de matrices.

tbuffer tbAnimMatrices
{
    matrix g_mTexBoneWorld[MAX_BONE_MATRICES];
};
      

Cet exemple de déclaration affecte manuellement une mémoire tampon constante pour démarrer à un registre particulier, ainsi que des éléments particuliers par des sous-composants.

cbuffer MyBuffer : register(b3)
{
    float4 Element1 : packoffset(c0);
    float1 Element2 : packoffset(c1);
    float1 Element3 : packoffset(c1.y);
}
      

Modèle de nuanceur 4