In-Place 影像編輯的解壓縮和封裝DXGI_FORMAT
D3DX_DXGIFormatConvert.inl 檔案包含內嵌格式轉換函式,您可以在 Direct3D 11 硬體上的計算著色器或像素著色器中使用。 您可以在應用程式中使用這些函式,同時讀取和寫入紋理。 也就是說,您可以執行就地影像編輯。 若要使用這些內嵌格式轉換函式,請在應用程式中包含 D3DX_DXGIFormatConvert.inl 檔案。
D3DX_DXGIFormatConvert.inl 標頭隨附於舊版 DirectX SDK 中。 它也包含在 Microsoft.DXSDK.D3DX NuGet 套件中。
Texture1D、Texture2D 或 Texture3D 資源的 Direct3D 11 未排序存取檢視 (UAV) 支援從計算著色器或像素著色器隨機存取讀取和寫入記憶體。 不過,Direct3D 11 只支援在 DXGI_FORMAT_R32_UINT 紋理格式中進行同時讀取與寫入。 例如,Direct3D 11 不支援同時讀取和寫入至其他更實用的格式,例如DXGI_FORMAT_R8G8B8A8_UNORM。 您只能使用 UAV 來隨機存取寫入這類其他格式,或者只能使用著色器資源檢視 (SRV) 來隨機存取讀取這類其他格式。 格式轉換硬體無法同時讀取和寫入這類其他格式。
不過,只要資源的原始格式支援轉換為DXGI_FORMAT_R32_UINT,您仍然可以在建立UAV時將紋理轉換為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,都能輕易支援且不需要下列過程中所描述的任何格式轉換協助。
執行就地影像編輯
使用先前情境中指定的適當無類型相依格式,以及必要的綁定旗標建立紋理,例如 D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE。
若要進行就地影像編輯,請建立具有DXGI_FORMAT_R32_UINT格式的UAV。 Direct3D 11 API 通常不允許在不同的格式「系列」之間轉換。不過,Direct3D 11 API 會以DXGI_FORMAT_R32_UINT格式發出例外狀況。
在計算著色器或像素著色器中,使用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)
然後,應用程式可以使用所需格式來建立其他檢視,例如 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->浮點數轉換。
-
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->浮點數轉換。
-
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->浮點數轉換。
-
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 的 程序設計指南