Decompressione e compressione DXGI_FORMAT per In-Place modifica delle immagini

Il file D3DX_DXGIFormatConvert.inl contiene funzioni di conversione in formato inline che è possibile usare nell'hardware compute shader o pixel shader su hardware Direct3D 11. È possibile usare queste funzioni nell'applicazione per leggere e scrivere contemporaneamente in una trama. Ciò significa che è possibile eseguire la modifica delle immagini sul posto. Per usare queste funzioni di conversione in formato inline, includere il file D3DX_DXGIFormatConvert.inl nell'applicazione.

L'intestazione D3DX_DXGIFormatConvert.inl viene fornita nell'SDK DirectX legacy. È incluso anche nel pacchetto NuGet Microsoft.DXSDK.D3DX .

La visualizzazione di accesso non ordinato (UAV) di Direct3D 11 di una risorsa Texture1D, Texture2D o Texture3D supporta letture e scritture casuali di accesso in memoria da un compute shader o da un pixel shader. Tuttavia, Direct3D 11 supporta simultaneamente sia la lettura che la scrittura solo nel formato di trama DXGI_FORMAT_R32_UINT. Ad esempio, Direct3D 11 non supporta simultaneamente sia la lettura che la scrittura in altri formati più utili, ad esempio DXGI_FORMAT_R8G8B8A8_UNORM. È possibile usare solo un UAV per accedere in modo casuale alla scrittura in altri formati oppure è possibile usare solo una visualizzazione risorse shader (SRV) per accedere in modo casuale in lettura da altri formati. L'hardware di conversione del formato non è disponibile per la lettura e la scrittura simultanea in tali altri formati.

Tuttavia, è comunque possibile leggere e scrivere contemporaneamente in altri formati eseguendo il cast della trama nel formato di trama DXGI_FORMAT_R32_UINT quando si crea un UAV, purché il formato originale della risorsa supporti il cast a DXGI_FORMAT_R32_UINT. La maggior parte dei formati a 32 bit per elemento supporta il cast in DXGI_FORMAT_R32_UINT. Eseguendo il cast della trama nel formato di trama DXGI_FORMAT_R32_UINT quando si crea un UAV, è quindi possibile eseguire simultaneamente letture e scritture nella trama, purché lo shader esegua il decompressione manuale del formato in lettura e compressione durante la scrittura.

Il vantaggio di eseguire il cast della trama nel formato di trama DXGI_FORMAT_R32_UINT è che in un secondo momento è possibile usare il formato appropriato (ad esempio, DXGI_FORMAT_R16G16_FLOAT) con altre visualizzazioni sulla stessa trama, ad esempio viste di destinazione di rendering (RTV) o SRV. Pertanto, l'hardware può eseguire il tipico decomprimere e comprimere il formato automatico, può eseguire il filtro delle trame e così via in cui non sono presenti limitazioni hardware.

Lo scenario seguente richiede che un'applicazione esegua la sequenza di azioni seguente per eseguire la modifica delle immagini sul posto.

Si supponga di voler creare una trama in cui è possibile usare un pixel shader o un compute shader per eseguire la modifica sul posto e si vuole che i dati della trama vengano archiviati in un formato discendente di uno dei formati TYPELESS seguenti:

  • DXGI_FORMAT_R10G10B10A2_TYPELESS
  • DXGI_FORMAT_R8G8B8A8_TYPELESS
  • DXGI_FORMAT_B8G8R8A8_TYPELESS
  • DXGI_FORMAT_B8G8R8X8_TYPELESS
  • DXGI_FORMAT_R16G16_TYPELESS

Ad esempio, il formato DXGI_FORMAT_R10G10B10A2_UNORM è un discendente del formato DXGI_FORMAT_R10G10B10A2_TYPELESS. Pertanto, DXGI_FORMAT_R10G10B10A2_UNORM supporta il modello di utilizzo descritto nella sequenza seguente. I formati che derivano da DXGI_FORMAT_R32_TYPELESS, ad esempio DXGI_FORMAT_R32_FLOAT, sono facilmente supportati senza richiedere una delle informazioni di conversione del formato descritte nella sequenza seguente.

