Sdílet prostřednictvím


Pravidla převodu dat

Následující části popisují, jak Direct3D zpracovává převody mezi datovými typy.

Terminologie datových typů

Následující sada termínů se následně používá k charakterizaci různých převodů formátu.

Semestr Definice
SNORM Zadané normalizované celé číslo, což znamená, že pro číslo doplňku 2 n-bitu znamená maximální hodnota 1,0f (např. 5bitová hodnota 01111 se mapuje na hodnotu 1,0f) a minimální hodnota znamená -1,0f (např. 5bitová hodnota 10000 se mapuje na -1,0f). Kromě toho se druhý minimální počet mapuje na -1,0f (např. 5bitová hodnota 10001 se mapuje na -1,0f). Existují tedy dvě celočíselné reprezentace pro -1,0f. Pro 0,0f existuje jedna reprezentace a jedna reprezentace pro 1.0f. Výsledkem je sada celočíselné reprezentace pro rovnoměrně rozložené hodnoty s plovoucí desetinou čárkou v oblasti (-1,0f... 0,0f) a také doplňková sada reprezentací čísel v rozsahu (0,0f... 1.0f)
UNORM Unsigned normalized integer, that for an n-bit number, all 0's means 0,0f, and all 1's means 1.0f. Je reprezentována posloupnost rovnoměrně rozmístěných hodnot s plovoucí desetinou čárkou od 0,0f do 1,0f. Například 2bitová verze UNORM představuje 0,0f, 1/3, 2/3 a 1,0f.
SINT Celé číslo se hlásí. 2. celé číslo doplňku. Například 3bitový SINT představuje celočíselné hodnoty -4, -3, -2, -1, 0, 1, 2, 3.
UINT Celé číslo bez znaménka Například 3bitový UINT představuje celočíselné hodnoty 0, 1, 2, 3, 4, 5, 6, 7.
PLOUT Hodnota s plovoucí desetinou čárkou v libovolné z reprezentací definovaných rozhraním Direct3D.
SRGB Podobně jako UNORM znamená pro n-bitové číslo všechny 0,0f a všechny 1 znamená 1,0f. Na rozdíl od UNORM však sekvenci celočíselného kódování bez znaménka mezi všemi 0 a všemi 1 představuje nelineární průběh v interpretaci čísel s plovoucí desetinou čárkou v rozmezí od 0,0f do 1,0f. Zhruba, pokud je tato nelineární progrese SRGB zobrazena jako posloupnost barev, zobrazí se jako lineární rampa úrovní světelnosti pro "průměrný" pozorovatel za "průměrných" podmínek zobrazení na "průměrném" displeji. Podrobné informace naleznete v barevné normě SRGB, IEC 61996-2-1, v IEC (International Electrotechnical Commission).

 

Převod s plovoucí desetinou čárkou

Kdykoli dojde k převodu s plovoucí desetinou čárkou mezi různými reprezentacemi, včetně reprezentací s plovoucí desetinou čárkou nebo z jiných reprezentací, platí následující pravidla.

Konververtování z reprezentace vyššího rozsahu na reprezentaci nižšího rozsahu

  • Při převodu do jiného plovoucího formátu se používá zaokrouhlení na nulu. Pokud je cílem celočíselná nebo pevná hodnota formátu, použije se zaokrouhlení na nejbližší sudé číslo, pokud není převod explicitně zdokumentován jako použití jiného chování zaokrouhlení, například zaokrouhlení na nejbližší pro FLOAT na SNORM, FLOAT na UNORM nebo FLOAT na SRGB. Další výjimky jsou ftoi a ftou shader instrukce, které používají round-to-zero. A konečně, převody float-to-pevné používané vzorkovačem textury a rasterizátory mají zadanou toleranci měřenou v jednotkovéLast-Place z nekonečného přesného ideálního.
  • U zdrojových hodnot větších než dynamický rozsah cílového formátu nižšího rozsahu (např. velká 32bitová hodnota float je zapsána do 16bitové hodnoty float RenderTarget), maximální reprezentovatelné (správně podepsané) hodnoty, NIKOLI včetně nekonečna se signepsem (kvůli zaokrouhlení na nulu popsanou výše).
  • NaN ve formátu vyššího rozsahu se převede na reprezentaci NaN ve formátu nižšího rozsahu, pokud reprezentace NaN existuje ve formátu nižšího rozsahu. Pokud nižší formát neobsahuje reprezentaci NaN, výsledek bude 0.
  • INF ve formátu vyššího rozsahu bude převeden na INF v nižším formátu rozsahu, pokud je k dispozici. Pokud nižší formát neobsahuje reprezentaci INF, převede se na maximální hodnotu reprezentovatelnou. Znaménko se zachová, pokud je k dispozici v cílovém formátu.
  • Denorm ve formátu vyššího rozsahu bude převeden na denorm reprezentaci ve formátu nižšího rozsahu, pokud je k dispozici ve formátu nižšího rozsahu a převod je možný, jinak je výsledek 0. Bit znaménka se zachová, pokud je k dispozici v cílovém formátu.

