Partager via


Règles de conversion de données

Les sections suivantes décrivent comment Direct3D gère les conversions entre les types de données.

Terminologie du type de données

L’ensemble de termes suivant est ensuite utilisé pour caractériser différentes conversions de format.

Terme Définition
SNORM Entier normalisé signé, ce qui signifie que pour le nombre de compléments n bits 2, la valeur maximale signifie 1,0f (par exemple, la valeur 5 bits 01111 correspond à 1,0f) et la valeur minimale signifie -1,0f (par exemple, la valeur 5 bits 10000 correspond à -1,0f). En outre, le deuxième nombre minimal est mappé à -1,0f (par exemple, la valeur 5 bits 10001 correspond à -1,0f). Il existe donc deux représentations entières pour -1.0f. Il existe une représentation unique pour 0.0f et une représentation unique pour 1.0f. Cela entraîne un ensemble de représentations entières pour les valeurs à virgule flottante uniformément espacées dans la plage (-1.0f... 0,0f), ainsi qu’un ensemble complémentaire de représentations pour les nombres de la plage (0,0f... 1.0f)
UNORM Entier normalisé non signé, ce qui signifie que pour un nombre n bits, tous les 0 signifient 0,0f, et tous les 1 signifient 1,0f. Une séquence de valeurs à virgule flottante uniformément espacées de 0,0f à 1,0f est représentée. Par exemple, un UNORM 2 bits représente 0,0f, 1/3, 2/3 et 1.0f.
SINT Entier signé. entier de complément 2. Par exemple, un SINT 3 bits représente les valeurs intégrales -4, -3, -2, -1, 0, 1, 2, 3.
UINT Entier non signé. Par exemple, un UINT 3 bits représente les valeurs intégrales 0, 1, 2, 3, 4, 5, 6, 7.
FLOTTER Valeur à virgule flottante dans l’une des représentations définies par Direct3D.
SRGB Similaire à UNORM, dans ce cas pour un nombre n bits, tous les 0 signifient 0,0f et tous les 1 signifie 1,0f. Toutefois, contrairement à UNORM, avec SRVB la séquence d’encodages entiers non signés entre toutes les 0 à toutes les 1 représentent une progression non linéaire dans l’interprétation à virgule flottante des nombres, entre 0,0f et 1,0f. À peu près, si cette progression non linéaire, SRVB, est affichée sous forme de séquence de couleurs, elle apparaît comme une rampe linéaire de niveaux de luminosité à un observateur « moyen », sous des conditions d’affichage « moyenne », sur un affichage « moyen ». Pour plus d’informations, reportez-vous à la norme de couleur SRGB, IEC 61996-2-1, à la IEC (Commission électrotechnique internationale).

 

Conversion à virgule flottante

Chaque fois qu’une conversion à virgule flottante entre différentes représentations se produit, y compris vers ou depuis des représentations à virgule flottante, les règles suivantes s’appliquent.

Conververting from a higher range representation to a lower range representation

  • L’arrondi à zéro est utilisé lors de la conversion vers un autre format float. Si la cible est un format entier ou à point fixe, round-to-near-even est utilisé, sauf si la conversion est explicitement documentée comme utilisant un autre comportement d’arrondi, tel que round-to-near pour FLOAT to SNORM, FLOAT to UNORM ou FLOAT to SRGB. D’autres exceptions sont les instructions de nuanceur ftoi et ftou, qui utilisent round-to-zero. Enfin, les conversions float-to-fixed utilisées par l’échantillonneur de texture et le rastériseur ont une tolérance spécifiée mesurée dans Unit-Last-Place d’un idéal infiniment précis.
  • Pour les valeurs sources supérieures à la plage dynamique d’un format cible de plage inférieure (par exemple, une grande valeur flottante 32 bits est écrite dans un RenderTarget flottant 16 bits), les résultats de valeur pouvant être représentées (correctement signés), PAS y compris l’infini signé (en raison de l’arrondi à zéro décrit ci-dessus).
  • NaN dans un format de plage supérieur est converti en représentation NaN au format de plage inférieur si la représentation NaN existe dans le format de plage inférieur. Si le format inférieur n’a pas de représentation NaN, le résultat est 0.
  • Inf dans un format de plage plus élevé sera converti en INF au format de plage inférieur si disponible. Si le format inférieur n’a pas de représentation INF, il est converti en valeur maximale pouvant être représentée. Le signe est conservé s’il est disponible dans le format cible.
  • Denorm dans un format de plage plus élevé sera converti en représentation Denorm au format de plage inférieure si disponible dans le format de plage inférieure et la conversion est possible, sinon le résultat est 0. Le bit de signe est conservé s’il est disponible au format cible.

