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 des types de données

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

Terme Définition
SNORM Entier normalisé signé, ce qui signifie que pour le nombre de compléments d’un n-bit 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 est mappée à -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 seule représentation pour 0.0f et une seule représentation pour 1.0f. Il en résulte un ensemble de représentations entières pour les valeurs à virgule flottante espacées uniformément 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, tout 0 signifie 0,0f et tout 1 signifie 1,0f. Une séquence de valeurs à virgule flottante espacées uniformément comprises entre 0,0f et 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 de 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.
FLOAT Valeur à virgule flottante dans l’une des représentations définies par Direct3D.
SRGB Semblable à UNORM, dans la mesure où pour un nombre n bits, tous les 0 signifient 0,0f et tous les 1 signifient 1,0f. Toutefois, contrairement à UNORM, avec SRGB, la séquence d’encodages entiers non signés entre tous les 0 et tous les 1 représente une progression non linéaire dans l’interprétation à virgule flottante des nombres, entre 0,0f et 1,0f. En gros, si cette progression non linéaire, SRGB, est affichée sous la forme d’une séquence de couleurs, elle apparaît sous la forme d’une rampe linéaire de niveaux de luminosité pour un observateur « moyen », dans des conditions d’affichage « moyennes », sur un affichage « moyen ». Pour plus d’informations, reportez-vous à la norme de couleur SRGB, IEC 61996-2-1, à l’IEC (International Electrotechnical Commission).

 

Conversion à virgule flottante

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

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

  • 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, l’arrondi au plus proche est utilisé, sauf si la conversion est explicitement documentée comme utilisant un autre comportement d’arrondi, tel que l’arrondi le plus proche pour FLOAT vers SNORM, FLOAT vers UNORM ou FLOAT vers SRGB. D’autres exceptions sont les instructions du nuanceur ftoi et ftou, qui utilisent la valeur arrondie à zéro. 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 en Unité-Last-Place à partir 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 de 32 bits est écrite dans un RenderTarget flottant 16 bits), la valeur représentantable maximale (signée de manière appropriée), sans compter l’infini signé (en raison de l’arrondi à zéro décrit ci-dessus).
  • NaN dans un format de plage supérieure est converti en représentation NaN dans le format de plage inférieure si la représentation NaN existe dans le format de plage inférieure. Si le format inférieur n’a pas de représentation NaN, le résultat est 0.
  • Inf dans un format de plage supérieure est converti en INF dans le format de plage inférieure, le cas échéant. 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.
  • Le denorm dans un format de plage supérieure est converti en représentation Denorm au format de plage inférieure si disponible dans le format de plage inférieure et si la conversion est possible, sinon le résultat est 0. Le bit de signe est conservé s’il est disponible dans le 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érieure sera converti en représentation NaN dans le format de plage supérieure si disponible dans le format de plage supérieure. Si le format de plage supérieure n’a pas de représentation NaN, il est converti en 0.
  • Inf dans un format de plage inférieure est converti en représentation INF dans le format de plage supérieure si disponible dans le format de plage supérieure. 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 denorm dans un format de plage inférieure sera converti en représentation normalisée au format de plage supérieure si possible, ou bien en représentation Denorm au format de plage supérieure si la représentation Denorm existe. À défaut, si le format de plage supérieure n’a pas de représentation Denorm, il est converti en 0. Le signe est conservé s’il est disponible dans le format cible. Notez que les nombres float 32 bits comptent comme un format sans représentation Denorm (car Denorms dans les opérations sur les floats 32 bits vide pour signer 0 conservé).

Conversion d’entiers

Le tableau suivant décrit les conversions des 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 FLOAT É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 est mappée à -1,0f. Par exemple, la valeur 5 bits 10000 est mappée à -1,0f.
  • Une valeur sur deux 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 donne -1.0f.
FLOAT SNORM Avec un nombre à virgule flottante, la conversion en une valeur entière n bits représentant la plage signée [-1.0f en 1.0f] se présente comme suit.
  • 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.
  • Convertissez de l’échelle float en é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 à virgule flottante restante (intégrale) est convertie directement en entier.
Cette conversion est autorisée avec 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 de l’échelle float en échelle entière, toute valeur dans D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unité-Last-Place d’une valeur de format cible pouvant être 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 dédécrée dans la plage et que toutes les valeurs de sortie sont réalisables. (Dans les constantes présentées ici, xx doit être remplacé par la version Direct3D, par exemple 10, 11 ou 12.)
UNORM FLOAT La valeur n-bit de départ est convertie en float (0.0f, 1.0f, 2.0f, etc.) puis divisée par (2ⁿ-1).
FLOAT 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, il est limité à 0,0f.
  • Convertir de l’échelle float à 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 à virgule flottante restante (intégrale) est convertie directement en entier.
