Share via


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 il numero di complemento di un bit 2, il valore massimo significa 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 corrisponde a -1,0f (ad esempio, il valore a 5 bit 10001 corrisponde a -1,0f). Esistono quindi due rappresentazioni integer per -1,0f. È presente una singola rappresentazione per 0,0f e una singola rappresentazione per 1,0f. In questo modo si ottiene un set di rappresentazioni integer per i valori a virgola mobile a virgola mobile uniforme nell'intervallo (-1,0f... 0,0f) e anche un set 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 1 significano 1,0f. Viene rappresentata una sequenza di valori a virgola mobile a virgola mobile 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. Numero 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.
FLOAT 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 integer senza segno tra tutte le 0 e tutte le 1 rappresenta 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 sequenza di colori, apparirebbe come una rampa lineare di livelli di luminosità a un osservatore "medio", in condizioni di visualizzazione "medie", su una visualizzazione "media". Per informazioni dettagliate complete, 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 a virgola mobile, si applicano le regole seguenti.

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

  • Viene usato da arrotondamento a zero durante la conversione in un altro formato float. Se la destinazione è un formato integer o a virgola fissa, viene usata la funzione round-to-near-even, a meno che la conversione non sia documentata in modo esplicito come l'uso di 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), SENZA includere 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 (poiché Denorms nelle operazioni sui float a 32 bit scaricano per firmare mantenuto 0).

Conversione integer

Nella tabella seguente vengono descritte le conversioni da varie rappresentazioni descritte in precedenza ad 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 FLOAT 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 viene mappato a -1,0f. Ad esempio, il valore a 5 bit 10000 corrisponde 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.
FLOAT 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 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 scale, 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 aggiuntivo di invertibilità dei dati garantisce che la conversione non venga creata nell'intervallo e che tutti i valori di output siano raggiungibili. Nelle costanti illustrate di seguito, xx deve essere sostituito con la versione Direct3D, ad esempio 10, 11 o 12.
UNORM FLOAT 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).
FLOAT 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 a 0,0f.
  • Convertire 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 D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place (sul lato intero). Ciò significa che dopo la conversione da float a integer scale, 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 aggiuntivo di invertibilità dei dati garantisce che la conversione non venga creata nell'intervallo e che tutti i valori di output siano raggiungibili.
SRGB FLOAT Di seguito è riportato il valore SRGB ideale per la conversione 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 D3Dxx_SRGB_TO_FLOAT_TOLERANCE_IN_ULP Unit-Last-Place (sul lato SRGB).
FLOAT SRGB Di seguito è riportata la conversione FLOAT -> SRGB ideale.
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 a 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
  • Convertire 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 D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP Unit-Last-Place (sul lato intero). Ciò significa che dopo la conversione da float a integer scale, 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 aggiuntivo di invertibilità dei dati garantisce che la conversione non venga creata 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 (LSB) del formato di destinazione 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 un numero minore o uguale di bit (e/o modifica della firma), il valore iniziale viene semplicemente bloccato nell'intervallo del formato di destinazione.

 

Conversione integer a virgola fissa

Gli 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" onnipresente è un caso speciale di un numero intero a virgola fissa con il decimale alla fine del numero.

Le rappresentazioni dei numeri a virgola fissa sono caratterizzate come: 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 definito equamente anche per gli 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 dove si trova il decimale implicito. L'aggiunta di 1 a un numero a virgola fissa di 16,8 significa semplicemente aggiungere 256, poiché il decimale è 8 posizioni dalla fine meno significativa del numero. Altre operazioni, ad esempio la moltiplicazione, possono essere eseguite anche 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 integer 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 bloccate a virgola fissa, mentre altre operazioni, ad esempio l'installazione dell'interpolatore di attributi, usano posizioni che sono state convertite in virgola mobile dalle posizioni bloccate del punto fisso.
  • Le coordinate delle trame per le operazioni di campionamento vengono mappate 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 di filtro. I valori di peso vengono riconvertiti in virgola mobile prima dell'esecuzione effettiva dell'aritmetica del filtro.
Tipo di dati di origine Tipo di dati di destinazione Regola di conversione
FLOAT Numero intero a virgola fissa Di seguito è riportata la procedura generale per convertire 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.
  • Calcolo FixedMin = -2⁽ⁱ⁻¹⁾
  • Calcolo FixedMax = 2⁽ⁱ⁻¹⁾ - 2(-f)
  • Se n è un NaN, result = 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 consentite D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP tolleranza Unit-Last-Place nel risultato intero, anziché il valore infinito preciso n*2f dopo l'ultimo passaggio precedente.
Numero intero a virgola fissa FLOAT Si supponga che la rappresentazione a virgola fissa specifica convertita 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 bit (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)