Règles à virgule flottante (Direct3D 11)

Direct3D 11 prend en charge plusieurs représentations à virgule flottante. Tous les calculs à virgule flottante fonctionnent sous un sous-ensemble défini des règles ieee 754 32 bits à virgule flottante de précision unique.

Règles à virgule flottante 32 bits

Il existe deux ensembles de règles : celles qui sont conformes à IEEE-754 et celles qui s’écartent de la norme.

Règles IEEE-754 respectées

Certaines de ces règles sont une option unique où IEEE-754 offre des choix.

  • Diviser par 0 produit +/- INF, sauf 0/0 qui aboutit à NaN.
  • log of (+/-) 0 génère -INF. le journal d’une valeur négative (autre que -0) produit naN.
  • La racine carrée réciproque (rsq) ou la racine carrée (sqrt) d’un nombre négatif produit naN. L’exception est -0 ; sqrt(-0) produit -0 et rsq(-0) produit -INF.
  • INF - INF = NaN
  • (+/-) INF / (+/-)INF = NaN
  • (+/-) INF * 0 = NaN
  • NaN (n’importe quel OP) any-value = NaN
  • Les comparaisons EQ, GT, GE, LT et LE, lorsque l’un ou les deux opérandes sont NaN retourne FALSE.
  • Les comparaisons ignorent le signe 0 (donc +0 est égal à -0).
  • La comparaison NE, lorsque l’un ou les deux opérandes est NaN retourne TRUE.
  • Les comparaisons de toute valeur non NaN par rapport à +/- INF retournent le résultat correct.

Écarts ou exigences supplémentaires par rapport aux règles IEEE-754

  • IEEE-754 nécessite des opérations à virgule flottante pour produire un résultat qui est la valeur représentable la plus proche d’un résultat d’une précision infinie, connu sous le nom de round-à-nearest-even. Direct3D 11 définit la même exigence : les opérations à virgule flottante 32 bits produisent un résultat qui se trouve à 0,5 unité dernière place (ULP) du résultat de précision infinie. Cela signifie que, par exemple, le matériel est autorisé à tronquer les résultats en 32 bits plutôt qu’à effectuer un tour à un niveau égal, car cela entraînerait une erreur d’au plus 0,5 ULP. Cette règle s’applique uniquement à l’addition, à la soustraction et à la multiplication.

  • Il n’existe aucune prise en charge des exceptions à virgule flottante, status bits ou interruptions.

  • Les dénormes sont vidés au zéro conservé par les signes sur l’entrée et la sortie de toute opération mathématique à virgule flottante. Des exceptions sont effectuées pour toute opération d’E/S ou de déplacement de données qui ne manipule pas les données.

  • Les états qui contiennent des valeurs à virgule flottante, telles que les valeurs Viewport MinDepth/MaxDepth et BorderColor, peuvent être fournis en tant que valeurs dénorm et peuvent ou non être vidés avant que le matériel ne les utilise.

  • Les opérations min ou max vident les dénormes à des fins de comparaison, mais le résultat peut ou non être vidé.

  • L’entrée NaN d’une opération produit toujours le NaN sur la sortie. Toutefois, le modèle de bits exact du NaN n’est pas requis pour rester le même (sauf si l’opération est une instruction de déplacement brute qui ne modifie pas les données).)

  • Les opérations min ou max pour lesquelles un seul opérande est NaN retournent l’autre opérande comme résultat (contrairement aux règles de comparaison que nous avons examinées précédemment). Il s’agit d’une règle IEEE 754R.

    La spécification IEEE-754R pour les opérations min et max à virgule flottante indique que si l’une des entrées de min ou max est une valeur QNaN silencieuse, le résultat de l’opération est l’autre paramètre. Par exemple :

    min(x,QNaN) == min(QNaN,x) == x (same for max)
    

    Une révision de la spécification IEEE-754R a adopté un comportement différent pour min et max lorsqu’une entrée est une valeur SNaN de « signalisation » par rapport à une valeur QNaN :

    min(x,SNaN) == min(SNaN,x) == QNaN (same for max)
    
    

    En règle générale, Direct3D suit les normes pour l’arithmétique : IEEE-754 et IEEE-754R. Mais dans ce cas, nous avons une déviation.

    Les règles arithmétiques de Direct3D 10 et versions ultérieures n’effectuent aucune distinction entre les valeurs NaN silencieuses et de signalisation (QNaN et SNaN). Toutes les valeurs NaN sont gérées de la même façon. Dans le cas de min et max, le comportement Direct3D de toute valeur NaN est similaire à la façon dont QNaN est géré dans la définition IEEE-754R. (Pour l’exhaustivité : si les deux entrées sont NaN, toute valeur NaN est retournée.)

  • Une autre règle IEEE 754R est que min(-0,+0) == min(+0,-0) == -0, et max(-0,+0) == max(+0,-0) == +0, ce qui respecte le signe, contrairement aux règles de comparaison pour le zéro signé (comme nous l’avons vu précédemment). Direct3D recommande le comportement IEEE 754R ici, mais ne l’applique pas ; il est possible que le résultat de la comparaison de zéros dépende de l’ordre des paramètres, à l’aide d’une comparaison qui ignore les signes.

  • x*1.0f génère toujours x (à l’exception du dénorme vidé).

  • x/1.0f entraîne toujours x (sauf le dénorme vidé).

  • x +/- 0,0f entraîne toujours x (sauf le dénorme vidé). Mais -0 + 0 = +0.

  • Les opérations fusionnées (telles que mad, dp3) produisent des résultats qui ne sont pas moins précis que le pire ordre série possible d’évaluation de l’expansion non fusionnée de l’opération. La définition du pire classement possible, à des fins de tolérance, n’est pas une définition fixe pour une opération de fusion donnée; elle dépend des valeurs particulières des entrées. Les étapes individuelles de l’expansion non fusionnée sont chacune autorisées 1 tolérance ULP (ou pour toutes les instructions Direct3D appelle avec une tolérance plus laxiste que 1 ULP, plus la tolérance lax est autorisée).

  • Les opérations fusionnées respectent les mêmes règles NaN que les opérations non fusionnées.

  • sqrt et rcp ont une tolérance ULP 1. Les instructions de racine carrée réciproques et réciproques du nuanceur, rcp et rsq, ont leur propre exigence de précision détendue distincte.

  • La multiplication et la division fonctionnent chacune au niveau de précision à virgule flottante 32 bits (précision à 0,5 ULP pour la multiplication, 1,0 ULP pour la réciproque). Si x/y est implémenté directement, les résultats doivent être d’une précision supérieure ou égale à celle d’une méthode en deux étapes.

