Limitations du contrôle de flux
Les instructions de contrôle de flux du nuanceur de pixels ont des limites qui affectent le nombre de niveaux d’imbrication pouvant être inclus dans les instructions. En outre, il existe certaines limitations pour l’implémentation du contrôle de flux par pixel avec des instructions de dégradé.
Notes
Lorsque vous utilisez les profils de nuanceur *_4_0_level_9_x HLSL, vous utilisez implicitement les profils de nuanceur modèle 2.x pour prendre en charge le matériel compatible Direct3D 9. Les profils du modèle de nuanceur 2.x prennent en charge un comportement de contrôle de flux plus limité que les profils shader model 4.x et versions ultérieures.
- Nombres de profondeurs des instructions du nuanceur de pixels
- Interaction du contrôle de flux Per-Pixel avec les dégradés d’écran
Nombres de profondeurs des instructions du nuanceur de pixels
ps_2_0 ne prend pas en charge le contrôle de flux. Les limitations des autres versions du nuanceur de pixels sont répertoriées ci-dessous.
Nombre de profondeurs d’instruction pour ps_2_x
Chaque instruction est comptabilisée par rapport à une ou plusieurs limites de profondeur d’imbrication. Le tableau suivant répertorie le nombre de profondeurs que chaque instruction ajoute ou soustrait de la profondeur existante.
Instruction | Imbrication statique | Imbrication dynamique | imbrication boucle/rep | imbrication des appels |
---|---|---|---|---|
si bool - ps | 1 | 0 | 0 | 0 |
if_comp - ps | 0 | 1 | 0 | 0 |
si pred - ps | 0 | 1 | 0 | 0 |
else - ps | 0 | 0 | 0 | 0 |
endif - ps | -1(si bool - ps) | -1(si préd - ps ou if_comp - ps) | 0 | 0 |
rep - ps | 0 | 0 | 1 | 0 |
endrep - ps | 0 | 0 | -1 | 0 |
break - ps | 0 | 0 | 0 | 0 |
break_comp - ps | 0 | 1, -1 | 0 | 0 |
breakp - ps | 0 | 0 | 0 | 0 |
call - ps | 0 | 0 | 0 | 1 |
callnz bool - ps | 0 | 0 | 0 | 1 |
callnz pred - ps | 0 | 1 | 0 | 1 |
ret - ps | 0 | -1(callnz pred - ps) | 0 | -1 |
setp_comp - ps | 0 | 0 | 0 | 0 |
Profondeur d’imbrication
La profondeur d’imbrication définit le nombre d’instructions pouvant être appelées les unes à l’intérieur des autres. Chaque type d’instruction a une ou plusieurs limites d’imbrication, comme indiqué dans le tableau suivant.
Type d’instruction | Maximum |
---|---|
Imbrication statique | 24 si (D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth > 0); 0 sinon |
Imbrication dynamique | 0 à 24, consultez D3DCAPS9. D3DPSHADERCAPS2_0.DynamicFlowControlDepth |
imbrication de rep | 0 à 4, consultez D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth |
imbrication des appels | 0 à 4, consultez D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth (indépendamment de la limite de rep) |
Nombre de profondeurs d’instruction pour ps_2_sw
Chaque instruction compte par rapport à une ou plusieurs limites de profondeur d’imbrication. Ce tableau montre le nombre de profondeurs que chaque instruction ajoute ou soustrait de la profondeur existante.
Instruction | Imbrication statique | Imbrication dynamique | imbrication de boucles/rep | imbrication des appels |
---|---|---|---|---|
if bool - ps | 1 | 0 | 0 | 0 |
si pred - ps | 0 | 1 | 0 | 0 |
if_comp - ps | 0 | 1 | 0 | 0 |
else - ps | 0 | 0 | 0 | 0 |
endif - ps | -1(si bool - ps) | -1(si pred - ps ou if_comp - ps) | 0 | 0 |
rep - ps | 0 | 0 | 1 | 0 |
endrep - ps | 0 | 0 | -1 | 0 |
boucle - ps | n/a | n/a | n/a | n/a |
endloop - ps | n/a | n/a | n/a | n/a |
break - ps | 0 | 0 | 0 | 0 |
break_comp - ps | 0 | 1, -1 | 0 | 0 |
breakp - ps | 0 | 0 | 0 | 0 |
call - ps | 0 | 0 | 0 | 1 |
callnz bool - ps | 0 | 0 | 0 | 1 |
callnz pred - ps | 0 | 1 | 0 | 1 |
ret - ps | 0 | -1(callnz pred - ps) | 0 | -1 |
setp_comp - ps | 0 | 0 | 0 | 0 |
Profondeur d’imbrication
La profondeur d’imbrication définit le nombre d’instructions qui peuvent être appelées l’une de l’autre. Chaque type d’instruction a une ou plusieurs limites d’imbrication, comme indiqué dans le tableau suivant.
Type d’instruction | Maximum |
---|---|
Imbrication statique | 24 |
Imbrication dynamique | 24 |
imbrication de rep | 4 |
imbrication des appels | 4 |
Nombre de profondeurs d’instruction pour ps_3_0
Chaque instruction compte par rapport à une ou plusieurs limites de profondeur d’imbrication. Ce tableau montre le nombre de profondeurs que chaque instruction ajoute ou soustrait de la profondeur existante.
Instruction | Imbrication statique | Imbrication dynamique | imbrication de boucles/rep | imbrication des appels |
---|---|---|---|---|
if bool - ps | 1 | 0 | 0 | 0 |
si pred - ps | 0 | 1 | 0 | 0 |
if_comp - ps | 0 | 1 | 0 | 0 |
else - ps | 0 | 0 | 0 | 0 |
endif - ps | -1(si bool - ps) | -1(si pred - ps ou if_comp - ps) | 0 | 0 |
rep - ps | 0 | 0 | 1 | 0 |
endrep - ps | 0 | 0 | -1 | 0 |
boucle - ps | 0 | 0 | 1 | 0 |
endloop - ps | 0 | 0 | -1 | 0 |
break - ps | 0 | 0 | 0 | 0 |
break_comp - ps | 0 | 1, -1 | 0 | 0 |
breakp - ps | 0 | 0 | 0 | 0 |
call - ps | 0 | 0 | 0 | 1 |
callnz bool - ps | 0 | 0 | 0 | 1 |
callnz pred - ps | 0 | 1 | 0 | 1 |
ret - ps | 0 | -1(callnz pred - ps) | 0 | -1 |
setp_comp - ps | 0 | 0 | 0 | 0 |
Profondeur d’imbrication
La profondeur d’imbrication définit le nombre d’instructions qui peuvent être appelées les unes à l’intérieur des autres. Chaque type d’instruction a une ou plusieurs limites d’imbrication, comme indiqué dans le tableau suivant.
Type d’instruction | Maximum |
---|---|
Imbrication statique | 24 |
Imbrication dynamique | 24 |
imbrication boucle/rep | 4 |
imbrication des appels | 4 |
Nombre de profondeurs d’instruction pour ps_3_sw
Chaque instruction est comptabilisée par rapport à une ou plusieurs limites de profondeur d’imbrication. Ce tableau montre le nombre de profondeurs que chaque instruction ajoute ou soustrait de la profondeur existante.
Instruction | Imbrication statique | Imbrication dynamique | imbrication boucle/rep | imbrication des appels |
---|---|---|---|---|
si bool - ps | 1 | 0 | 0 | 0 |
si pred - ps | 0 | 1 | 0 | 0 |
if_comp - ps | 0 | 1 | 0 | 0 |
else - ps | 0 | 0 | 0 | 0 |
endif - ps | -1(si bool - ps) | -1(si préd - ps ou if_comp - ps) | 0 | 0 |
rep - ps | 0 | 0 | 1 | 0 |
endrep - ps | 0 | 0 | -1 | 0 |
boucle - ps | 0 | 0 | 1 | 0 |
endloop - ps | 0 | 0 | -1 | 0 |
break - ps | 0 | 0 | 0 | 0 |
break_comp - ps | 0 | 1, -1 | 0 | 0 |
breakp - ps | 0 | 0 | 0 | 0 |
call - ps | 0 | 0 | 0 | 1 |
callnz bool - ps | 0 | 0 | 0 | 1 |
callnz pred - ps | 0 | 1 | 0 | 1 |
ret - ps | 0 | -1(callnz pred - ps) | 0 | -1 |
setp_comp - ps | 0 | 0 | 0 | 0 |
Profondeur d’imbrication
La profondeur d’imbrication définit le nombre d’instructions qui peuvent être appelées l’une de l’autre. Chaque type d’instruction a une ou plusieurs limites d’imbrication, comme indiqué dans le tableau suivant.
Type d’instruction | Maximum |
---|---|
Imbrication statique | 24 |
Imbrication dynamique | 24 |
imbrication de boucles/rep | 4 |
imbrication des appels | 4 |
Interaction du contrôle de flux Per-Pixel avec les dégradés d’écran
Le jeu d’instructions du nuanceur de pixels comprend plusieurs instructions qui produisent ou utilisent des dégradés de quantités par rapport à l’espace d’écran x et y. L’utilisation la plus courante des dégradés consiste à calculer des calculs de niveau de détail pour l’échantillonnage de texture et, dans le cas d’un filtrage anisotropique, à sélectionner des échantillons le long de l’axe de l’anisotropie. En règle générale, les implémentations matérielles exécutent le nuanceur de pixels sur plusieurs pixels simultanément (par exemple, une grille de 2x2), de sorte que les dégradés de quantités calculées dans le nuanceur peuvent être raisonnablement approximatifs en tant que deltas des valeurs au même point d’exécution dans les pixels adjacents.
Lorsque le contrôle de flux est présent dans un nuanceur, le résultat d’un calcul de dégradé demandé à l’intérieur d’un chemin de branche donné est ambigu lorsque des pixels adjacents peuvent exécuter des chemins de contrôle de flux distincts. Par conséquent, il est jugé illégal d’utiliser une opération de nuanceur de pixels qui demande qu’un calcul de dégradé se produise à un emplacement qui se trouve à l’intérieur d’une construction de contrôle de flux qui peut varier d’un pixel à l’autre pour une primitive donnée en cours de rastérisation.
Toutes les instructions du nuanceur de pixels sont partitionnés dans les opérations autorisées et dans celles qui ne sont pas autorisées à l’intérieur du contrôle de flux :
Scénario A : opérations qui ne sont pas autorisées à l’intérieur du contrôle de flux qui peuvent varier sur les pixels d’une primitive. Il s’agit notamment des opérations répertoriées dans le tableau suivant.
Instruction Est autorisé dans le contrôle de flux dans les cas suivants : texld - ps_2_0 et up, texldb - ps et texldp - ps Un registre temporaire est utilisé pour la coordonnée de texture. dsx - ps and dsy - ps Un registre temporaire est utilisé pour l’opérande. Scénario B : opérations autorisées n’importe où. Il s’agit notamment des opérations répertoriées dans le tableau suivant.
Instruction Est autorisé n’importe où dans les cas suivants : texld - ps_2_0 et up, texldb - ps et texldp - ps Une quantité en lecture seule est utilisée pour la coordonnée de texture (peut varier par pixel, comme les coordonnées de texture interpolées). dsx - ps and dsy - ps Une quantité en lecture seule est utilisée pour l’opérande d’entrée (peut varier par pixel, comme les coordonnées de texture interpolées). texldl - ps L’utilisateur fournit le niveau de détail en tant qu’argument, de sorte qu’il n’y a pas de dégradés et donc pas de problème avec le contrôle de flux. texldd - ps L’utilisateur fournit des dégradés comme arguments d’entrée. Il n’y a donc aucun problème avec le contrôle de flux.
Ces restrictions sont strictement appliquées dans la validation du nuanceur. Les scénarios ayant une condition de branche qui ressemble à une branche de branche de façon cohérente sur une primitive, même si un opérande dans l’expression de condition est une quantité calculée par un nuanceur de pixels, toujours dans le scénario A et ne sont pas autorisés. De même, les scénarios où des dégradés sont demandés sur une quantité x calculée par nuanceur à partir du contrôle de flux dynamique, mais où il semble que x n’est modifié sur aucune des branches, tombent néanmoins toujours dans le scénario A et ne sont pas autorisés.
La prédication est incluse dans ces restrictions sur le contrôle de flux, de sorte que les implémentations restent libres d’échanger trivialement l’implémentation d’instructions de branche avec des instructions prédicées.
L’utilisateur peut utiliser les instructions des scénarios A et B ensemble. Par exemple, supposons que l’utilisateur a besoin d’un exemple de texture anisotrope en fonction d’une coordonnée de texture calculée par nuanceur ; Toutefois, la charge de texture n’est nécessaire que pour les pixels qui satisfont à certaines conditions par pixel. Pour répondre à ces exigences, l’utilisateur peut calculer la coordonnée de texture pour tous les pixels, en dehors du contrôle de flux variable par pixel, en calculant immédiatement les dégradés à l’aide des instructions dsx - ps et dsy - ps . Ensuite, dans un bloc par pixel si bool - ps/endif - bloc ps , l’utilisateur peut utiliser texldd - ps (charge de texture avec des dégradés fournis par l’utilisateur), en passant les dégradés précalculés. Une autre façon de décrire ce modèle d’utilisation est que, alors que tous les pixels de la primitive devaient calculer les coordonnées de texture et être impliqués dans le calcul du dégradé, seuls les pixels qui avaient besoin d’échantillonner une texture l’ont réellement fait.
Quelles que soient ces règles, il incombe toujours à l’utilisateur de s’assurer qu’avant de calculer un gradient (ou d’effectuer un exemple de texture qui calcule implicitement un dégradé), le registre contenant les données sources doit avoir été initialisé pour tous les chemins d’exécution au préalable. L’initialisation des registres temporaires n’est pas validée ou appliquée en général.
Rubriques connexes