Auspacken und Packen von DXGI_FORMAT für In-Place Bildbearbeitung

Die Datei D3DX_DXGIFormatConvert.inl enthält Inlineformatkonvertierungsfunktionen, die Sie im Compute-Shader oder Pixelshader auf Direct3D 11-Hardware verwenden können. Sie können diese Funktionen in Ihrer Anwendung verwenden, um gleichzeitig aus einer Textur zu lesen und in eine Textur zu schreiben. Das heißt, Sie können eine direkte Bildbearbeitung durchführen. Um diese Inlineformatkonvertierungsfunktionen zu verwenden, schließen Sie die Datei D3DX_DXGIFormatConvert.inl in Ihre Anwendung ein.

Der D3DX_DXGIFormatConvert.inl-Header ist im Legacy-DirectX SDK enthalten. Es ist auch im NuGet-Paket Microsoft.DXSDK.D3DX enthalten.

Die ungeordnete Zugriffsansicht (UAV) von Direct3D 11 einer Textur1D-, Texture2D- oder Texture3D-Ressource unterstützt zufällige Lese- und Schreibvorgänge in den Arbeitsspeicher von einem Compute-Shader oder Pixelshader. Direct3D 11 unterstützt jedoch gleichzeitig das Lesen und Schreiben in das DXGI_FORMAT_R32_UINT Texturformat. Direct3D 11 unterstützt beispielsweise nicht gleichzeitiges Lesen von und Schreiben in anderen, nützlicheren Formaten, z. B. DXGI_FORMAT_R8G8B8A8_UNORM. Sie können nur eine UAV verwenden, um nach dem Zufallszugriff in solche anderen Formate zu schreiben, oder Sie können nur eine Shader-Ressourcenansicht (SRV) verwenden, um zufällige Lesevorgänge aus solchen anderen Formaten zu erhalten. Die Hardware für die Formatkonvertierung ist nicht verfügbar, um gleichzeitig aus diesen anderen Formaten zu lesen und zu schreiben.

Sie können jedoch gleichzeitig aus anderen Formaten lesen und in solche anderen Formate schreiben, indem Sie die Textur beim Erstellen eines UAV in das DXGI_FORMAT_R32_UINT-Texturformat umwandeln, sofern das ursprüngliche Format der Ressource die Umwandlung in DXGI_FORMAT_R32_UINT unterstützt. Die meisten 32-Bit-Formate pro Element unterstützen die Umwandlung in DXGI_FORMAT_R32_UINT. Wenn Sie beim Erstellen eines UAV die Textur in das DXGI_FORMAT_R32_UINT Texturformat umwandeln, können Sie gleichzeitig Lese- und Schreibvorgänge in die Textur ausführen, solange der Shader das manuelle Auspacken des Formats beim Lesen und Packen beim Schreiben ausführt.

Der Vorteil der Umwandlung der Textur in das DXGI_FORMAT_R32_UINT Texturformat besteht darin, dass Sie später das entsprechende Format (z. B. DXGI_FORMAT_R16G16_FLOAT) mit anderen Ansichten derselben Textur verwenden können, z. B. Renderzielansichten (RTVs) oder SRVs. Daher kann die Hardware das typische automatische Format auspacken und packen, texturfiltern und so weiter, wo keine Hardwareeinschränkungen bestehen.

Im folgenden Szenario muss eine Anwendung die folgende Abfolge von Aktionen ausführen, um eine direkte Bildbearbeitung durchzuführen.

Angenommen, Sie möchten eine Textur erstellen, für die Sie einen Pixel-Shader oder Compute-Shader verwenden können, um die direkte Bearbeitung durchzuführen, und Sie möchten, dass die Texturdaten in einem Format gespeichert werden, das ein Nachfolger eines der folgenden TYPELESS-Formate ist:

  • DXGI_FORMAT_R10G10B10A2_TYPELESS
  • DXGI_FORMAT_R8G8B8A8_TYPELESS
  • DXGI_FORMAT_B8G8R8A8_TYPELESS
  • DXGI_FORMAT_B8G8R8X8_TYPELESS
  • DXGI_FORMAT_R16G16_TYPELESS

Beispielsweise ist das DXGI_FORMAT_R10G10B10A2_UNORM Format ein Nachfolger des DXGI_FORMAT_R10G10B10A2_TYPELESS-Formats. Daher unterstützt DXGI_FORMAT_R10G10B10A2_UNORM das Verwendungsmuster, das in der folgenden Sequenz beschrieben wird. Formate, die von DXGI_FORMAT_R32_TYPELESS abstammen, z. B. DXGI_FORMAT_R32_FLOAT, werden trivial unterstützt, ohne dass eine der in der folgenden Sequenz beschriebenen Hilfen zur Formatkonvertierung erforderlich ist.