Převod z reprezentace nižšího rozsahu na reprezentaci vyššího rozsahu

  • NaN ve formátu nižšího rozsahu se převede na reprezentaci NaN ve formátu vyššího rozsahu, pokud je k dispozici ve formátu vyššího rozsahu. Pokud formát vyššího rozsahu neobsahuje reprezentaci NaN, převede se na 0.
  • INF ve formátu nižšího rozsahu bude převeden na reprezentaci INF ve formátu vyššího rozsahu, pokud je k dispozici ve formátu vyššího rozsahu. Pokud vyšší formát neobsahuje reprezentaci INF, převede se na maximální hodnotu reprezentovatelnou (MAX_FLOAT v daném formátu). Znaménko se zachová, pokud je k dispozici v cílovém formátu.
  • Denorm ve formátu nižšího rozsahu bude převeden na normalizovanou reprezentaci ve formátu vyššího rozsahu, pokud je to možné, nebo jinak na reprezentaci Denorm ve formátu vyššího rozsahu, pokud existuje reprezentace Denorm. Pokud formát vyššího rozsahu neobsahuje denormní reprezentaci, převede se na 0. Znaménko se zachová, pokud je k dispozici v cílovém formátu. Všimněte si, že 32bitová čísla float se počítají jako formát bez reprezentace Denorm (protože denormy v operacích s 32bitovými plovoucími plovoucími čísly se zachovají na 0).

Celočíselné převody

Následující tabulka popisuje převody z různých reprezentací popsaných výše na jiné reprezentace. Zobrazí se pouze převody, ke kterým skutečně dochází v Direct3D.

Datový typ zdroje Cílový datový typ Pravidlo převodu
SNORM PLOUT Vzhledem k n-bitové celočíselné hodnotě představující rozsah signed [-1,0f až 1,0f], převod na číslo s plovoucí desetinou čárkou je následující.
  • Záporná hodnota se mapuje na -1,0f. Například 5bitová hodnota 10000 mapuje na -1,0f.
  • Každá ostatní hodnota se převede na hodnotu float (zavolejte ji c) a výsledek = c * (1,0f / (2⁽ⁿ⁻¹⁾-1)). Například 5bitová hodnota 10001 se převede na -15,0f a pak vydělí hodnotou 15,0f a získá hodnotu -1,0f.
PLOUT SNORM Při zadání čísla s plovoucí desetinou čárkou je převod na celočíselnou hodnotu n-bitu představující rozsah signed range [-1,0f až 1,0f] následujícím způsobem.
  • Let c představuje počáteční hodnotu.
  • Pokud je c naN, výsledek je 0.
  • Pokud c > 1.0f, včetně INF, je upínací na 1.0f.
  • Pokud c < -1.0f, včetně -INF, je upínací na -1.0f.
  • Převod z plovoucího měřítka na celočíselné měřítko: c = c * (2ⁿ⁻¹-1).
  • Následujícím způsobem převeďte na celé číslo.
    • Pokud c >= 0, pak c = c + 0,5f, jinak c = c - 0,5f.
    • Přetažení desetinné čárky a zbývající hodnota s plovoucí desetinnou čárkou (celočíselná) se převede přímo na celé číslo.