Règles à virgule flottante 64 bits (double précision)

Les pilotes matériels et d’affichage prennent éventuellement en charge la virgule flottante double précision. Pour indiquer la prise en charge, lorsque vous appelez ID3D11Device::CheckFeatureSupport avec D3D11_FEATURE_DOUBLES, le pilote définit DoublePrecisionFloatShaderOps de D3D11_FEATURE_DATA_DOUBLES sur TRUE. Le pilote et le matériel doivent ensuite prendre en charge toutes les instructions à virgule flottante double précision.

Les instructions de double précision respectent les exigences de comportement IEEE 754R.

La prise en charge de la génération de valeurs dénormalisées est requise pour les données de double précision (pas de comportement de vidage à zéro). De même, les instructions ne lisent pas les données dénormalisées sous la forme d’un zéro signé, elles respectent la valeur denorm.

Règles à virgule flottante 16 bits

Direct3D 11 prend également en charge les représentations 16 bits de nombres à virgule flottante.

Format:

  • 1 bits de signe (s)dans la position du bit MSB
  • 5 bits d’exposant biaisé (e)
  • 10 bits de fraction (f), avec un bit masqué supplémentaire

Une valeur float16 (v) suit ces règles :

  • si e == 31 et f != 0, alors v est NaN indépendamment de s
  • si e == 31 et f == 0, alors v = (-1)s*infinity (infini signé)
  • si e est compris entre 0 et 31, alors v = (-1)s*2(e-15)*(1.f)
  • si e == 0 et f != 0, alors v = (-1)s*2(e-14)*(0.f) (nombres dénormalisés)
  • si e == 0 et f == 0, alors v = (-1)s*0 (zéro signé)

Les règles à virgule flottante 32 bits tiennent également pour les nombres à virgule flottante 16 bits, ajustés pour la disposition de bits décrite précédemment. Les exceptions à cette règle sont les suivantes :

  • Précision : les opérations non fusionnées sur des nombres à virgule flottante 16 bits produisent un résultat qui est la valeur représentable la plus proche d’un résultat d’une précision infinie (même arrondi à plus proche, par IEEE-754, appliqué aux valeurs 16 bits). Les règles à virgule flottante 32 bits respectent une tolérance ULP 1, les règles à virgule flottante 16 bits respectent 0,5 ULP pour les opérations non fusionnées et 0,6 ULP pour les opérations fusionnées.
  • Les nombres à virgule flottante 16 bits préservent les dénormes.

Règles à virgule flottante 11 bits et 10 bits

Direct3D 11 prend également en charge les formats à virgule flottante 11 bits et 10 bits.

Format:

  • Aucun bit de signe
  • 5 bits d’exposant biaisé (e)
  • 6 bits de fraction (f) pour un format 11 bits, 5 bits de fraction (f) pour un format 10 bits, avec un bit masqué supplémentaire dans les deux cas.

Une valeur float11/float10 (v) suit les règles suivantes :

  • si e == 31 et f != 0, alors v est NaN
  • si e == 31 et f == 0, alors v = +infini
  • si e est compris entre 0 et 31, alors v = 2(e-15)*(1.f)
  • si e == 0 et f != 0, alors v = *2(e-14)*(0.f) (nombres dénormalisés)
  • si e == 0 et f == 0, alors v = 0 (zéro)

Les règles à virgule flottante 32 bits s’en tiennent également pour les nombres à virgule flottante 11 bits et 10 bits, ajustés pour la disposition de bits décrite précédemment. Voici certaines exceptions :

  • Précision : les règles à virgule flottante 32 bits respectent 0,5 ULP.
  • Les nombres à virgule flottante 10/11 bits préservent les dénormes.
  • Toute opération qui entraînerait un nombre inférieur à zéro est limitée à zéro.

Ressources

Textures