Limitations du contrôle Flow

Les instructions de contrôle de flux du nuanceur de pixels ont des limites qui affectent le nombre de niveaux d’imbrication qui peuvent ê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 HLSL *_4_0_level_9_x, vous utilisez implicitement les profils shader Model 2.x pour prendre en charge le matériel compatible Direct3D 9. Les profils shader Model 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 d’instruction 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’instructions 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 de boucles/rep imbrication des appels
if bool - ps 1 0 0 0
if_comp - ps 0 1 0 0
si préd - ps 0 1 0 0
else - ps 0 0 0 0
endif - ps -1(if 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
appel - 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 de l’intérieur les unes des autres. Chaque type d’instruction a une ou plusieurs limites d’imbrication, comme indiqué dans le tableau suivant.

Type d’instruction Maximale
Imbrication statique 24 si (D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth > 0); 0 sinon
Imbrication dynamique 0 à 24, voir D3DCAPS9. D3DPSHADERCAPS2_0.DynamicFlowControlDepth
imbrication de rep 0 à 4, voir D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth
imbrication des appels 0 à 4, voir D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth (indépendamment de la limite de rep)

 

Nombre de profondeurs d’instruction pour ps_2_sw

Chaque instruction est comptabilisée par rapport à une ou plusieurs limites de profondeur d’imbrication. Ce tableau indique 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 préd - ps 0 1 0 0
if_comp - ps 0 1 0 0
else - ps 0 0 0 0
endif - ps -1(if 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 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
appel - 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 entre elles. Chaque type d’instruction a une ou plusieurs limites d’imbrication, comme indiqué dans le tableau suivant.

Type d’instruction Maximale
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 est comptabilisée par rapport à une ou plusieurs limites de profondeur d’imbrication. Ce tableau indique 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 préd - ps 0 1 0 0
if_comp - ps 0 1 0 0
else - ps 0 0 0 0
endif - ps -1(if 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
appel - 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 entre elles. Chaque type d’instruction a une ou plusieurs limites d’imbrication, comme indiqué dans le tableau suivant.

Type d’instruction Maximale
Imbrication statique 24
Imbrication dynamique 24
imbrication de boucles/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 indique 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 préd - ps 0 1 0 0
if_comp - ps 0 1 0 0
else - ps 0 0 0 0
endif - ps -1(if 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
appel - 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 entre elles. Chaque type d’instruction a une ou plusieurs limites d’imbrication, comme indiqué dans le tableau suivant.

Type d’instruction Maximale
Imbrication statique 24
Imbrication dynamique 24
imbrication de boucles/rep 4
imbrication des appels 4

 

Interaction du contrôle Per-Pixel Flow avec des dégradés d’écran

L’ensemble d’instructions du nuanceur de pixels inclut 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 pour les 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, en sélectionnant des échantillons le long de l’axe de l’anisotropie. En règle générale, les implémentations matérielles exécutent simultanément le nuanceur de pixels sur plusieurs pixels (comme une grille 2x2), afin que les dégradés de quantités calculées dans le nuanceur puissent ê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 les pixels adjacents peuvent exécuter des chemins de contrôle de flux distincts. Par conséquent, il est considéré comme illégal d’utiliser toute opération de nuanceur de pixels qui demande un calcul de dégradé à se produire à un emplacement situé à l’intérieur d’une construction de contrôle de flux qui peut varier d’un pixel à l’autre pour une primitive donnée ratérisée.

Toutes les instructions de nuanceur de pixels sont partitionnée en ces 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 en pixels dans une primitive. Celles-ci incluent les opérations répertoriées dans le tableau suivant.

    Instruction Est autorisé dans Flow contrôle quand :
    texld - ps_2_0 et haut, texldb - ps et texldp - ps Un registre temporaire est utilisé pour la coordonnée de texture.
    dsx - ps et dsy - ps Un registre temporaire est utilisé pour l’opérande.

     

  • Scénario B : opérations autorisées n’importe où. Celles-ci incluent les opérations répertoriées dans le tableau suivant.

    Instruction Est autorisé n’importe où quand :
    texld - ps_2_0 et haut, 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 et 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 un niveau de détail en tant qu’argument, de sorte qu’il n’y a pas de dégradés, et donc aucun problème avec le contrôle de flux.
    texldd - ps L’utilisateur fournit des dégradés en tant qu’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 semblable à celle-ci se branchent de manière cohérente sur une primitive, même si un opérande dans l’expression de condition est une quantité calculée par pixels, néanmoins tombent toujours dans le scénario A et ne sont pas autorisés. De même, les scénarios où les dégradés sont demandés sur une quantité calculée par nuanceur x à partir du contrôle de flux dynamique, mais où il semble que x n’est pas modifié dans l’une des branches, reste 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, afin que les implémentations restent libres d’échanger facilement l’implémentation des instructions de branche avec des instructions prédicées.

L’utilisateur peut utiliser des instructions des scénarios A et B ensemble. Par exemple, supposons que l’utilisateur a besoin d’un échantillon de texture anisotropique en fonction d’une coordonnée de texture calculée du nuanceur ; Toutefois, la charge de texture n’est nécessaire que pour les pixels répondant à une condition 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, calculer immédiatement des dégradés à l’aide dsx - ps et dsy - instructions ps . Ensuite, dans un bloc bool par pixel si bool -psendif - 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, même si tous les pixels de la primitive ont dû calculer les coordonnées de texture et être impliqués dans le calcul du dégradé, seuls les pixels nécessaires pour échantillonner une texture l’ont fait réellement.

Indépendamment de ces règles, la charge est toujours sur l’utilisateur pour s’assurer qu’avant de calculer un dégradé (ou d’effectuer un échantillon 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.

Instructions du nuanceur de pixels