Share via


Konvertieren von Datentypen

In den folgenden Abschnitten wird beschrieben, wie Direct3D Konvertierungen zwischen Datentypen verarbeitet.

Terminologie für Datentypen

Der folgende Satz von Begriffen wird anschließend verwendet, um verschiedene Formatkonvertierungen zu charakterisieren.

Begriff Definition
SNORM Normierte Ganzzahl mit Vorzeichen, d. h. für die Ergänzungsnummer einer n-Bit 2 bedeutet der Maximalwert 1,0f (z. B. der 5-Bit-Wert 01111 entspricht 1,0f), und der Mindestwert bedeutet -1,0f (z. B. der 5-Bit-Wert 10000 entspricht -1,0f). Darüber hinaus entspricht die zweite Mindestzahl -1,0f (z. B. der 5-Bit-Wert 10001 entspricht -1,0f). Es gibt also zwei ganzzahlige Darstellungen für -1,0f. Es gibt eine einzelne Darstellung für 0,0f und eine einzelne Darstellung für 1,0f. Dies führt zu einer Reihe ganzzahliger Darstellungen für gleichmäßige Gleitkommawerte im Bereich (-1,0f... 0,0f) und auch eine ergänzende Gruppe von Darstellungen für Zahlen im Bereich (0,0f... 1.0f)
UNORM Normierte Ganzzahl ohne Vorzeichen, d. h. bei einer n-Bit-Zahl bedeuten alle Nullen 0,0f und alle Einsen 1,0f. Eine Abfolge von gleichmäßigen Gleitkommawerten von 0,0f bis 1,0f wird dargestellt. Beispielsweise stellt eine 2-Bit-UNORM 0,0f, 1/3, 2/3 und 1,0f dar.
SINT Ganze Zahl mit Vorzeichen. Die Komplementzahl von 2. Beispielsweise stellt ein 3-Bit-SINT die integralen Werte -4, -3, -2, -1, 0, 1, 2, 3 dar.
UINT Ganze Zahl ohne Vorzeichen. Beispielsweise stellt ein 3-Bit-UINT die integralen Werte 0, 1, 2, 3, 4, 5, 6, 7 dar.
FLOAT Ein Gleitkommawert in einer der von Direct3D definierten Darstellungen.
SRGB Ähnlich wie UNORM, wobei für eine n-Bit-Zahl alle Nullen 0,0f und alle Einsen 1,0f bedeuten. Im Gegensatz zu UNORM stellt jedoch bei SRGB die Abfolge vorzeichenloser Integer-Kodierungen zwischen allen Nullen und allen Einsen eine nichtlineare Progression in der Gleitkomma-Interpretation der Zahlen dar, zwischen 0,0f und 1,0f. Wenn diese nichtlineare Entwicklung, SRGB, als eine Reihe von Farben angezeigt wird, würde es als lineare Rampe der Leuchtdichtestufen zu einem "durchschnittlichen" Beobachter unter "durchschnittlichen" Anzeigebedingungen auf einer "durchschnittlichen" Anzeige erscheinen. Ausführliche Informationen finden Sie unter der SRGB-Farbnorm IEC 61996-2-1 bei IEC (International Electrotechnical Commission).

 

Die oben genannten Begriffe werden häufig als "Formatnamenmodifizierer" verwendet, in denen sie beschreiben, wie Daten im Arbeitsspeicher angeordnet sind und welche Konvertierung im Transportpfad (möglicherweise einschließlich Filterung) vom Speicher in oder von einer Pipelineeinheit wie einem Shader ausgeführt wird.

Gleitkommakonvertierungen

Immer wenn eine Gleitkommakonvertierung zwischen verschiedenen Darstellungen erfolgt, einschließlich zu oder aus nicht gleitkommafreien Darstellungen, gelten die folgenden Regeln.