Conversion d’une représentation de plage inférieure en représentation de plage supérieure

  • NaN dans un format de plage inférieur est converti en représentation NaN au format de plage supérieur s’il est disponible dans le format de plage supérieur. Si le format de plage supérieur n’a pas de représentation NaN, il est converti en 0.
  • INF dans un format de plage inférieur est converti en représentation INF au format de plage supérieur s’il est disponible dans le format de plage supérieur. Si le format supérieur n’a pas de représentation INF, il est converti en valeur maximale pouvant être représentée (MAX_FLOAT dans ce format). Le signe est conservé s’il est disponible dans le format cible.
  • Le dénorm dans un format de plage inférieur est converti en représentation normalisée au format de plage supérieur si possible, ou en représentation dénorm au format de plage supérieur si la représentation Denorm existe. En cas d’échec, si le format de plage supérieur n’a pas de représentation dénorm, il est converti en 0. Le signe est conservé s’il est disponible dans le format cible. Notez que les nombres flottants 32 bits sont comptabilisés sous la forme d’un format sans représentation dénorm (car les dénorms dans les opérations sur les flotteurs 32 bits sont vidés pour signer la valeur 0 conservée).

Conversion d’entiers

Le tableau suivant décrit les conversions de différentes représentations décrites ci-dessus vers d’autres représentations. Seules les conversions qui se produisent réellement dans Direct3D sont affichées.

Type de données source Type de données de destination Règle de conversion
SNORM FLOTTER Étant donné une valeur entière n bits représentant la plage signée [-1.0f à 1.0f], la conversion en virgule flottante est la suivante.
  • La valeur la plus négative correspond à -1,0f. Par exemple, la valeur 5 bits 10000 correspond à -1.0f.
  • Chaque autre valeur est convertie en float (appelez-la c), puis result = c * (1.0f / (2⁽ⁿ⁻¹⁾-1)). Par exemple, la valeur 5 bits 10001 est convertie en -15.0f, puis divisée par 15.0f, ce qui génère -1.0f.
FLOTTER SNORM Étant donné un nombre à virgule flottante, la conversion en valeur entière n bits représentant la plage signée [-1.0f à 1.0f] est la suivante.
  • Laissez c représenter la valeur de départ.
  • Si c est NaN, le résultat est 0.
  • Si c > 1.0f, y compris INF, il est limité à 1,0f.
  • Si c < -1.0f, y compris -INF, il est limité à -1.0f.
  • Convertir de l’échelle flottante à l’échelle entière : c = c * (2ⁿ⁻¹-1).
  • Convertissez en entier comme suit.
    • Si c >= 0, c = c + 0,5f, sinon, c = c - 0,5f.
    • Supprimez la fraction décimale et la valeur flottante restante (intégrale) est convertie directement en entier.
Cette conversion est autorisée à une tolérance de D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_Unit-Last-Place Unit-Last-Place (côté entier). Cela signifie qu’après la conversion d’une échelle flottante en échelle entière, toute valeur comprise dans D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place d’une valeur de format cible représentée est autorisée à être mappée à cette valeur. L’exigence supplémentaire d’invertabilité des données garantit que la conversion n’est pas obtenue dans la plage et que toutes les valeurs de sortie sont accessibles. (Dans les constantes indiquées ici, xx doivent être remplacées par la version Direct3D, par exemple 10, 11 ou 12.)
UNORM FLOTTER La valeur n-bit de départ est convertie en float (0.0f, 1.0f, 2.0f, etc.) puis divisée par (2ⁿ-1).
FLOTTER UNORM Laissez c représenter la valeur de départ.
  • Si c est NaN, le résultat est 0.
  • Si c > 1.0f, y compris INF, il est limité à 1,0f.
  • Si c < 0,0f, y compris -INF, elle est limitée à 0,0f.
  • Convertir de l’échelle flottante à l’échelle entière : c = c * (2ⁿ-1).
  • Convertir en entier.
    • c = c + 0,5f.
    • La fraction décimale est supprimée et la valeur flottante restante (intégrale) est convertie directement en entier.
