Condividi tramite


Decompattazione e compattazione di DXGI_FORMAT per la modifica delle immagini In-Place

Il file D3DX_DXGIFormatConvert.inl contiene funzioni di conversione inline che è possibile usare nei compute shader o pixel shader su hardware Direct3D 11. È possibile usare queste funzioni nella tua applicazione per leggere e scrivere contemporaneamente in una texture. 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 è inclusa nel vecchio SDK DirectX. È incluso anche nel pacchetto NuGet Microsoft.DXSDK.D3DX.

La visualizzazione di accesso non ordinato (UAV) di una risorsa Texture1D, Texture2D o Texture3D supporta letture e scritture casuali in memoria da un compute shader o 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 casualmente alla scrittura in altri formati oppure è possibile usare solo una visualizzazione risorse shader (SRV) per l'accesso casuale in lettura da tali altri formati. L'hardware di conversione del formato non è disponibile per la lettura simultanea e la scrittura in tali altri formati.

Tuttavia, è comunque possibile leggere e scrivere simultaneamente in altri formati convertendo la trama nel formato DXGI_FORMAT_R32_UINT quando si crea un UAV, a condizione che il formato originale della risorsa supporti la conversione a DXGI_FORMAT_R32_UINT. La maggior parte dei formati a 32 bit per elemento supporta il casting a DXGI_FORMAT_R32_UINT. Eseguendo il cast della texture nel formato DXGI_FORMAT_R32_UINT quando si crea un UAV, è possibile eseguire letture e scritture simultanee sulla texture, purché lo shader esegua manualmente la decompressione del formato in lettura e la compressione in scrittura.

Il vantaggio di convertire la trama nel formato DXGI_FORMAT_R32_UINT è che successivamente è possibile utilizzare il formato appropriato (ad esempio, DXGI_FORMAT_R16G16_FLOAT) con altre visualizzazioni sulla stessa trama, come le visualizzazioni del bersaglio di rendering (RTV) o SRV. Pertanto, l'hardware può eseguire l'estrazione e l'impacchettamento automatico del formato tipico, può eseguire il filtro delle texture e così via dove non ci sono 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 direttamente

  1. Creare una trama con l'appropriato formato TYPELESS-dipendente specificato nello scenario precedente, insieme ai necessari flag di associazione, come 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 "famiglie" di formato diverso. Tuttavia, l'API Direct3D 11 crea un'eccezione con il formato DXGI_FORMAT_R32_UINT.

  3. Nel compute shader o nel pixel shader, utilizzare le funzioni inline di impacchettamento e decompressione appropriate fornite nel file D3DX_DXGIFormatConvert.inl. Si supponga, ad esempio, che l'UAV DXGI_FORMAT_R32_UINT della texture 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 su un UAV o leggere come un SRV, non è necessario eseguire questa conversione perché è possibile usare UAV o SRV completamente tipizzati. Le funzioni di conversione del formato fornite in D3DX_DXGIFormatConvert.inl sono potenzialmente utili solo se si desidera leggere e scrivere simultaneamente su un UAV di una texture.

 

Di seguito è riportato l'elenco delle funzioni di conversione del formato incluse nel file D3DX_DXGIFormatConvert.inl. Queste funzioni vengono classificate in base al DXGI_FORMAT che scompattano e impacchettano. Ognuno dei formati supportati deriva da uno dei formati TYPELESS elencati nello scenario precedente e supporta il casting verso DXGI_FORMAT_R32_UINT in qualità di 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 in HLSL

Guida alla programmazione di per HLSL