Partager via


Modèle de nuanceur 3 (référence HLSL)

Les nuanceurs de vertex et les nuanceurs de pixels sont considérablement simplifiés à partir des versions antérieures du nuanceur. Si vous implémentez des nuanceurs dans le matériel, vous ne pouvez pas utiliser vs_3_0 ou ps_3_0 avec d’autres versions de nuanceur, et vous ne pouvez pas utiliser l’un ou l’autre type de nuanceur avec le pipeline de fonction fixe. Ces modifications permettent de simplifier les pilotes et le runtime. La seule exception est que les nuanceurs de vs_3_0 logiciels uniquement peuvent être utilisés avec n’importe quelle version du nuanceur de pixels. En outre, si vous utilisez un nuanceur de vs_3_0 logiciel uniquement avec une version précédente du nuanceur de pixels, le nuanceur de vertex ne peut utiliser que la sémantique de sortie compatible avec les codes de format de vertex flexible (FVF).

La sémantique utilisée sur les sorties du nuanceur de vertex doit être utilisée sur les entrées du nuanceur de pixels. La sémantique est utilisée pour mapper les sorties du nuanceur de vertex aux entrées du nuanceur de pixels, de la même manière que la déclaration de vertex est mappée aux registres d’entrée du nuanceur de vertex et aux modèles de nuanceur précédents. Consultez Correspondance sémantique sur les nuanceurs 3.0 et ps 3.0.

Des états de rendu du mode wrap supplémentaires ont été ajoutés pour couvrir la possibilité de coordonnées de texture supplémentaires dans ce nouveau schéma. Les attributs avec D3DDECLUSAGE_TEXCOORD et l’index d’utilisation de 0 à 15 sont interpolés en mode wrap lorsque le D3DRS_WRAP* correspondant est défini.

Fonctionnalités du nuanceur de vertex modèle 3

Les types de registre de sortie du nuanceur de vertex ont été réduits en douze registres (voir Registres de sortie). Chaque registre utilisé doit être déclaré à l’aide de l’instruction dcl et d’une sémantique (par exemple, dcl_color0 o0.xyzw).

Le modèle de nuanceur de vertex 3_0 (vs_3_0) s’étend sur les fonctionnalités de vs_2_0 avec une indexation de registre plus puissante, un ensemble de registres de sortie simplifiés, la possibilité d’échantillonner une texture dans un nuanceur de vertex et la possibilité de contrôler la vitesse à laquelle les entrées de nuanceur sont initialisées.

Indexer n’importe quel registre

Tous les registres ( registre d’entrée et registres de sortie) peuvent être indexés à l’aide du registre du compteur de boucles (seuls les registres constants peuvent être indexés dans les versions antérieures).)

Vous devez déclarer les registres d’entrée et de sortie avant de les indexer. Toutefois, vous ne pouvez indexer aucun registre de sortie qui a été déclaré avec une sémantique de position ou de taille de point. En fait, si l’indexation est utilisée, la sémantique position et psize doivent être déclarées dans les registres o0 et o1 respectivement.

Vous n’êtes autorisé à indexer qu’une plage continue de registres ; autrement dit, vous ne pouvez pas indexer entre des registres qui n’ont pas été déclarés. Bien que cette restriction puisse être gênante, elle permet l’optimisation matérielle. Si vous tentez d’indexer des registres non contigus, vous obtiendrez des résultats non définis. La validation du nuanceur n’applique pas cette restriction.

Simplifier les registres de sortie

Tous les différents types de registres de sortie ont été réduits en douze registres de sortie : 1 pour la position, 2 pour la couleur, 8 pour la texture et 1 pour le brouillard ou la taille de point. Ces registres interpolent toutes les données qu’ils contiennent pour le nuanceur de pixels. Les déclarations de registre de sortie sont requises et la sémantique est affectée à chaque registre.