So führen Sie die direkte Bildbearbeitung durch

  1. Erstellen Sie eine Textur mit dem entsprechenden TYPELESS-abhängigen Format, das im vorherigen Szenario angegeben wurde, zusammen mit den erforderlichen Bindungsflags, z. B. D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE.

  2. Erstellen Sie für die direkte Bildbearbeitung ein UAV mit dem format DXGI_FORMAT_R32_UINT. Die Direct3D 11-API lässt in der Regel keine Umwandlung zwischen verschiedenen Formaten zu. Die Direct3D 11-API macht jedoch eine Ausnahme mit dem DXGI_FORMAT_R32_UINT Format.

  3. Verwenden Sie im Compute-Shader oder Pixelshader das entsprechende Inlineformatpaket und die Entpackfunktionen, die in der Datei D3DX_DXGIFormatConvert.inl bereitgestellt werden. Angenommen, die DXGI_FORMAT_R32_UINT UAV der Textur enthält wirklich DXGI_FORMAT_R10G10B10A2_UNORM formatierten Daten. Nachdem die Anwendung ein uint aus dem UAV in den Shader gelesen hat, muss sie die folgende Funktion aufrufen, um das Texturformat zu entpacken:

    XMFLOAT4 D3DX_R10G10B10A2_UNORM_to_FLOAT4(UINT packedInput)
    

    Um dann in das UAV im selben Shader zu schreiben, ruft die Anwendung die folgende Funktion auf, um Shaderdaten in einen Uint zu packen, den die Anwendung in das UAV schreiben kann:

    UINT D3DX_FLOAT4_to_R10G10B10A2_UNORM(hlsl_precise XMFLOAT4 unpackedInput)
    
  4. Die Anwendung kann dann andere Ansichten erstellen, z. B. SRVs, mit dem erforderlichen Format. Beispielsweise kann die Anwendung eine SRV mit dem DXGI_FORMAT_R10G10B10A2_UNORM Format erstellen, wenn die Ressource als DXGI_FORMAT_R10G10B10A2_TYPELESS erstellt wurde. Wenn ein Shader auf diese SRV zugreift, kann die Hardware wie gewohnt eine automatische Typkonvertierung durchführen.

Hinweis

Wenn der Shader nur in ein UAV schreiben oder als SRV lesen muss, ist keine dieser Konvertierungsarbeiten erforderlich, da Sie voll typisierte UAVs oder SRVs verwenden können. Die in D3DX_DXGIFormatConvert.inl bereitgestellten Formatkonvertierungsfunktionen sind möglicherweise nur nützlich, wenn Sie gleichzeitige Lese- und Schreibvorgänge aus einem UAV einer Textur durchführen möchten.

 

Im Folgenden ist die Liste der Formatkonvertierungsfunktionen aufgeführt, die in der Datei D3DX_DXGIFormatConvert.inl enthalten sind. Diese Funktionen werden nach den DXGI_FORMAT kategorisiert, die sie auspacken und packen. Jedes der unterstützten Formate stammt von einem der im vorherigen Szenario aufgeführten TYPELESS-Formate ab und unterstützt die Umwandlung in DXGI_FORMAT_R32_UINT als 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)

Hinweis

Die _inexact-Type-Funktion verwendet Shaderanweisungen, die nicht über eine hohe Genauigkeit verfügen, um die genaue Antwort zu erhalten. Die alternative Funktion verwendet eine im Shader gespeicherte Nachschlagetabelle, um eine genaue SRGB-float-Konvertierung> zu ermöglichen.

 

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)

Hinweis

Die _inexact-Type-Funktion verwendet Shaderanweisungen, die nicht über eine hohe Genauigkeit verfügen, um die genaue Antwort zu erhalten. Die alternative Funktion verwendet eine im Shader gespeicherte Nachschlagetabelle, um eine genaue SRGB-float-Konvertierung> zu ermöglichen.

 

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)

Hinweis

Die _inexact-Type-Funktion verwendet Shaderanweisungen, die nicht über eine hohe Genauigkeit verfügen, um die genaue Antwort zu erhalten. Die alternative Funktion verwendet eine im Shader gespeicherte Nachschlagetabelle, um eine genaue SRGB-float-Konvertierung> zu ermöglichen.

 

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)

Programmieranleitung für HLSL

Programmieranleitung für HLSL