Condividi tramite


Regole di conversione dei dati

Le sezioni seguenti descrivono come Direct3D gestisce le conversioni tra tipi di dati.

Terminologia dei tipi di dati

Il set di termini seguente viene usato successivamente per caratterizzare varie conversioni di formato.

Termine Definizione
SNORM Intero normalizzato con segno, ovvero per un numero di complemento di n bit 2, il valore massimo indica 1,0f (ad esempio, il valore a 5 bit 01111 corrisponde a 1,0f) e il valore minimo indica -1,0f (ad esempio, il valore a 5 bit 10000 corrisponde a -1,0f). Inoltre, il secondo numero minimo viene mappato a -1,0f (ad esempio, il valore a 5 bit 10001 corrisponde a -1,0f). Esistono quindi due rappresentazioni integer per -1,0f. Esiste una singola rappresentazione per 0,0f e una singola rappresentazione per 1,0f. Ciò comporta un set di rappresentazioni integer per i valori a virgola mobile a virgola mobile uniforme nell'intervallo (-1,0f... 0,0f) e anche un insieme complementare di rappresentazioni per i numeri nell'intervallo (0,0f... 1.0f)
UNORM Intero normalizzato senza segno, ovvero per un numero a n bit, tutti gli 0 significano 0,0f e tutti i valori di 1 significano 1,0f. Viene rappresentata una sequenza di valori a virgola mobile con spaziatura uniforme da 0,0f a 1,0f. Ad esempio, uno UNORM a 2 bit rappresenta 0,0f, 1/3, 2/3 e 1,0f.
SINT Intero con segno. Intero di complemento di 2. Ad esempio, un SINT a 3 bit rappresenta i valori integrali -4, -3, -2, -1, 0, 1, 2, 3.
UINT Intero senza segno. Ad esempio, un UINT a 3 bit rappresenta i valori integrali 0, 1, 2, 3, 4, 5, 6, 7.
GALLEGGIARE Valore a virgola mobile in una delle rappresentazioni definite da Direct3D.
SRGB Analogamente a UNORM, in quanto per un numero a n bit, tutti gli 0 significano 0,0f e tutti i 1 significano 1,0f. Tuttavia, a differenza di UNORM, con SRGB la sequenza di codifiche intere senza segno tra tutti gli 0 e tutti gli 1 rappresentano una progressione non lineare nell'interpretazione a virgola mobile dei numeri, tra 0,0f e 1,0f. Approssimativamente, se questa progressione non lineare, SRGB, viene visualizzata come una sequenza di colori, appare come una rampa lineare di livelli di luminosità a un osservatore "medio", in condizioni di visualizzazione "medie", su un display "medio". Per informazioni dettagliate, vedere lo standard di colore SRGB, IEC 61996-2-1, presso IEC (International Electrotechnical Commission).

 

Conversione a virgola mobile

Ogni volta che si verifica una conversione a virgola mobile tra rappresentazioni diverse, incluse le rappresentazioni a virgola mobile o da rappresentazioni non a virgola mobile, si applicano le regole seguenti.