Konvertieren von einer Darstellung eines höheren Bereichs zu einer Darstellung eines niedrigeren Bereichs

  • Während der Konvertierung in ein anderes Float-Format wird Round-to-zero verwendet. Wenn das Ziel ein ganzzahliges oder festes Punktformat ist, wird round-to-nearest-even verwendet, es sei denn, die Konvertierung wird explizit unter Verwendung eines anderen Rundungsverhaltens dokumentiert, z. B. round-to-nearest for FLOAT to SNORM, FLOAT to UNORM oder FLOAT to SRGB. Andere Ausnahmen sind die ftoi- und ftou-Shaderanweisungen, die round-to-zero verwenden. Schließlich haben die float-to-fixed-Konvertierungen, die vom Textursampler und Rasterizer verwendet werden, eine angegebene Toleranz, die in Unit-Last-Place von einem unendlich genauen Ideal gemessen wird.
  • Für Quellwerte, die größer sind als der dynamische Bereich eines Zielformats mit geringerem Bereich (z. B. ein großer 32-Bit-Gleitkommawert wird in ein 16-Bit-Gleitkomma-RenderTarget geschrieben), ergibt sich der maximal darstellbare (entsprechend vorzeichenbehaftete) Wert, NICHT einschließlich vorzeichenbehafteter Unendlichkeit (aufgrund der oben beschriebenen Rundung auf Null).
  • NaN in einem Format für einen höheren Bereich wird in naN-Darstellung im Format des unteren Bereichs konvertiert, wenn die NaN-Darstellung im Format des unteren Bereichs vorhanden ist. Wenn das untere Format keine NaN-Darstellung aufweist, lautet das Ergebnis 0.
  • INF in einem Format für einen höheren Bereich wird in INF im Format des unteren Bereichs konvertiert, falls verfügbar. Wenn das untere Format keine INF-Darstellung aufweist, wird es in den maximal dargestellten Wert konvertiert. Das Zeichen wird beibehalten, wenn es im Zielformat verfügbar ist.
  • Die Denorm in einem Format mit höherem Bereich wird in die Denorm-Darstellung im Format mit niedrigerem Bereich umgewandelt, wenn sie im Format mit niedrigerem Bereich verfügbar und die Umwandlung möglich ist; andernfalls ist das Ergebnis 0. Das Zeichenbit wird beibehalten, wenn es im Zielformat verfügbar ist.

Konvertieren von einer Darstellung eines niedrigeren Bereichs in eine Darstellung eines höheren Bereichs

  • NaN in einem Format für einen niedrigeren Bereich wird in die NaN-Darstellung im Format für den höheren Bereich konvertiert, falls im Format für einen höheren Bereich verfügbar. Wenn das Format für den höheren Bereich keine NaN-Darstellung aufweist, wird es in 0 konvertiert.
  • INF in einem Format für einen niedrigeren Bereich wird in die INF-Darstellung im Format höherer Bereiche konvertiert, wenn es im Format für einen höheren Bereich verfügbar ist. Wenn das höhere Format keine INF-Darstellung aufweist, wird es in den maximal dargestellten Wert konvertiert (MAX_FLOAT in diesem Format). Das Zeichen wird beibehalten, wenn es im Zielformat verfügbar ist.
  • Denorm in einem niedrigeren Bereichsformat wird nach Möglichkeit in eine normalisierte Darstellung im Format für einen höheren Bereich oder in eine Denorm-Darstellung im Format höherer Bereiche konvertiert, wenn die Denorm-Darstellung vorhanden ist. Wenn das Format für den höheren Bereich keine Denorm-Darstellung aufweist, wird das Format nicht in 0 konvertiert. Das Zeichen wird beibehalten, wenn es im Zielformat verfügbar ist. Beachten Sie, dass 32-Bit-Gleitkommazahlen als Format ohne Denorm-Darstellung zählen (da Denorms bei Operationen mit 32-Bit-Gleitkommazahlen bündig sind und das Vorzeichen 0 erhalten bleibt).

Ganzzahlige Konvertierung

In der folgenden Tabelle werden Konvertierungen aus verschiedenen oben beschriebenen Darstellungen in andere Darstellungen beschrieben. Es werden nur Konvertierungen angezeigt, die tatsächlich in Direct3D auftreten.

Bei ganzzahligen Zahlen, sofern nicht anders angegeben, werden alle Konvertierungen in/von ganzzahligen Darstellungen in float-Darstellungen, die unten beschrieben werden, genau ausgeführt.

Quelldatentyp Zieldatentyp Konvertierungsregel
SNORM FLOAT