Per eseguire la modifica delle immagini sul posto

  1. Creare una trama con il formato dipendente typeless appropriato specificato nello scenario precedente insieme ai flag di associazione necessari, ad esempio D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE.

  2. Per la modifica delle immagini sul posto, creare un UAV con il formato DXGI_FORMAT_R32_UINT. L'API Direct3D 11 in genere non consente il cast tra diverse "famiglie". Tuttavia, l'API Direct3D 11 genera un'eccezione con il formato DXGI_FORMAT_R32_UINT.

  3. Nel compute shader o pixel shader usare le funzioni di pacchetto di formato inline e decomprime appropriate fornite nel file D3DX_DXGIFormatConvert.inl. Si supponga, ad esempio, che il DXGI_FORMAT_R32_UINT UAV della trama contenga effettivamente dati formattati DXGI_FORMAT_R10G10B10A2_UNORM. Dopo che l'applicazione legge un uint dall'UAV nello shader, deve chiamare la funzione seguente per decomprimere il formato della trama:

    XMFLOAT4 D3DX_R10G10B10A2_UNORM_to_FLOAT4(UINT packedInput)
    

    Quindi, per scrivere nell'UAV nello stesso shader, l'applicazione chiama la funzione seguente per comprimere i dati dello shader in un uint che l'applicazione può scrivere nell'UAV:

    UINT D3DX_FLOAT4_to_R10G10B10A2_UNORM(hlsl_precise XMFLOAT4 unpackedInput)
    
  4. L'applicazione può quindi creare altre visualizzazioni, ad esempio SRV, con il formato richiesto. Ad esempio, l'applicazione può creare un SRV con il formato DXGI_FORMAT_R10G10B10A2_UNORM se la risorsa è stata creata come DXGI_FORMAT_R10G10B10A2_TYPELESS. Quando uno shader accede a tale SRV, l'hardware può eseguire la conversione automatica dei tipi come di consueto.

Nota

Se lo shader deve scrivere solo in un UAV o leggere come SRV, nessuna di queste operazioni di conversione è necessaria perché è possibile usare UAV o SRV completamente tipizzato. Le funzioni di conversione del formato fornite in D3DX_DXGIFormatConvert.inl sono potenzialmente utili solo se si desidera eseguire la lettura e la scrittura simultanee in un UAV di una trama.

 

Di seguito è riportato l'elenco delle funzioni di conversione del formato incluse nel file D3DX_DXGIFormatConvert.inl. Queste funzioni sono classificate in base al DXGI_FORMAT che decomprimono e comprimono. Ognuno dei formati supportati deriva da uno dei formati TYPELESS elencati nello scenario precedente e supporta il cast in DXGI_FORMAT_R32_UINT come UAV.

DXGI_FORMAT_R10G10B10A2_UNORM

XMFLOAT4 D3DX_R10G10B10A2_UNORM_to_FLOAT4(UINT packedInput)
UINT     D3DX_FLOAT4_to_R10G10B10A2_UNORM(hlsl_precise XMFLOAT4 unpackedInput)

DXGI_FORMAT_R10G10B10A2_UINT

XMUINT4 D3DX_R10G10B10A2_UINT_to_UINT4(UINT packedInput)
UINT    D3DX_UINT4_to_R10G10B10A2_UINT(XMUINT4 unpackedInput)

DXGI_FORMAT_R8G8B8A8_UNORM

XMFLOAT4 D3DX_R8G8B8A8_UNORM_to_FLOAT4(UINT packedInput)
UINT     D3DX_FLOAT4_to_R8G8B8A8_UNORM(hlsl_precise XMFLOAT4 unpackedInput)

DXGI_FORMAT_R8G8B8A8_UNORM_SRGB

XMFLOAT4 D3DX_R8G8B8A8_UNORM_SRGB_to_FLOAT4_inexact(UINT packedInput) *
XMFLOAT4 D3DX_R8G8B8A8_UNORM_SRGB_to_FLOAT4(UINT packedInput)
UINT     D3DX_FLOAT4_to_R8G8B8A8_UNORM_SRGB(hlsl_precise XMFLOAT4 unpackedInput)

Nota

La funzione di tipo _inexact usa istruzioni shader che non hanno una precisione sufficiente per fornire la risposta esatta. La funzione alternativa usa una tabella di ricerca archiviata nello shader per fornire una conversione SRGB-float> esatta.

 

DXGI_FORMAT_R8G8B8A8_UINT