Cette conversion est autorisée avec une tolérance de D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place (côté entier). Cela signifie qu’après la conversion de l’échelle float en échelle entière, toute valeur dans D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unité-Last-Place d’une valeur de format cible pouvant être 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 dédécrée dans la plage et que toutes les valeurs de sortie sont réalisables.
SRGB FLOAT Voici la conversion idéale de SRGB en FLOAT.
  • Prenez la valeur n bits de départ, convertissez-la en float (0.0f, 1.0f, 2.0f, etc.) ; appelez ceci c.
  • c = c * (1.0f / (2ⁿ-1))
  • Si (c < = D3Dxx_SRGB_TO_FLOAT_THRESHOLD) alors : 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 avec une tolérance de D3Dxx_SRGB_TO_FLOAT_TOLERANCE_IN_ULP Unit-Last-Place (côté SRGB).
FLOAT SRGB Voici la conversion FLOAT -> SRGB idéale.
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, il est limité à 0,0f.
  • Si (c <= D3Dxx_FLOAT_TO_SRGB_THRESHOLD) alors : 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 float à 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 à virgule flottante restante (intégrale) est convertie directement en entier.
Cette conversion est autorisée avec une tolérance de D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place (côté entier). Cela signifie qu’après la conversion de l’échelle float en échelle entière, toute valeur dans D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unité-Last-Place d’une valeur de format cible pouvant être 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 dédécrée dans la plage et que toutes les valeurs de sortie sont réalisables.
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 nombre de départ est « étendu par signe » en bits supplémentaires disponibles dans le format cible.
UINT SINT avec plus de bits Pour effectuer une conversion d’UINT en SINT avec plus de bits, le nombre est copié dans les bits les moins significatifs (LSB) du format cible, et les bases de données 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 autres MSB sont remplis avec 0.
UINT UINT avec plus de bits Pour effectuer une conversion d’UINT en UINT avec plus de bits, le nombre est copié dans les LSB du format cible et les MSB supplémentaires sont remplis avec 0.
SINT ou UINT SINT ou UINT avec des bits inférieurs ou égaux Pour effectuer une conversion d’une SINT ou d’un UINT en SINT ou UINT avec moins de bits 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 à point fixe

Les entiers à virgule fixe sont simplement des entiers d’une certaine taille de bits qui ont une virgule décimale implicite à un emplacement fixe.

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

Les représentations de nombre de points fixes sont caractérisées par : i.f, où i est le nombre de bits entiers et f le nombre de bits fractionnaires. Par exemple, 16,8 signifie 16 bits entier suivi 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’il puisse également être défini de façon égale 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 des nombres à virgule fixe sont effectuées simplement à l’aide de l’arithmétique d’entier standard, sans tenir compte de l’emplacement où se trouve la décimale implicite. L’ajout de 1 à un nombre de points fixes 16,8 signifie simplement ajouter 256, car la décimale est de 8 places dans à partir de la fin la moins significative du nombre. D’autres opérations, telles que la multiplication, peuvent également être effectuées simplement à l’aide de l’arithmétique entier, à 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 d’entiers à point fixe sont utilisées de deux façons dans Direct3D.

  • Les positions post-clippées du vertex dans le rastériseur sont ancrées sur un point fixe, pour répartir uniformément la précision sur la zone RenderTarget. De nombreuses opérations de rastériseur, y compris l’élimination du visage comme exemple, se produisent sur des positions ancré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 à nouveau en virgule flottante à partir des positions ancrées à point fixe.
  • Les coordonnées de texture pour les opérations d’échantillonnage sont ancrées sur un point fixe (après avoir été mises à l’échelle par taille de texture), pour répartir uniformément la précision dans l’espace de texture, lors du choix des emplacements/pondérations de l’appui de filtre. Les valeurs de pondération sont reconvertes 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
FLOAT Entier à point fixe Voici la procédure générale pour convertir un nombre à virgule flottante n en entier à point fixe i.f, où i est le nombre de bits entiers (signés) et f le nombre de bits fractionnaires.
  • Compute FixedMin = -2⁽ⁱ⁻¹⁾
  • Compute FixedMax = 2⁽ⁱ⁻¹⁾ - 2(-f)
  • Si n est un NaN, result = 0 ; si n a la valeur +Inf, result = FixedMax*2f; si n est -Inf, result = FixedMin*2f
  • Si n >= FixedMax, result = Fixedmax*2f; si n <= FixedMin, result = FixedMin*2f
  • Sinon, calculez n*2f et convertissez en entier.
Les implémentations sont autorisées D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP tolérance 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 à point fixe FLOAT Supposons que la représentation à point fixe spécifique convertie en virgule flottante ne contient pas plus de 24 bits d’informations, dont 23 bits au plus dans le composant fractionnaire. Supposons qu’un nombre de points fixes donné, fxp, soit au format i.f (entier i bits, fraction f bits). La conversion en float est semblable au pseudocode suivant.
résultat float = (float)(fxp >> f) + // extract integer
((float)(fxp & (2f - 1)) / (2f)); fraction d’extraction

 

Ressources (Direct3D 10)