Tento převod je povolena tolerance D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_Unit-Last-Place jednotkovéLast-Place (na straně celého čísla). To znamená, že po převodu z float na celočíselné měřítko je možné namapovat libovolnou hodnotu v rámci D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP jednotku –Last-Place reprezentovatelné cílové hodnoty formátu. Dodatečný požadavek na invertovatelnost dat zajišťuje, že převod není v rozsahu a všechny výstupní hodnoty jsou dosažitelné. (V zde uvedených konstantách by xx měly být nahrazeny verzí Direct3D, například 10, 11 nebo 12.)
UNORM PLOUT Počáteční n-bitová hodnota se převede na hodnotu float (0.0f, 1.0f, 2.0f atd.) a pak ji vydělí (2ⁿ-1).
PLOUT UNORM Let c představuje počáteční hodnotu.
  • Pokud je c naN, výsledek je 0.
  • Pokud c > 1.0f, včetně INF, je upínací na 1.0f.
  • Pokud c < 0,0f, včetně -INF, je upínací na 0,0f.
  • Převod z plovoucího měřítka na celočíselné měřítko: c = c * (2ⁿ-1).
  • Převede na celé číslo.
    • c = c + 0,5f.
    • Desetinná desetinná čárka se zahodí a zbývající hodnota s plovoucí desetinnou čárkou (celočíselná) se převede přímo na celé číslo.
Tento převod je povolena tolerance D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP jednotkovéLast-Place (na celočíselné straně). To znamená, že po převodu z float na celočíselné měřítko je možné namapovat libovolnou hodnotu v rámci D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP jednotku –Last-Place reprezentovatelné cílové hodnoty formátu. Dodatečný požadavek na invertovatelnost dat zajišťuje, že převod není v rozsahu a všechny výstupní hodnoty jsou dosažitelné.
SRGB PLOUT Následuje ideální převod SRGB na FLOAT.
  • Vezměte počáteční n-bitovou hodnotu, převeďte ji float (0.0f, 1.0f, 2.0f atd.); zavolejte to c.
  • c = c * (1.0f / (2ⁿ-1))
  • Pokud (c < = D3Dxx_SRGB_TO_FLOAT_THRESHOLD) pak: 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
Tento převod je povolena tolerance D3Dxx_SRGB_TO_FLOAT_TOLERANCE_IN_ULP jednotkovéLast-Place (na straně SRGB).
PLOUT SRGB Následuje ideální převod FLOAT -> SRGB.
Za předpokladu, že cílová barevná komponenta SRGB obsahuje n bitů:
  • Předpokládejme, že počáteční hodnota je c.
  • Pokud je c naN, výsledek je 0.
  • Je-li c > 1.0f, včetně INF, je upínací na 1.0f.
  • Pokud c < 0,0f, včetně -INF, je upínací na 0,0f.
  • Pokud (c <= D3Dxx_FLOAT_TO_SRGB_THRESHOLD) pak: 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
  • Převod z plovoucího měřítka na celočíselné měřítko: c = c * (2ⁿ-1).
  • Převést na celé číslo:
    • c = c + 0,5f.
    • Desetinná desetinná čárka se zahodí a zbývající hodnota s plovoucí desetinnou čárkou (celočíselná) se převede přímo na celé číslo.
Tento převod je povolena tolerance D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP jednotkovéLast-Place (na celočíselné straně). To znamená, že po převodu z float na celočíselné měřítko je možné namapovat libovolnou hodnotu v rámci D3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP jednotku –Last-Place reprezentovatelné cílové hodnoty formátu. Dodatečný požadavek na invertovatelnost dat zajišťuje, že převod není v rozsahu a všechny výstupní hodnoty jsou dosažitelné.
SINT SINT s více bity Pokud chcete převést z SINT na SINT s více bity, nejvýznamnější bit (MSB) počátečního čísla je "sign-extended" na další bity dostupné v cílovém formátu.
UINT SINT s více bity Pokud chcete převést Z UINT na SINT s více bity, zkopíruje se číslo do nejméně významných bitů cílového formátu (LSB) a další msb jsou vycpané číslem 0.
SINT UINT s více bity Chcete-li převést z SINT na UINT s více bity: Pokud je záporná, hodnota se uchytá na hodnotu 0. V opačném případě se číslo zkopíruje do LSB cílového formátu a další MSB se vycpávají číslem 0.
UINT UINT s více bity Chcete-li převést z UINT na UINT s více bity, číslo se zkopíruje do LSB cílového formátu a další MSB jsou vycpané číslem 0.
SINT nebo UINT SINT nebo UINT s menším nebo rovným bitem Chcete-li převést z SINT nebo UINT na SINT nebo UINT s menším nebo rovným bitem (a/nebo změnou signativy), počáteční hodnota se jednoduše upne na rozsah cílového formátu.

 

