类型化无序访问视图 (UAV) 加载

无序访问视图(UAV)类型化负载是着色器从具有特定 DXGI_FORMAT的 UAV 读取的能力。

概述

无序访问视图(UAV)是无序访问资源的视图(可以包括缓冲区、纹理和纹理数组,但不包含多采样)。 UAV 允许从多个线程进行临时无序读/写访问。 这意味着,此资源类型可由多个线程同时读取/写入,而不会生成内存冲突。 此同时访问通过使用 Atomic Functions进行处理。

D3D12(和 D3D11.3)扩展了可用于类型化 UAV 加载的格式列表。

支持的格式和 API 调用

以前,以下三种格式支持类型化 UAV 加载,并且需要 D3D11.0 硬件。 所有 D3D11.3 和 D3D12 硬件都支持它们。

  • R32_FLOAT
  • R32_UINT
  • R32_SINT

以下格式支持为 D3D12 或 D3D11.3 硬件上的集,因此,如果支持任何格式,则支持所有格式。

  • R32G32B32A32_FLOAT
  • R32G32B32A32_UINT
  • R32G32B32A32_SINT
  • R16G16B16A16_FLOAT
  • R16G16B16A16_UINT
  • R16G16B16A16_SINT
  • R8G8B8A8_UNORM
  • R8G8B8A8_UINT
  • R8G8B8A8_SINT
  • R16_FLOAT
  • R16_UINT
  • R16_SINT
  • R8_UNORM
  • R8_UINT
  • R8_SINT

在 D3D12 和 D3D11.3 硬件上可选择性地单独支持以下格式,因此需要对每种格式进行单个查询以测试支持。

  • R16G16B16A16_UNORM
  • R16G16B16A16_SNORM
  • R32G32_FLOAT
  • R32G32_UINT
  • R32G32_SINT
  • R10G10B10A2_UNORM
  • R10G10B10A2_UINT
  • R11G11B10_FLOAT
  • R8G8B8A8_SNORM
  • R16G16_FLOAT
  • R16G16_UNORM
  • R16G16_UINT
  • R16G16_SNORM
  • R16G16_SINT
  • R8G8_UNORM
  • R8G8_UINT
  • R8G8_SNORM
  • R8G8_SINT
  • R16_UNORM
  • R16_SNORM
  • R8_SNORM
  • A8_UNORM
  • B5G6R5_UNORM
  • B5G5R5A1_UNORM
  • B4G4R4A4_UNORM

若要确定对任何其他格式的支持,请使用 D3D12_FEATURE_DATA_D3D12_OPTIONS 结构调用 checkFeatureSupport 作为第一个参数(请参阅 功能查询)。 如果支持上述“支持为集”列表,将设置 TypedUAVLoadAdditionalFormats 字段。 使用 D3D12_FEATURE_DATA_FORMAT_SUPPORT 结构(根据 D3D12_FORMAT_SUPPORT2 枚举D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD成员检查返回的结构)对 CheckFeatureSupport进行第二次调用,以确定在上面列出的可选支持格式列表中的支持,例如:

D3D12_FEATURE_DATA_D3D12_OPTIONS FeatureData;
ZeroMemory(&FeatureData, sizeof(FeatureData));
HRESULT hr = pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &FeatureData, sizeof(FeatureData));
if (SUCCEEDED(hr))
{
    // TypedUAVLoadAdditionalFormats contains a Boolean that tells you whether the feature is supported or not
    if (FeatureData.TypedUAVLoadAdditionalFormats)
    {
        // Can assume “all-or-nothing” subset is supported (e.g. R32G32B32A32_FLOAT)
        // Cannot assume other formats are supported, so we check:
        D3D12_FEATURE_DATA_FORMAT_SUPPORT FormatSupport = {DXGI_FORMAT_R32G32_FLOAT, D3D12_FORMAT_SUPPORT1_NONE, D3D12_FORMAT_SUPPORT2_NONE};
        hr = pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &FormatSupport, sizeof(FormatSupport));
        if (SUCCEEDED(hr) && (FormatSupport.Support2 & D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD) != 0)
        {
            // DXGI_FORMAT_R32G32_FLOAT supports UAV Typed Load!
        }
    }
}

使用来自 HLSL 的类型化 UAV 加载

对于类型化的 UAV,HLSL 标志D3D_SHADER_REQUIRES_TYPED_UAV_LOAD_ADDITIONAL_FORMATS。

下面是处理类型化 UAV 加载的示例着色器代码:

RWTexture2D<float4> uav1;
uint2 coord;
float4 main() : SV_Target
{
  return uav1.Load(coord);
}

使用来自 HLSL 的 UNORM 和 SNORM 类型 UAV 加载

使用类型化 UAV 加载从 UNORM 或 SNORM 资源读取时,必须正确声明要 unormsnorm的 HLSL 对象的元素类型。 它被指定为未定义的行为,用于将 HLSL 中声明的元素类型与基础资源数据类型不匹配。 例如,如果在具有R8_UNORM数据的缓冲区资源上使用类型化 UAV 加载,则必须将元素类型声明为 unorm float

RWBuffer<unorm float> uav;

呈现

资源绑定

HLSL 中的 资源绑定

着色器模型 5.1

在 HLSL 中指定根签名