Cette conversion est autorisée à une tolérance de D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place (côté entier). Cela signifie qu’après la conversion d’une échelle flottante en échelle entière, toute valeur comprise dans D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place d’une valeur de format cible représentée est autorisée à être mappée à cette valeur. L’exigence supplémentaire d’invertabilité des données garantit que la conversion n’est pas obtenue dans la plage et que toutes les valeurs de sortie sont accessibles.
SRGB FLOTTER Voici la conversion SRVB idéale en FLOAT.
  • Prenez la valeur n-bit de départ, convertissez-la en float (0.0f, 1.0f, 2.0f, etc.) ; appelez ce c.
  • c = c * (1.0f / (2ⁿ-1))
  • Si (c < = D3Dxx_SRGB_TO_FLOAT_THRESHOLD) puis : result = c / D3Dxx_SRGB_TO_FLOAT_DENOMINATOR_1, else : result = ((c + D3Dxx_SRGB_TO_FLOAT_OFFSET)/D3Dxx_SRGB_TO_FLOAT_DENOMINATOR_2)D3Dxx_SRGB_TO_FLOAT_EXPONENT
Cette conversion est autorisée à une tolérance de D3Dxx_SRGB_TO_FLOAT_TOLERANCE_IN_ULP Unit-Last-Place (côté SRGB).
FLOTTER SRGB Voici l’idéal FLOAT -> conversion SRGB.
En supposant que le composant de couleur SRGB cible a n bits :
  • Supposons que la valeur de départ soit c.
  • Si c est NaN, le résultat est 0.
  • Si c > 1.0f, y compris INF, est limité à 1,0f.
  • Si c < 0,0f, y compris -INF, elle est limitée à 0,0f.
  • Si (c <= D3Dxx_FLOAT_TO_SRGB_THRESHOLD) puis : c = D3Dxx_FLOAT_TO_SRGB_SCALE_1 * c, sinon : c = D3Dxx_FLOAT_TO_SRGB_SCALE_2 * c(D3Dxx_FLOAT_TO_SRGB_EXPONENT_NUMERATOR/D3Dxx_FLOAT_TO_SRGB_EXPONENT_DENOMINATOR) - D3Dxx_FLOAT_TO_SRGB_OFFSET
  • Convertir de l’échelle flottante à l’échelle entière : c = c * (2ⁿ-1).
  • Convertir en entier :
    • c = c + 0,5f.
    • La fraction décimale est supprimée et la valeur flottante restante (intégrale) est convertie directement en entier.
Cette conversion est autorisée à une tolérance de D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place (côté entier). Cela signifie qu’après la conversion d’une échelle flottante en échelle entière, toute valeur comprise dans D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place d’une valeur de format cible représentée est autorisée à être mappée à cette valeur. L’exigence supplémentaire d’invertabilité des données garantit que la conversion n’est pas obtenue dans la plage et que toutes les valeurs de sortie sont accessibles.
SINT SINT avec plus de bits Pour effectuer une conversion de SINT en SINT avec plus de bits, le bit le plus significatif (MSB) du numéro de départ est « sign-extended » vers les bits supplémentaires disponibles dans le format cible.
UINT SINT avec plus de bits Pour effectuer une conversion de UINT en SINT avec plus de bits, le nombre est copié dans les bits les moins significatifs (LSB) du format cible et les msB supplémentaires sont complétées avec 0.
SINT UINT avec plus de bits Pour effectuer une conversion de SINT en UINT avec plus de bits : si elle est négative, la valeur est limitée à 0. Sinon, le nombre est copié dans les LSB du format cible et les msB supplémentaires sont rembourrés avec 0.
UINT UINT avec plus de bits Pour convertir UINT en UINT avec plus de bits, le nombre est copié dans les LSB du format cible et les msB supplémentaires sont rembourrés avec 0.
SINT ou UINT SINT ou UINT avec des bits inférieurs ou égaux Pour effectuer une conversion d’un SINT ou UINT en SINT ou UINT avec des bits inférieurs ou égaux (et/ou une modification de la signature), la valeur de départ est simplement limitée à la plage du format cible.

 

