【问题标题】:How can i resolve DXGI_FORMAT compatibility issues?如何解决 DXGI_FORMAT 兼容性问题?
【发布时间】:2020-11-06 16:54:44
【问题描述】:

我想使用计算着色器进行后期处理。所以想法是将CS输出设置为后台缓冲区。据我所知,这意味着使用无人机。但后台缓冲区使用 BGRA。所以这个:

Microsoft::WRL::ComPtr<ID3D11Texture2D> pBackBuffer;
pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &pBackBuffer);

D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc;
uav_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;// BGRA!
uav_desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
uav_desc.Texture2D.MipSlice = 0;

Microsoft::WRL::ComPtr<ID3D11UnorderedAccessView> pUnorderedAccessView;
pDevice->CreateUnorderedAccessView(
    pBackBuffer.Get(),
    &uav_desc,
    &pUnorderedAccessView);

生成错误:格式(0x57,B8G8R8A8_UNORM)不能用于类型化无序访问视图。

如果我尝试将格式更改为符合MDOCS 的兼容格式:

...
uav_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;// RGBA!
...

生成错误:创建视图时,格式(0x1c,R8G8B8A8_UNORM)无效;资源已使用完全限定的格式创建,该格式不可转换(0x57,B8G8R8A8_UNORM)。

问题是我不在乎格式是什么,因为它可以在计算着色器中修复!

有没有办法绕过这个?或者也许不使用无人机进行 CS 输出?

【问题讨论】:

    标签: c++ directx directx-11


    【解决方案1】:

    加载/存储仅支持 UAV 格式的子集,这就是 BGRA 格式失败的原因。

    逻辑编码在这个辅助函数中:

    // typedUAVLoadAdditionalFormats is the value obtained from D3D12_FEATURE_DATA_D3D12_OPTIONS.TypedUAVLoadAdditionalFormats
    
        bool FormatIsUAVCompatible(_In_ ID3D12Device* device, bool typedUAVLoadAdditionalFormats, DXGI_FORMAT format) noexcept
        {
            switch (format)
            {
            case DXGI_FORMAT_R32_FLOAT:
            case DXGI_FORMAT_R32_UINT:
            case DXGI_FORMAT_R32_SINT:
                // Unconditionally supported.
                return true;
    
            case DXGI_FORMAT_R32G32B32A32_FLOAT:
            case DXGI_FORMAT_R32G32B32A32_UINT:
            case DXGI_FORMAT_R32G32B32A32_SINT:
            case DXGI_FORMAT_R16G16B16A16_FLOAT:
            case DXGI_FORMAT_R16G16B16A16_UINT:
            case DXGI_FORMAT_R16G16B16A16_SINT:
            case DXGI_FORMAT_R8G8B8A8_UNORM:
            case DXGI_FORMAT_R8G8B8A8_UINT:
            case DXGI_FORMAT_R8G8B8A8_SINT:
            case DXGI_FORMAT_R16_FLOAT:
            case DXGI_FORMAT_R16_UINT:
            case DXGI_FORMAT_R16_SINT:
            case DXGI_FORMAT_R8_UNORM:
            case DXGI_FORMAT_R8_UINT:
            case DXGI_FORMAT_R8_SINT:
                // All these are supported if this optional feature is set.
                return typedUAVLoadAdditionalFormats;
    
            case DXGI_FORMAT_R16G16B16A16_UNORM:
            case DXGI_FORMAT_R16G16B16A16_SNORM:
            case DXGI_FORMAT_R32G32_FLOAT:
            case DXGI_FORMAT_R32G32_UINT:
            case DXGI_FORMAT_R32G32_SINT:
            case DXGI_FORMAT_R10G10B10A2_UNORM:
            case DXGI_FORMAT_R10G10B10A2_UINT:
            case DXGI_FORMAT_R11G11B10_FLOAT:
            case DXGI_FORMAT_R8G8B8A8_SNORM:
            case DXGI_FORMAT_R16G16_FLOAT:
            case DXGI_FORMAT_R16G16_UNORM:
            case DXGI_FORMAT_R16G16_UINT:
            case DXGI_FORMAT_R16G16_SNORM:
            case DXGI_FORMAT_R16G16_SINT:
            case DXGI_FORMAT_R8G8_UNORM:
            case DXGI_FORMAT_R8G8_UINT:
            case DXGI_FORMAT_R8G8_SNORM:
            case DXGI_FORMAT_R8G8_SINT:
            case DXGI_FORMAT_R16_UNORM:
            case DXGI_FORMAT_R16_SNORM:
            case DXGI_FORMAT_R8_SNORM:
            case DXGI_FORMAT_A8_UNORM:
            case DXGI_FORMAT_B5G6R5_UNORM:
            case DXGI_FORMAT_B5G5R5A1_UNORM:
            case DXGI_FORMAT_B4G4R4A4_UNORM:
                // Conditionally supported by specific devices.
                if (typedUAVLoadAdditionalFormats)
                {
                    D3D12_FEATURE_DATA_FORMAT_SUPPORT formatSupport = { format, D3D12_FORMAT_SUPPORT1_NONE, D3D12_FORMAT_SUPPORT2_NONE };
                    if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &formatSupport, sizeof(formatSupport))))
                    {
                        const DWORD mask = D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD | D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE;
                        return ((formatSupport.Support2 & mask) == mask);
                    }
                }
                return false;
    
            default:
                return false;
            }
        }
    

    除了 16pp 格式(没有 RGB 版本)之外,该列表中没有 BGRA 格式。

    要支持 BGRA,您可以在与 RGBA UAV 相同的内存位置使用别名纹理,以便重新解释数据。这在设备支持D3D12_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE(即您必须检查D3D12_FEATURE_DATA_D3D12_OPTIONS.StandardSwizzle64KBSupported)时才能正常工作。不幸的是,并非所有设备都支持此功能。

    请参阅 DirectX Tool Kit for DX12 的基于 CS 的 mipmap 生成代码 GenerateMips_TexturePathBGR in ResourceUpload.cpp

    简而言之,如果设备不支持D3D12_FEATURE_DATA_D3D12_OPTIONS.StandardSwizzle64KBSupported,我无法为这些格式生成mipmap:DXGI_FORMAT_B8G8R8A8_UNORMDXGI_FORMAT_B8G8R8X8_UNORMDXGI_FORMAT_B8G8R8A8_UNORM_SRGBDXGI_FORMAT_B8G8R8X8_UNORM_SRGB到期因为无人机不支持 BGRA。

    在 Xbox 上,它是 UMA 架构,我知道 RGBA/BGRA 在内存中的布局方式相同,因此验证不会阻止该平台上的别名。一些较旧的 PC 驱动程序允许您使用 D3D12_TEXTURE_LAYOUT_UNKNOWN 毫无问题地执行此操作,但验证层的现代版本阻止在运行时执行此操作。

    对于一些有限的场景,你可以尝试使用D3D12_TEXTURE_LAYOUT_ROW_MAJOR,但是它非常慢并且有很多limitations,这使得它对于DirectX Tool Kit for DX12没有用处。 p>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-16
      • 2021-06-24
      • 2012-03-30
      • 2015-04-09
      • 2015-10-18
      • 1970-01-01
      • 2012-12-21
      相关资源
      最近更新 更多