Bei einem n-Bit-Ganzzahlwert, der den vorzeichenbehafteten Bereich [-1,0f bis 1,0f] repräsentiert, erfolgt die Umwandlung in eine Gleitkommazahl wie folgt.

  • Der negativste Wert entspricht -1,0f. Der 5-Bit-Wert 10000 entspricht beispielsweise -1,0f.
  • Jeder andere Wert wird in einen Float konvertiert (nennen Sie ihn c), und dann Ergebnis = c * (1,0f / (2⁽ⁿ⁻¹⁾-1)). Beispielsweise wird der 5-Bit-Wert 10001 in -15,0f konvertiert und dann durch 15,0f dividiert, ergibt -1,0f.
FLOAT SNORM

Bei einer Gleitkommazahl entspricht die Konvertierung in einen ganzzahligen n-Bit-Wert, der den vorzeichenbehafteten Bereich [-1,0f zu 1,0f] darstellt.

  • c steht für den Ausgangswert.
  • Wenn c gleich NaN ist, ist das Ergebnis 0.
  • Wenn c > 1,0f, einschließlich INF, ist es auf 1,0f geklemmt.
  • Wenn c < -1.0f, einschließlich -INF, ist es auf -1,0f geklemmt.
  • Konvertieren von Float-Skalierung in ganzzahlige Skalierung: c = c * (2ⁿ⁻¹-1).
  • Konvertieren Sie wie folgt in eine ganze Zahl.
    • Wenn c >= 0 dann c = c + 0,5f, andernfalls c = c - 0,5f.
    • Legen Sie den Dezimalbruch ab, und der re Standard ing-Gleitkommawert (integraler) Wert wird direkt in eine ganze Zahl konvertiert.

Bei dieser Konvertierung ist eine Toleranz von D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_Unit-Last-Place Unit-Last-Place (auf ganzzahliger Seite) zulässig. Dies bedeutet, dass nach dem Konvertieren von float in ganzzahlige Skalierung jeder Wert innerhalb von D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place eines darstellbaren Zielformatwerts zulässig ist, diesen Wert zuzuordnen. Die zusätzliche Dateninvertierbarkeitsanforderung stellt sicher, dass die Konvertierung nicht über den bereichsübergreifenden Bereich hinaus wächst und alle Ausgabewerte erreichbar sind. (In den hier gezeigten Konstanten sollte xx durch die Direct3D-Version ersetzt werden, z. B. 10, 11 oder 12.)

UNORM FLOAT

Der erste n-Bit-Wert wird in float (0,0f, 1,0f, 2,0f usw.) konvertiert und dann durch (2ⁿ-1) dividiert.

FLOAT UNORM

c steht für den Ausgangswert.

  • Wenn c gleich NaN ist, ist das Ergebnis 0.
  • Wenn c > 1,0f, einschließlich INF, ist es auf 1,0f geklemmt.
  • Wenn c < 0,0f, einschließlich -INF, ist es auf 0,0f geklemmt.
  • Konvertieren sie von float-Skalierung in ganzzahlige Skalierung: c = c * (2ⁿ-1).
  • In ganze Zahl konvertieren.
    • c = c + 0,5f.
    • Der Dezimalbruch wird verworfen, und der re Standard ing-Gleitkommawert (integraler) Wert wird direkt in eine ganze Zahl konvertiert.

Diese Konvertierung ist zulässig für eine Toleranz von D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place (auf der ganzzahligen Seite). Dies bedeutet, dass nach dem Konvertieren von float in ganzzahlige Skalierung jeder Wert innerhalb von D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place eines darstellbaren Zielformatwerts zulässig ist, diesen Wert zuzuordnen. Die zusätzliche Dateninvertierbarkeitsanforderung stellt sicher, dass die Konvertierung nicht über den bereichsübergreifenden Bereich hinaus wächst und alle Ausgabewerte erreichbar sind.

SRGB FLOAT

Es folgt die ideale SRGB to FLOAT-Konvertierung.

  • Nehmen Sie den n-Bit-Ausgangswert und wandeln Sie ihn in eine Gleitkommazahl um (0.0f, 1.0f, 2.0f, usw.); nennen Sie dies c.
  • c = c * (1,0f / (2ⁿ-1))
  • Wenn (c < = D3Dxx_SRGB_TO_FLOAT_THRESHOLD) dann: Ergebnis = c / D3Dxx_SRGB_TO_FLOAT_DENOMINATOR_1, sonst: Ergebnis = ((c + D3Dxx_SRGB_TO_FLOAT_OFFSET)/D3Dxx_SRGB_TO_FLOAT_DENOMINATOR_2)D3Dxx_SRGB_TO_FLOAT_EXPONENT