XMUINT4 D3DX_R8G8B8A8_UINT_to_UINT4(UINT packedInput)
XMUINT  D3DX_UINT4_to_R8G8B8A8_UINT(XMUINT4 unpackedInput)

DXGI_FORMAT_R8G8B8A8_SNORM

XMFLOAT4 D3DX_R8G8B8A8_SNORM_to_FLOAT4(UINT packedInput)
UINT     D3DX_FLOAT4_to_R8G8B8A8_SNORM(hlsl_precise XMFLOAT4 unpackedInput)

DXGI_FORMAT_R8G8B8A8_SINT

XMINT4 D3DX_R8G8B8A8_SINT_to_INT4(UINT packedInput)
UINT   D3DX_INT4_to_R8G8B8A8_SINT(XMINT4 unpackedInput)

DXGI_FORMAT_B8G8R8A8_UNORM

XMFLOAT4 D3DX_B8G8R8A8_UNORM_to_FLOAT4(UINT packedInput)
UINT     D3DX_FLOAT4_to_B8G8R8A8_UNORM(hlsl_precise XMFLOAT4 unpackedInput)

DXGI_FORMAT_B8G8R8A8_UNORM_SRGB

XMFLOAT4 D3DX_B8G8R8A8_UNORM_SRGB_to_FLOAT4_inexact(UINT packedInput) *
XMFLOAT4 D3DX_B8G8R8A8_UNORM_SRGB_to_FLOAT4(UINT packedInput)
UINT     D3DX_FLOAT4_to_R8G8B8A8_UNORM_SRGB(hlsl_precise XMFLOAT4 unpackedInput)

Nota

La funzione di tipo _inexact usa istruzioni shader che non hanno una precisione sufficiente per fornire la risposta esatta. La funzione alternativa usa una tabella di ricerca archiviata nello shader per fornire una conversione SRGB-float> esatta.

 

DXGI_FORMAT_B8G8R8X8_UNORM

XMFLOAT3 D3DX_B8G8R8X8_UNORM_to_FLOAT3(UINT packedInput)
UINT     D3DX_FLOAT3_to_B8G8R8X8_UNORM(hlsl_precise XMFLOAT3 unpackedInput)

DXGI_FORMAT_B8G8R8X8_UNORM_SRGB

XMFLOAT3 D3DX_B8G8R8X8_UNORM_SRGB_to_FLOAT3_inexact(UINT packedInput) *
XMFLOAT3 D3DX_B8G8R8X8_UNORM_SRGB_to_FLOAT3(UINT packedInput)
UINT     D3DX_FLOAT3_to_B8G8R8X8_UNORM_SRGB(hlsl_precise XMFLOAT3 unpackedInput)

Nota

La funzione di tipo _inexact usa istruzioni shader che non hanno una precisione sufficiente per fornire la risposta esatta. La funzione alternativa usa una tabella di ricerca archiviata nello shader per fornire una conversione SRGB-float> esatta.

 

DXGI_FORMAT_R16G16_FLOAT

XMFLOAT2 D3DX_R16G16_FLOAT_to_FLOAT2(UINT packedInput)
UINT     D3DX_FLOAT2_to_R16G16_FLOAT(hlsl_precise XMFLOAT2 unpackedInput)

DXGI_FORMAT_R16G16_UNORM

XMFLOAT2 D3DX_R16G16_UNORM_to_FLOAT2(UINT packedInput)
UINT     D3DX_FLOAT2_to_R16G16_UNORM(hlsl_precise FLOAT2 unpackedInput)

DXGI_FORMAT_R16G16_UINT

XMUINT2 D3DX_R16G16_UINT_to_UINT2(UINT packedInput)
UINT    D3DX_UINT2_to_R16G16_UINT(XMUINT2 unpackedInput)

DXGI_FORMAT_R16G16_SNORM

XMFLOAT2 D3DX_R16G16_SNORM_to_FLOAT2(UINT packedInput)
UINT     D3DX_FLOAT2_to_R16G16_SNORM(hlsl_precise XMFLOAT2 unpackedInput)

DXGI_FORMAT_R16G16_SINT

XMINT2 D3DX_R16G16_SINT_to_INT2(UINT packedInput)
UINT   D3DX_INT2_to_R16G16_SINT(XMINT2 unpackedInput)

Guida alla programmazione per HLSL

Guida alla programmazione per HLSL