Conversion d’entier de point fixe

Les entiers de point fixe sont simplement des entiers de taille de bits qui ont un décimal implicite à un emplacement fixe.

Le type de données « entier » omniprésent est un cas spécial d’un entier de point fixe avec la décimale à la fin du nombre.

Les représentations numériques à virgule fixe sont caractérisées par : i.f, où i est le nombre de bits entiers et f est le nombre de bits fractionnels. Par exemple, 16,8 signifie 16 bits entiers suivis de 8 bits de fraction. La partie entière est stockée dans le complément de 2, au moins comme défini ici (bien qu’elle puisse également être définie pour les entiers non signés). La partie fractionnaire est stockée sous forme non signée. La partie fractionnaire représente toujours la fraction positive entre les deux valeurs intégrales les plus proches, en commençant par la plus négative.

Les opérations d’addition et de soustraction sur les nombres à points fixes sont effectuées simplement à l’aide d’une arithmétique d’entier standard, sans aucune considération pour laquelle les décimales implicites se trouvent. L’ajout de 1 à un nombre fixe de 16,8 signifie simplement ajouter 256, car la décimale est de 8 places à partir de la fin la moins significative du nombre. D’autres opérations telles que la multiplication peuvent être effectuées tout simplement à l’aide d’une arithmétique entière, à condition que l’effet sur la décimale fixe soit pris en compte. Par exemple, la multiplication de deux entiers de 16,8 à l’aide d’une multiplication d’entiers produit un résultat de 32,16.

Les représentations entières à virgule fixe sont utilisées de deux manières dans Direct3D.

  • Les positions de vertex post-clippées dans le rastériseur sont alignées sur un point fixe, pour répartir uniformément la précision dans la zone RenderTarget. De nombreuses opérations de rastériseur, y compris le culage du visage comme un exemple, se produisent sur des positions alignées à point fixe, tandis que d’autres opérations, telles que la configuration de l’interpolateur d’attribut, utilisent des positions qui ont été converties en virgule flottante à partir des positions alignées à point fixe.
  • Les coordonnées de texture pour les opérations d’échantillonnage sont alignées sur un point fixe (après avoir été mises à l’échelle par taille de texture), pour répartir uniformément la précision entre l’espace de texture, en choisissant les emplacements/pondérations des appuis de filtre. Les valeurs de poids sont converties en virgule flottante avant l’exécution de l’arithmétique de filtrage réel.
Type de données source Type de données de destination Règle de conversion
FLOTTER Entier de point fixe Voici la procédure générale permettant de convertir un nombre à virgule flottante n en entier à un point fixe i.f, où i est le nombre (signé) de bits entiers et f est le nombre de bits fractionnaires.
  • Compute FixedMin = -2⁽ⁱ⁻¹⁾
  • Compute FixedMax = 2⁽ⁱ⁻¹⁾ - 2(-f)
  • Si n est un naN, résultat = 0 ; si n est +Inf, result = FixedMax*2f; si n est -Inf, résultat = FixedMin*2f
  • Si n >= FixedMax, result = Fixedmax*2f; si n <= FixedMin, result = FixedMin*2f
  • Sinon, calcul n*2f et convertir en entier.
Les implémentations sont autorisées D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP tolérance d’unité-Last-Place dans le résultat entier, au lieu de la valeur infiniment précise n*2f après la dernière étape ci-dessus.
Entier de point fixe FLOTTER Supposons que la représentation à point fixe spécifique convertie en float ne contient pas plus de 24 bits d’informations au total, dont pas plus de 23 bits dans le composant fractionnaire. Supposons qu’un nombre de points fixes donné, fxp, soit au format i.f (entier i bits, fraction de bits f). La conversion en float est semblable au pseudocode suivant.
float result = (float)(fxp >> f) + // extract integer
((float)(fxp & (2f - 1)) / (2f)) ; extraire la fraction

 

ressources (Direct3D 10)