In-Place影像編輯的解壓縮和封裝DXGI_FORMAT

D3DX_DXGIFormatConvert.inl 檔案包含內嵌格式轉換函式,您可以在 Direct3D 11 硬體上的計算著色器或圖元著色器中使用。 您可以在應用程式中使用這些函式,同時讀取和寫入紋理。 也就是說,您可以執行就地影像編輯。 若要使用這些內嵌格式轉換函式,請在應用程式中包含 D3DX_DXGIFormatConvert.inl 檔案。

D3DX_DXGIFormatConvert.inl 標頭隨附于舊版 DirectX SDK 中。 它也包含在Microsoft.DXSDK.D3DX NuGet套件中。

Direct3D 11 的 Unordered Access View (UAV) Texture1D、Texture2D 或 Texture3D 資源支援從計算著色器或圖元著色器隨機存取讀取和寫入記憶體。 不過,Direct3D 11 支援同時讀取和寫入至DXGI_FORMAT_R32_UINT紋理格式。 例如,Direct3D 11 不支援同時讀取和寫入其他更實用的格式,例如DXGI_FORMAT_R8G8B8A8_UNORM。 您只能使用 UAV 隨機存取寫入這類其他格式,或者只能使用著色器資源檢視 (SRV) ,以隨機存取讀取這類其他格式。 格式轉換硬體無法同時讀取和寫入這類其他格式。

不過,只要資源的原始格式支援轉換成DXGI_FORMAT_R32_UINT,您仍然可以同時讀取和寫入這類其他格式,方法是將紋理轉換成DXGI_FORMAT_R32_UINT紋理格式。 每個元素格式最多 32 位支援轉換成DXGI_FORMAT_R32_UINT。 藉由在建立 UAV 時將紋理轉換成DXGI_FORMAT_R32_UINT紋理格式,只要著色器在寫入時執行手動格式解除封裝,就可以同時執行紋理的讀取和寫入。

將紋理轉換成DXGI_FORMAT_R32_UINT紋理格式的優點是稍後您可以使用適當的格式 (例如,DXGI_FORMAT_R16G16_FLOAT) 相同紋理上的其他檢視,例如轉譯目標檢視 (RTV) 或 SRV。 因此,硬體可以執行一般自動解壓縮格式和套件、執行紋理篩選等,而沒有任何硬體限制。

下列案例需要應用程式採取下列動作順序來執行就地影像編輯。

假設您想要建立紋理,您可以使用圖元著色器或計算著色器來執行就地編輯,而且您想要將紋理資料儲存成下列其中一種 TYPELESS 格式的子系:

  • DXGI_FORMAT_R10G10B10A2_TYPELESS
  • DXGI_FORMAT_R8G8B8A8_TYPELESS
  • DXGI_FORMAT_B8G8R8A8_TYPELESS
  • DXGI_FORMAT_B8G8R8X8_TYPELESS
  • DXGI_FORMAT_R16G16_TYPELESS

例如,DXGI_FORMAT_R10G10B10A2_UNORM格式是DXGI_FORMAT_R10G10B10A2_TYPELESS格式的子系。 因此,DXGI_FORMAT_R10G10B10A2_UNORM支援下列順序中所述的使用模式。 從DXGI_FORMAT_R32_TYPELESS遞減的格式,例如DXGI_FORMAT_R32_FLOAT,可簡單支援,而不需要下列順序所述的任何格式轉換說明。

執行就地影像編輯

  1. 使用先前案例中指定的適當 TYPELESS 相依格式建立紋理,以及必要的系結旗標,例如D3D11_BIND_UNORDERED_ACCESS |D3D11_BIND_SHADER_RESOURCE。

  2. 若要進行就地影像編輯,請使用DXGI_FORMAT_R32_UINT格式建立 UAV。 Direct3D 11 API 通常不允許在不同的格式「系列」之間進行轉換。不過,Direct3D 11 API 會以DXGI_FORMAT_R32_UINT格式提出例外狀況。

  3. 在計算著色器或圖元著色器中,使用D3DX_DXGIFormatConvert.inl 檔案中提供的適當內嵌格式套件和解壓縮函式。 例如,假設紋理DXGI_FORMAT_R32_UINT UAV 確實會保存DXGI_FORMAT_R10G10B10A2_UNORM格式的資料。 應用程式將 UAV 中的 uint 讀入著色器之後,它必須呼叫下列函式來解除封裝紋理格式:

    XMFLOAT4 D3DX_R10G10B10A2_UNORM_to_FLOAT4(UINT packedInput)
    

    然後,若要在相同的著色器中寫入 UAV,應用程式會呼叫下列函式,將著色器資料封裝到應用程式可以寫入 UAV 的 uint:

    UINT D3DX_FLOAT4_to_R10G10B10A2_UNORM(hlsl_precise XMFLOAT4 unpackedInput)
    
  4. 然後,應用程式可以建立其他檢視,例如具有必要格式的 SRV。 例如,如果資源已建立為DXGI_FORMAT_R10G10B10A2_TYPELESS,則應用程式可以使用DXGI_FORMAT_R10G10B10A2_UNORM格式來建立 SRV。 當著色器存取該 SRV 時,硬體可以如往常執行自動類型轉換。

注意

如果著色器只能寫入 UAV 或讀取為 SRV,則不需要此轉換工作,因為您可以使用完整類型的 UAV 或 SRV。 只有在您想要同時讀取和寫入紋理的 UAV 時,D3DX_DXGIFormatConvert.inl 中提供的格式轉換函式才可能很有用。

 

以下是包含在 D3DX_DXGIFormatConvert.inl 檔案中的格式轉換函式清單。 這些函式會依解壓縮和封裝的DXGI_FORMAT進行分類。 每個支援的格式都會從上述案例所列的其中一個 TYPELESS 格式遞減,並支援轉換成 UAV DXGI_FORMAT_R32_UINT。

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)

注意

_inexact類型函式會使用沒有足夠精確度的著色器指令來提供確切答案。 替代函式會使用儲存在著色器中的查閱表格來提供確切的 SRGB-float > 轉換。

 

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)

注意

_inexact類型函式會使用沒有足夠精確度的著色器指令來提供確切答案。 替代函式會使用儲存在著色器中的查閱表格來提供確切的 SRGB-float > 轉換。

 

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)

注意

_inexact類型函式會使用沒有足夠精確度的著色器指令來提供確切答案。 替代函式會使用儲存在著色器中的查閱表格來提供確切的 SRGB-float > 轉換。

 

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)

HLSL 的程式設計指南

HLSL 的程式設計指南