Les registres peuvent être répartis comme suit :

  • Au moins un registre doit être déclaré en tant que registre de position à quatre composants. Il s’agit du seul registre de nuanceur de vertex requis.
  • Les dix premiers registres consommés par un nuanceur peuvent utiliser jusqu’à quatre composants (xyzw) au maximum.
  • Le dernier (ou douzième) registre ne peut contenir qu’un scalaire (par exemple, une taille de point).

Pour obtenir la liste des registres, consultez Registres - vs_3_0.

Exemple de texture dans un nuanceur de vertex

Le nuanceur de vertex 3_0 prend en charge la recherche de texture dans le nuanceur de vertex à l’aide de texldl - vs.

Fonctionnalités du modèle de nuanceur de pixels 3

Les registres de couleur et de texture du nuanceur de pixels ont été réduits en dix registres d’entrée (voir Types de registre d’entrée). Le registre visage est un registre scalaire à virgule flottante. Seul le signe de ce registre est valide. Si le signe est négatif, la primitive est une face arrière. Il peut être utilisé à l’intérieur d’un nuanceur de pixels pour obtenir un éclairage à deux côtés, pour instance. Le registre de position fait référence aux pixels actuels (x,y).

Les registres de constantes du nuanceur peuvent être définis à l’aide de :

Faire correspondre la sémantique sur les nuanceurs vs_3_0 et ps_3_0

Il existe certaines restrictions sur l’utilisation sémantique avec vs_3_0 et ps_3_0. En général, vous devez être prudent lorsque vous utilisez une sémantique pour une entrée de nuanceur qui correspond à une sémantique utilisée sur une sortie de nuanceur.

Par instance, ce nuanceur de pixels contient plusieurs noms dans un même registre :

ps_3_0 
dcl_texcoord0 v0.x 
dcl_texcoord1 v0.yz // Valid to pack multiple names into one register 
dcl_texcoord2_centroid v1.w
...

Chaque registre a une sémantique différente. Notez que vous pouvez également nommer v0.x et v0.yz avec une sémantique différente (multiple) en raison de l’utilisation du masque d’écriture.

Étant donné le nuanceur de pixels, le nuanceur de vs_3_0 suivant ne peut pas être associé à celui-ci :

vs_3_0 
... 
dcl_texcoord0 o5.x 
dcl_texcoord1 o6.yzw 
...

Ces deux nuanceurs entrent en conflit avec leur utilisation de la sémantique D3DDECLUSAGE_TEXCOORD0 Et D3DDECLUSAGE_TEXCOORD1 .

Réécrire le nuanceur de vertex comme suit pour éviter la collision sémantique :

vs_3_0 
... 
dcl_texcoord2 o3 
dcl_texcoord3 o9 
...

De même, un nom sémantique déclaré sur différents registres d’entrée dans le nuanceur de pixels (v0 et v1 dans le nuanceur de pixels) ne peut pas être utilisé dans un registre de sortie unique dans ce nuanceur de vertex. Par instance, ce nuanceur de vertex ne peut pas être associé au nuanceur de pixels, car D3DDECLUSAGE_TEXCOORD1 est utilisé pour les registres d’entrée du nuanceur de pixels (v0, v1) et le registre de sortie du nuanceur de vertex o3.

vs_3_0 
... 
dcl_texcoord0 o3.x 
dcl_texcoord1 o3.yz 

dcl_texcoord2 o3.w // BAD! Would be valid if this were not o3 
dcl_texcoord3 o9 ... 

En revanche, ce nuanceur de vertex ne peut pas être associé au nuanceur de pixels, car le masque de sortie d’un paramètre avec une sémantique donnée ne fournit pas les données demandées par le nuanceur de pixels :

vs_3_0 
... 
dcl_texcoord0 o5.x 
dcl_texcoord1 o5.yzw 
dcl_texcoord2 o7.yz // BAD! Would be valid if w were included 
dcl_texcoord3 o9 
... 