Převod celočíselného čísla s pevným bodem

Celá čísla s pevnou desetinnou čárkou jsou jednoduše celá čísla určité velikosti bitu, která mají implicitní desetinnou čárku v pevném umístění.

Všudypřítomný datový typ "celé číslo" je zvláštní případ celého čísla s pevným bodem s desetinnou čárkou na konci čísla.

Číselná čísla s pevnými body jsou charakterizována takto: i.f, kde i je počet celých bitů a f je počet desetinných bitů. Například 16,8 znamená 16 bitů celé číslo následované 8 bity zlomku. Celočíselná část je uložena v doplňku 2, alespoň tak, jak je zde definováno (i když lze definovat stejně pro celá čísla bez znaménka). Zlomková část je uložena v nepodepsané podobě. Zlomková část vždy představuje kladný zlomek mezi dvěma nejbližšími celočíselnými hodnotami počínaje nejvíce negativními.

Operace sčítání a odčítání u čísel s pevnými body se provádějí jednoduše pomocí standardního celočíselného aritmetika, aniž by bylo potřeba vzít v úvahu, kde implicitní desetinná místa leží. Přičtením čísla 1 k pevnému bodu 16,8 stačí sčítá číslo 256, protože desetinné číslo je 8 míst od nejméně významného konce čísla. Jiné operace, jako je násobení, je možné provádět i jednoduše pomocí celočíselné aritmetické operace, pokud je výsledkem pevné desetinné číslo. Například násobením dvou 16,8 celých čísel pomocí celočíselného násobení vznikne výsledek 32,16.

Celočíselné reprezentace s pevnými body se v Direct3D používají dvěma způsoby.

  • Post-clipped vrchol pozice v rastrovači jsou přichycené k pevnému bodu, aby se rovnoměrně rozmístit přesnost napříč oblastí RenderTarget. Mnoho rastrových operací, včetně odvrácení tváře jako jednoho příkladu, se vyskytuje na pevných pozicích přichycených bodů, zatímco jiné operace, jako je nastavení interpolátoru atributů, používají pozice, které byly převedeny zpět na plovoucí desetinnou čárku z pevné pozice přichycené bodem.
  • Souřadnice textury pro operace vzorkování jsou přichycené k pevnému bodu (po škálování podle velikosti textury), aby se rovnoměrně rozmísťovala přesnost mezi prostor textury při výběru umístění/váhy filtru. Hodnoty váhy se před provedením aritmetické operace skutečného filtrování převedou zpět na plovoucí desetinu.
Datový typ zdroje Cílový datový typ Pravidlo převodu
PLOUT Celé číslo s pevným bodem Následuje obecný postup pro převod čísla s plovoucí desetinnou čárkou n na celé číslo s pevnou desetinnou čárkou, i.f, kde i je počet bitů celého čísla (signed) a f je počet desetinných bitů.
  • Compute FixedMin = -2⁽ⁱ⁻¹⁾
  • Compute FixedMax = 2⁽ⁱ⁻¹⁾ - 2(-f)
  • Pokud n je naN, výsledek = 0; pokud n je +Inf, výsledek = FixedMax*2f; pokud n je -Inf, výsledek = FixedMin*2f
  • Pokud n >= FixedMax, výsledek = Fixedmax*2f; pokud n <= FixedMin, result = FixedMin*2f
  • Jinak vypočítá n*2f a převede na celé číslo.
Implementace jsou povoleny d3Dxx_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP jednotek -Last-Place tolerance v celočíselném výsledku, místo nekonečné přesné hodnoty n*2f po posledním kroku výše.
Celé číslo s pevným bodem PLOUT Předpokládejme, že reprezentace konkrétního pevného bodu převedená na plovoucí desetinnou čárku neobsahuje více než celkem 24 bitů informací, maximálně 23 bitů, z nichž je ve zlomkové komponentě. Předpokládejme, že dané číslo s pevným bodem, fxp, je ve formátu i.f (i bits integer, f bits zlomek). Převod na float je podobný následujícímu pseudokódu.
float result = (float)(fxp >> f) + // extrahování celého čísla
((float)(fxp & (2f - 1)) / (2f)); extrakce zlomku

 

zdroje (Direct3D 10)