Bei dieser Konvertierung ist eine Toleranz von D3Dxx_SRGB_TO_FLOAT_TOLERANCE_IN_ULP Unit-Last-Place (auf srGB-Seite) zulässig.

FLOAT SRGB

Nachfolgend sehen Sie die ideale FLOAT -> SRGB-Konvertierung.

Vorausgesetzt, die Ziel-SRGB-Farbkomponente weist n Bits auf:

  • Angenommen, der Ausgangswert ist c.
  • Wenn c gleich NaN ist, ist das Ergebnis 0.
  • Wenn c > 1.0f, einschließlich INF, auf 1,0f geklemmt ist.
  • Wenn c < 0,0f, einschließlich -INF, ist es auf 0,0f geklemmt.
  • Wenn (c <= D3Dxx_FLOAT_TO_SRGB_THRESHOLD) dann: c = D3Dxx_FLOAT_TO_SRGB_SCALE_1 * c, sonst: 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
  • Konvertieren sie von float-Skalierung in ganzzahlige Skalierung: c = c * (2ⁿ-1).
  • In ganze Zahl konvertieren:
    • c = c + 0,5f.
    • Der Dezimalbruch wird verworfen, und der re Standard ing-Gleitkommawert (integraler) Wert wird direkt in eine ganze Zahl konvertiert.

Diese Konvertierung ist zulässig für eine Toleranz von D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place (auf der ganzzahligen Seite). Dies bedeutet, dass nach dem Konvertieren von float in ganzzahlige Skalierung jeder Wert innerhalb von D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place eines darstellbaren Zielformatwerts zulässig ist, diesen Wert zuzuordnen. Die zusätzliche Dateninvertierbarkeitsanforderung stellt sicher, dass die Konvertierung nicht über den bereichsübergreifenden Bereich hinaus wächst und alle Ausgabewerte erreichbar sind.

SINT SINT mit weiteren Bits

Zum Konvertieren von SINT in einen SINT mit mehr Bits ist das wichtigste Bit (MSB) der Startnummer "sign-extended" auf die zusätzlichen Bits, die im Zielformat verfügbar sind.

UINT SINT mit weiteren Bits

Um von UINT in einen SINT mit mehr Bits zu konvertieren, wird die Zahl in die niedrigstwertigen Bits (LSBs) des Zielformats kopiert und zusätzliche MSBs werden mit 0 aufgefüllt.

SINT UINT mit weiteren Bits

Zum Konvertieren von SINT in UINT mit mehr Bits: Wenn negativ, wird der Wert auf 0 geklemmt. Andernfalls wird die Zahl in die LSBs des Zielformats kopiert, und zusätzliche MSB-Dateien werden mit 0 aufgefüllt.

UINT UINT mit weiteren Bits

Zum Konvertieren von UINT in UINT mit mehr Bits wird die Zahl in die LSBs des Zielformats kopiert, und zusätzliche MSB-Dateien werden mit 0 aufgefüllt.

SINT oder UINT SINT oder UINT mit weniger oder gleichen Bits

Zur Konvertierung von einem SINT oder UINT in einen SINT oder UINT mit weniger oder gleichen Bits (und/oder Änderung der Vorzeichen) wird der Ausgangswert einfach auf den Bereich des Zielformats geklemmt.

 

Ganzzahlige Festkommakonvertierung

Festkommazahlen sind einfach ganze Zahlen mit einer Bitgröße, die an einer festen Position einen impliziten Dezimalkommapunkt aufweisen.

Der verbreitete Datentyp "Integer" ist ein Spezialfall einer Festkommazahl mit dem Dezimalzeichen am Ende der Zahl.