Ce nuanceur de vertex ne fournit pas de sortie avec l’un des noms sémantiques demandés par le nuanceur de pixels, de sorte que le couplage du nuanceur n’est pas valide :

vs_3_0 
... 
dcl_texcoord0 o5.x 
dcl_texcoord1 o5.yzw 
dcl_texcoord3 o9 
// The pixel shader wants texcoord2, with a w component, 
// but it isn't output by this vertex shader at all! 
... 

Modifications du mode brouillard, profondeur et ombrage

Lorsque D3DRS_SHADEMODE est défini pour l’ombrage plat lors de la découpage et de la rastérisation de triangles, les attributs avec D3DDECLUSAGE_COLOR sont interpolés en tant que nuances plates. Si des composants d’un registre sont déclarés avec une sémantique de couleur, mais que d’autres composants du même registre reçoivent une sémantique différente, l’interpolation de fond plat (linéaire ou plat) ne sera pas définie sur les composants de ce registre sans sémantique de couleur.

Si le rendu du brouillard est souhaité, les nuanceurs vs_3_0 et ps_3_0 doivent implémenter le brouillard. Aucun calcul de brouillard n’est effectué en dehors des nuanceurs. Il n’y a pas de registre de brouillard dans vs_3_0, et des sémantiques supplémentaires D3DDECLUSAGE_FOG (pour le facteur de mélange de brouillard calculé par sommet) et D3DDECLUSAGE_DEPTH (pour passer une valeur de profondeur au nuanceur de pixels pour calculer le facteur de fusion de brouillard) ont été ajoutés.

L’état de l’étape de texture D3DTSS_TEXCOORDINDEX est ignoré lors de l’utilisation du nuanceur de pixels 3.0.

Les valeurs suivantes ont été ajoutées pour prendre en charge ces modifications :

// Fog and Depth usages
D3DDECLUSAGE_FOG 
D3DDECLUSAGE_DEPTH 

// Additional wrap states for vs_3_0 attributes with D3DDECLUSAGE_TEXCOORD 
D3DRS_WRAP8 
D3DRS_WRAP9 
D3DRS_WRAP10 
D3DRS_WRAP11 
D3DRS_WRAP12 
D3DRS_WRAP13 
D3DRS_WRAP14 
D3DRS_WRAP15

Conversions à virgule flottante et entière

Les mathématiques à virgule flottante se produisent à différentes précisions et plages (16 bits, 24 bits et 32 bits) dans différentes parties du pipeline. Une valeur supérieure à la plage dynamique du pipeline qui entre dans ce pipeline (par exemple, une carte de texture float 32 bits est échantillonnée dans un pipeline float 24 bits dans ps_2_0) crée un résultat non défini. Pour un comportement prévisible, vous devez fixer une telle valeur au maximum de la plage dynamique.

La conversion d’une valeur à virgule flottante en entier se produit à plusieurs endroits, par exemple :

  • Lors de la rencontre d’une instruction mova - vs .
  • Pendant l’adressage de texture.
  • Lors de l’écriture dans une cible de rendu à virgule non flottante.

Spécification d’une précision totale ou partielle

Les ps_3_0 et les ps_2_x prennent en charge deux niveaux de précision :

ps_3_0 ps_2_0 Precision Valeur
x Complète fp32 ou version ultérieure
x Précision partielle fp16=s10e5
x x Complète fp24=s16e7 ou version ultérieure
x x Précision partielle fp16=s10e5

 

ps_3_0 prend en charge plus de précision que ps_2_0. Par défaut, toutes les opérations se produisent au niveau de précision totale.

La précision partielle (voir Modificateurs de registre du nuanceur de pixels) est demandée en ajoutant le modificateur _pp au code du nuanceur (à condition que l’implémentation sous-jacente le prenne en charge). Les implémentations sont toujours libres d’ignorer le modificateur et d’effectuer les opérations affectées en toute précision.