Conversione da una rappresentazione di intervallo superiore a una rappresentazione di intervallo inferiore

  • Viene usato round-to-zero durante la conversione in un altro formato float. Se la destinazione è un formato integer o a virgola fissa, viene usato round-to-near-even, a meno che la conversione non sia documentata in modo esplicito come usando un altro comportamento di arrotondamento, ad esempio round-to-nearest per FLOAT a SNORM, FLOAT a UNORM o FLOAT a SRGB. Altre eccezioni sono le istruzioni ftoi e ftou shader, che usano round-to-zero. Infine, le conversioni float-to-fixed usate dal campionatore di trama e dal rasterizzatore hanno una tolleranza specificata misurata in Unit-Last-Place da un ideale infinitamente preciso.
  • Per i valori di origine maggiori dell'intervallo dinamico di un formato di destinazione di intervallo inferiore (ad esempio, un valore float a 32 bit elevato viene scritto in un oggetto RenderTarget a 16 bit), il valore massimo rappresentabile (con segno appropriato) non include l'infinito con segno (a causa dell'arrotondamento a zero descritto in precedenza).
  • NaN in un formato di intervallo superiore verrà convertito in rappresentazione NaN nel formato di intervallo inferiore se la rappresentazione NaN esiste nel formato di intervallo inferiore. Se il formato inferiore non ha una rappresentazione NaN, il risultato sarà 0.
  • INF in un formato di intervallo superiore verrà convertito in INF nel formato di intervallo inferiore, se disponibile. Se il formato inferiore non ha una rappresentazione INF, verrà convertito nel valore massimo rappresentabile. Il segno verrà mantenuto se disponibile nel formato di destinazione.
  • Denorm in un formato di intervallo superiore verrà convertito nella rappresentazione Denorm nel formato di intervallo inferiore, se disponibile nel formato di intervallo inferiore e la conversione è possibile, altrimenti il risultato è 0. Il bit del segno verrà mantenuto se disponibile nel formato di destinazione.

Conversione da una rappresentazione di intervallo inferiore a una rappresentazione di intervallo superiore

  • NaN in un formato di intervallo inferiore verrà convertito nella rappresentazione NaN nel formato di intervallo superiore, se disponibile nel formato di intervallo superiore. Se il formato di intervallo superiore non ha una rappresentazione NaN, verrà convertito in 0.
  • INF in un formato di intervallo inferiore verrà convertito nella rappresentazione INF nel formato di intervallo superiore, se disponibile nel formato di intervallo superiore. Se il formato superiore non ha una rappresentazione INF, verrà convertito nel valore massimo rappresentabile (MAX_FLOAT in tale formato). Il segno verrà mantenuto se disponibile nel formato di destinazione.
  • Denorm in un formato di intervallo inferiore verrà convertito in una rappresentazione normalizzata nel formato di intervallo superiore, se possibile, oppure in una rappresentazione Denorm nel formato di intervallo superiore se la rappresentazione Denorm esiste. In caso contrario, se il formato di intervallo superiore non ha una rappresentazione Denorm, verrà convertito in 0. Il segno verrà mantenuto se disponibile nel formato di destinazione. Si noti che i numeri float a 32 bit vengono conteggiati come formato senza una rappresentazione Denorm (perché Denorms nelle operazioni sui float a 32 bit scaricano per firmare 0).

Conversione integer

Nella tabella seguente vengono descritte le conversioni da varie rappresentazioni descritte in precedenza in altre rappresentazioni. Vengono visualizzate solo le conversioni effettivamente eseguite in Direct3D.

Tipo di dati di origine Tipo di dati di destinazione Regola di conversione
SNORM GALLEGGIARE Dato un valore intero a n bit che rappresenta l'intervallo con segno [-1.0f a 1.0f], la conversione in virgola mobile è la seguente.
  • Il valore più negativo è mappato a -1,0f. Ad esempio, il valore a 5 bit 10000 viene mappato a -1,0f.
  • Ogni altro valore viene convertito in float (chiamarlo c) e quindi risultato = c * (1,0f / (2⁽ⁿ⁻¹⁾-1)). Ad esempio, il valore a 5 bit 10001 viene convertito in -15,0f e quindi diviso per 15,0f, che restituisce -1,0f.
GALLEGGIARE SNORM Dato un numero a virgola mobile, la conversione in un valore intero a n bit che rappresenta l'intervallo con segno [-1.0f a 1.0f] è il seguente.
  • Lasciare che c rappresenti il valore iniziale.
  • Se c è NaN, il risultato è 0.
  • Se c > 1.0f, incluso INF, viene bloccato su 1,0f.
  • Se c < -1.0f, incluso -INF, viene bloccato su -1,0f.
  • Convertire da scala float a scala integer: c = c * (2ⁿ⁻¹-1).
  • Convertire in un numero intero come indicato di seguito.
    • Se c >= 0, c = c + 0,5f; in caso contrario, c = c - 0,5f.
    • Eliminare la frazione decimale e il valore a virgola mobile rimanente (integrale) viene convertito direttamente in un numero intero.
Questa conversione è consentita una tolleranza di D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_Unit-Last-Place unit-Last-Place (sul lato intero). Ciò significa che, dopo la conversione da float a integer, qualsiasi valore all'interno di D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place di un valore di formato di destinazione rappresentabile è autorizzato a eseguire il mapping a tale valore. Il requisito di invertibilità dei dati aggiuntivo garantisce che la conversione non venga generata nell'intervallo e che tutti i valori di output siano raggiungibili. Nelle costanti illustrate di seguito xx devono essere sostituite con la versione Direct3D, ad esempio 10, 11 o 12.
UNORM GALLEGGIARE Il valore iniziale di n bit viene convertito in float (0,0f, 1,0f, 2,0f e così via) e quindi diviso per (2ⁿ-1).
GALLEGGIARE UNORM Lasciare che c rappresenti il valore iniziale.
  • Se c è NaN, il risultato è 0.
  • Se c > 1.0f, incluso INF, viene bloccato su 1,0f.
  • Se c < 0,0f, incluso -INF, viene bloccato su 0,0f.
  • Conversione da scala float a scala integer: c = c * (2ⁿ-1).
  • Converti in integer.
    • c = c + 0,5f.
    • La frazione decimale viene eliminata e il valore a virgola mobile rimanente (integrale) viene convertito direttamente in un numero intero.
Questa conversione è consentita una tolleranza di D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP unit-Last-Place (sul lato intero). Ciò significa che, dopo la conversione da float a integer, qualsiasi valore all'interno di D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place di un valore di formato di destinazione rappresentabile è autorizzato a eseguire il mapping a tale valore. Il requisito di invertibilità dei dati aggiuntivo garantisce che la conversione non venga generata nell'intervallo e che tutti i valori di output siano raggiungibili.
SRGB GALLEGGIARE Di seguito è riportata la conversione SRGB ideale per FLOAT.
  • Prendere il valore n bit iniziale, convertirlo in float (0,0f, 1,0f, 2,0f e così via); chiamare questo c.
  • c = c * (1.0f / (2ⁿ-1))
  • Se (c < = D3Dxx_SRGB_TO_FLOAT_THRESHOLD) allora: 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
Questa conversione è consentita una tolleranza di D3Dxx_SRGB_TO_FLOAT_TOLERANCE_IN_ULP unit-Last-Place (sul lato SRGB).
GALLEGGIARE SRGB Di seguito è riportata la conversione FLOAT ideale> SRGB.
Supponendo che il componente colore SRGB di destinazione abbia n bit:
  • Si supponga che il valore iniziale sia c.
  • Se c è NaN, il risultato è 0.
  • Se c > 1,0f, incluso INF, viene bloccato su 1,0f.
  • Se c < 0,0f, incluso -INF, viene bloccato su 0,0f.
  • Se (c <= D3Dxx_FLOAT_TO_SRGB_THRESHOLD) allora: c = D3Dxx_FLOAT_TO_SRGB_SCALE_1 * c, else: 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
  • Conversione da scala float a scala integer: c = c * (2ⁿ-1).
  • Converti in integer:
    • c = c + 0,5f.
    • La frazione decimale viene eliminata e il valore a virgola mobile rimanente (integrale) viene convertito direttamente in un numero intero.
Questa conversione è consentita una tolleranza di D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP unit-Last-Place (sul lato intero). Ciò significa che, dopo la conversione da float a integer, qualsiasi valore all'interno di D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place di un valore di formato di destinazione rappresentabile è autorizzato a eseguire il mapping a tale valore. Il requisito di invertibilità dei dati aggiuntivo garantisce che la conversione non venga generata nell'intervallo e che tutti i valori di output siano raggiungibili.
SINT SINT con più bit Per eseguire la conversione da SINT a SINT con più bit, il bit più significativo (MSB) del numero iniziale è "sign-extended" ai bit aggiuntivi disponibili nel formato di destinazione.
UINT SINT con più bit Per eseguire la conversione da UINT a SINT con più bit, il numero viene copiato nei bit meno significativi del formato di destinazione (LSB) e gli MSB aggiuntivi vengono riempiti con 0.
SINT UINT con più bit Per eseguire la conversione da SINT a UINT con più bit: se negativo, il valore viene bloccato su 0. In caso contrario, il numero viene copiato nei LSB del formato di destinazione e gli MSB aggiuntivi vengono riempiti con 0.
UINT UINT con più bit Per eseguire la conversione da UINT a UINT con più bit, il numero viene copiato nei LSB del formato di destinazione e gli MSB aggiuntivi vengono riempiti con 0.
SINT o UINT SINT o UINT con un numero minore o uguale di bit Per eseguire la conversione da SINT o UINT a SINT o UINT con bit minori o uguali (e/o modifica della firma), il valore iniziale viene semplicemente bloccato nell'intervallo del formato di destinazione.

 

Conversione integer a virgola fissa

I numeri interi a virgola fissa sono semplicemente numeri interi di alcune dimensioni di bit che hanno un separatore decimale implicito in una posizione fissa.

Il tipo di dati "integer" universale è un caso speciale di un numero intero a virgola fissa con il separatore decimale alla fine del numero.

Le rappresentazioni dei numeri a virgola fissa sono caratterizzate da: ad esempio, dove i è il numero di bit interi e f è il numero di bit frazionari. Ad esempio, 16,8 indica un numero intero a 16 bit seguito da 8 bit di frazione. La parte integer viene archiviata nel complemento di 2, almeno come definito qui (anche se può essere definita ugualmente per interi senza segno). La parte frazionaria viene archiviata in formato senza segno. La parte frazionaria rappresenta sempre la frazione positiva tra i due valori integrali più vicini, a partire dal più negativo.

Le operazioni di addizione e sottrazione sui numeri a virgola fissa vengono eseguite semplicemente usando l'aritmetica integer standard, senza alcuna considerazione per la posizione decimale implicita. Aggiungendo 1 a un numero a 16,8 punti fissi significa semplicemente aggiungere 256, poiché il decimale è 8 posizioni dalla fine meno significativa del numero. È possibile eseguire anche altre operazioni, ad esempio la moltiplicazione, usando semplicemente l'aritmetica integer, a condizione che l'effetto sul decimale fisso sia tenuto conto. Ad esempio, la moltiplicazione di due numeri interi da 16,8 usando una moltiplicazione di numeri interi produce un risultato di 32,16.

Le rappresentazioni integer a virgola fissa vengono usate in due modi in Direct3D.

  • Le posizioni dei vertici post-ritagliate nel rasterizzatore vengono ritagliate fino al punto fisso, per distribuire in modo uniforme la precisione nell'area RenderTarget. Molte operazioni di rasterizzatore, tra cui il culling del viso come un esempio, si verificano in posizioni a virgola fissa, mentre altre operazioni, ad esempio l'impostazione dell'interpolatore di attributi, usano posizioni che sono state riconvertite in virgola mobile dalle posizioni a virgola fissa.
  • Le coordinate delle trame per le operazioni di campionamento vengono ritagliate al punto fisso (dopo essere state ridimensionate in base alle dimensioni della trama), per distribuire in modo uniforme la precisione nello spazio delle trame, scegliendo posizioni/pesi del tocco del filtro. I valori di peso vengono convertiti in virgola mobile prima dell'esecuzione dell'aritmetica effettiva del filtro.
Tipo di dati di origine Tipo di dati di destinazione Regola di conversione
GALLEGGIARE Numero intero a virgola fissa Di seguito è riportata la procedura generale per la conversione di un numero a virgola mobile n in un numero intero a virgola fissa i.f, dove i è il numero di bit interi (con segno) e f è il numero di bit frazionari.
  • Compute FixedMin = -2⁽ⁱ⁻¹⁾
  • Compute FixedMax = 2⁽ⁱ⁻¹⁾ - 2(-f)
  • Se n è un NaN, risultato = 0; se n è +Inf, result = FixedMax*2f; se n è -Inf, result = FixedMin*2f
  • Se n >= FixedMax, result = Fixedmax*2f; if n <= FixedMin, result = FixedMin*2f
  • In caso contrario, calcolare n*2f e convertirlo in integer.
Le implementazioni sono consentiteD3D xx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULPLast-Place tolleranza nel risultato intero, invece del valore infinito preciso n*2f dopo l'ultimo passaggio precedente.
Numero intero a virgola fissa GALLEGGIARE Si supponga che la rappresentazione a virgola fissa specifica da convertire in float non contenga più di un totale di 24 bit di informazioni, non più di 23 bit di cui si trova nel componente frazionaria. Si supponga che un determinato numero a virgola fissa, fxp, sia in formato i.f (i bit integer, f bits fraction). La conversione in float è simile allo pseudocodice seguente.
float result = (float)(fxp >> f) + // extract integer
((float)(fxp & (2f - 1)) / (2f)); estrai frazione

 

Risorse (Direct3D 10)