我想使用计算着色器进行后期处理。因此,其想法是将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输出?
答案 0 :(得分:2)
仅支持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
),则此 only 可以正常运行。不幸的是,并非所有设备都支持此功能。
请参见ResourceUpload.cpp中的 DirectX Toolkit for DX12 的基于CS的mipmap生成代码GenerateMips_TexturePathBGR
。
简而言之,,如果设备不支持D3D12_FEATURE_DATA_D3D12_OPTIONS.StandardSwizzle64KBSupported
,则无法生成以下格式的mipmap:DXGI_FORMAT_B8G8R8A8_UNORM
,DXGI_FORMAT_B8G8R8X8_UNORM
,{{ 1}},DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
,因为UAV不支持BGRA。
在Xbox上,它是UMA体系结构,我知道RGBA / BGRA在内存中的布局方式相同,因此验证不会阻止该平台上的别名。某些较旧的PC驱动程序可以让您
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB
正常工作,但是现代版本的验证层会阻止在运行时执行此操作。
在某些有限的情况下,您可以尝试使用
D3D12_TEXTURE_LAYOUT_UNKNOWN
,但是它非常慢并且有很多limitations,这对于用于DX12的DirectX工具包来说没什么用。 >。