Le modificateur _pp peut se produire dans deux contextes :

  • Sur une déclaration de coordonnées de texture pour passer des coordonnées de texture de précision partielle au nuanceur de pixels. Cela peut être utilisé lorsque les coordonnées de texture transmettent les données de couleur au nuanceur de pixels, ce qui peut être plus rapide avec une précision partielle qu’avec une précision totale dans certaines implémentations.
  • Sur n’importe quelle instruction pour demander l’utilisation d’une précision partielle, y compris des instructions de chargement de texture. Cela indique que l’implémentation est autorisée à exécuter l’instruction avec une précision partielle et à stocker un résultat de précision partielle. En l’absence d’un modificateur explicite, l’instruction doit être exécutée à pleine précision (quelle que soit la précision des opérandes d’entrée).

Une application peut choisir délibérément de trouver un compromis entre la précision et les performances. Il existe plusieurs types de données d’entrée de nuanceur qui sont des candidats naturels pour le traitement de précision partielle :

  • Les itérateurs de couleurs sont bien représentés par des valeurs de précision partielle.
  • Les valeurs de texture de la plupart des formats peuvent être représentées avec précision partielle (les valeurs échantillonnées à partir de textures de format à virgule flottante 32 bits constituent une exception évidente).
  • Les constantes peuvent être représentées par une représentation de précision partielle en fonction du nuanceur.

Dans tous ces cas, le développeur peut choisir de spécifier une précision partielle pour traiter les données, sachant qu’aucune précision des données d’entrée n’est perdue. Dans certains cas, un nuanceur peut exiger que les étapes internes d’un calcul soient effectuées à pleine précision, même lorsque les valeurs d’entrée et de sortie finale n’ont pas plus de précision partielle.

Nuanceurs de vertex et de pixels logiciels

Les implémentations logicielles (runtime et référence pour les nuanceurs de vertex et référence pour les nuanceurs de pixels) des nuanceurs de version 2_0 et ultérieures ont une certaine validation assouplie. Cela est utile à des fins de débogage et de prototypage. L’application indique au runtime/assembleur qu’elle doit assouplir une partie de la validation à l’aide de l’indicateur _sw dans l’assembleur (par exemple, vs_2_sw). Un nuanceur logiciel ne fonctionne pas avec le matériel.

vs_2_sw est un relâchement jusqu’à la limite maximale de vs_2_x; de même, ps_2_sw est un relâchement jusqu’à la limite maximale de ps_2_x. Plus précisément, les validations suivantes sont assouplies :

Modèle nuanceur Ressource Limite
vs_2_sw, vs_3_sw, ps_2_sw, ps_3_sw Nombre d’instructions Illimité
vs_2_sw, vs_3_sw, ps_2_sw, ps_3_sw Registres de constante float 8 192
vs_2_sw, vs_3_sw, ps_2_sw, ps_3_sw Registres de constantes entières 2 048
vs_2_sw, vs_3_sw, ps_2_sw, ps_3_sw Registres de constantes booléennes 2 048
ps_2_sw Profondeur de lecture dépendante Illimité
vs_2_sw instructions et étiquettes de contrôle de flux Illimité
vs_2_sw, vs_3_sw, ps_2_sw, ps_3_sw Démarrage/étape/nombre de boucles Le début de l’itération et la taille de l’étape d’itération pour les instructions de rep et de boucle sont des entiers signés 32 bits. Le nombre peut aller jusqu’à MAX_INT/64.
vs_2_sw, vs_3_sw, ps_2_sw, ps_3_sw Limites de port Les limites de port pour tous les fichiers de registre sont assouplies.
vs_3_sw Nombre d’interpolateurs 16 registres de sortie dans vs_3_sw.
ps_3_sw Nombre d’interpolateurs 14(16-2) inscriptions d’entrée pour ps_3_sw.

 

Modèle de nuanceur 3 (DirectX HLSL)