Festkommazahlendarstellungen sind gekennzeichnet als: i.f, wobei i die Anzahl der ganzzahligen Bits und f die Anzahl der Bruchbits ist. Beispielsweise bedeutet 16,8 16 Bit ganze Zahl gefolgt von 8 Bits Bruchzahl. Der ganzzahlige Teil wird im 2er-Komplement gespeichert, zumindest so, wie es hier definiert ist (obwohl es auch für ganze Zahlen ohne Vorzeichen definiert werden kann). Der Bruchteil wird vorzeichenlos gespeichert. Der Bruchteil stellt immer den positiven Bruch zwischen den beiden nächstgelegenen integralen Werten dar, beginnend mit dem negativsten.

Additions- und Subtraktionsvorgänge für Festkommazahlen werden einfach mit einer standardmäßigen ganzzahligen Arithmetik ausgeführt, ohne dass berücksichtigt wird, wo das implizierte Dezimalzeichen liegt. Das Hinzufügen von 1 zu einer 16,8 festen Punktzahl bedeutet lediglich das Hinzufügen von 256, da die Dezimalzahl 8 Stellen vom niedrigsten signifikanten Ende der Zahl ist. Andere Vorgänge wie die Multiplikation können auch einfach mit ganzzahliger Arithmetik durchgeführt werden, vorausgesetzt, der Effekt auf das feste Dezimaltrennzeichen wird berücksichtigt. Das Multiplizieren von zwei 16,8 ganzzahligen Zahlen mit einer ganzzahligen Multiplikation erzeugt beispielsweise ein Ergebnis von 32,16.

Ganzzahlige Festkommadarstellungen werden in Direct3D auf zwei Arten verwendet.

  • Postgeschnittene Vertexpositionen im Rasterizer werden an festen Punkt angedockt, um die Genauigkeit gleichmäßig über den RenderTarget-Bereich zu verteilen. Viele Rasterizervorgänge, einschließlich Gesichts-Culling als Beispiel, treten an angedockten Positionen an festen Punkten auf, während andere Vorgänge, z. B. die Einrichtung von Attributinterpolator, Positionen verwenden, die von den angedockten Positionen des festen Punkts in Gleitkommastellen konvertiert wurden.
  • Texturkoordinaten für Samplingvorgänge werden an festen Punkt angedockt (nachdem sie nach Texturgröße skaliert wurden), um die Genauigkeit gleichmäßig über den Texturraum zu verteilen, bei der Auswahl von Filterzapfpositionen/-gewichtungen. Gewichtungswerte werden zurück in Gleitkomma konvertiert, bevor die tatsächliche Filterarithmetik ausgeführt wird.
Quelldatentyp Zieldatentyp Konvertierungsregel
FLOAT Ganzzahliger Fixpunkt

Im Folgenden sehen Sie das allgemeine Verfahren zum Konvertieren einer Gleitkommazahl n in eine ganzzahlige Festkommazahl i.f, wobei i die Anzahl von (vorzeichenbehafteten) ganzzahligen Bits und f die Anzahl der Bruchbits ist.

  • Berechnen Sie FixedMin = -2⁽ⁱ-¹⁾
  • Berechnen Sie FixedMax = 2⁽ⁱ⁻¹⁾ - 2(-f)
  • Wenn n ein NaN ist, Ergebnis = 0; wenn n +Inf ist, Ergebnis = FixedMax*2f; wenn n -Inf ist, Ergebnis = FixedMin*2f
  • Wenn n >= FixedMax, Ergebnis = Fixedmax*2f; wenn n <= FixedMin, Ergebnis = FixedMin*2f
  • Andernfalls berechnen Sie n*2f und wandeln es in eine ganze Zahl um.

Den Implementierungen wird eine D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place-Toleranz im ganzzahligen Ergebnis erlaubt, anstelle des unendlich genauen Wertes n*2f nach dem letzten Schritt oben.

Ganzzahliger Fixpunkt FLOAT

Gehen Sie davon aus, dass die spezifische Festkommadarstellung, die in Float konvertiert wird, nicht mehr als insgesamt 24 Bits von Informationen enthält, von denen sich nicht mehr als 23 Bit in der Bruchkomponente befindet. Angenommen, eine bestimmte Feste Punktzahl, fxp, ist in i.f-Form (i Bit ganze Zahl, f Bits Bruch). Die Konvertierung in float entspricht dem folgenden Pseudocode.

float Ergebnis = (float)(fxp f) + // Ganzzahl extrahieren

((float)(fxp & (2f - 1)) / (2f)); // Bruchteil extrahieren

 

Anhänge