Chargements de vue d’accès non ordonné (UAV) typés

Un mode d’accès non ordonné (UAV) Typed Load est la possibilité pour un nuanceur de lire à partir d’un UAV avec un DXGI_FORMAT spécifique.

Vue d’ensemble

Une vue d’accès non triée (UAV) est une vue d’une ressource d’accès non triée (qui peut inclure des mémoires tampons, des textures et des tableaux de textures, mais sans échantillonnage multiple). Un UAV permet un accès en lecture/écriture dans le temps non ordonné à partir de plusieurs threads. Cela signifie que ce type de ressource peut être lu/écrit simultanément par plusieurs threads sans générer de conflits de mémoire. Cet accès simultané est géré via l’utilisation d’Atomic Functions.

D3D12 (et D3D11.3) s’étend sur la liste des formats qui peuvent être utilisés avec des charges d’UAV typées.

Formats et appels d’API pris en charge

Auparavant, les trois formats suivants prenaient en charge les chargements d’UAV typés et étaient requis pour le matériel D3D11.0. Ils sont pris en charge pour tout le matériel D3D11.3 et D3D12.

  • R32_FLOAT
  • R32_UINT
  • R32_SINT

Les formats suivants sont pris en charge en tant qu’ensemble sur le matériel D3D12 ou D3D11.3. Par conséquent, si l’un d’eux est pris en charge, tous sont pris en charge.

  • 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

Les formats suivants étant éventuellement et individuellement pris en charge sur le matériel D3D12 et D3D11.3, une requête unique doit être effectuée sur chaque format pour tester la prise en charge.

  • 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

Pour déterminer la prise en charge de tous les formats supplémentaires, appelez CheckFeatureSupport avec la structure D3D12_FEATURE_DATA_D3D12_OPTIONS comme premier paramètre (reportez-vous à Querying de capacité). Le champ TypedUAVLoadAdditionalFormats est défini si la liste « pris en charge en tant qu’ensemble » ci-dessus est prise en charge. Effectuez un deuxième appel à CheckFeatureSupport à l’aide d’une structure de D3D12_FEATURE_DATA_FORMAT_SUPPORT (en vérifiant la structure retournée par rapport au membre D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD de l’énumération D3D12_FORMAT_SUPPORT2 ) pour déterminer la prise en charge dans la liste des formats éventuellement pris en charge listés ci-dessus, par exemple :

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!
        }
    }
}

Utilisation de charges d’UAV typées à partir de HLSL

Pour les UAV typées, l’indicateur HLSL est D3D_SHADER_REQUIRES_TYPED_UAV_LOAD_ADDITIONAL_FORMATS.

Voici un exemple de code de nuanceur pour traiter une charge d’UAV typée :

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

Utilisation de charges UAV typées UNORM et SNORM à partir de HLSL

Lorsque vous utilisez des charges DAV typées pour lire à partir d’une ressource UNORM ou SNORM, vous devez déclarer correctement le type d’élément de l’objet HLSL comme étant unorm ou snorm. Il est spécifié comme comportement non défini pour ne pas mettre en correspondance le type d’élément déclaré dans HLSL avec le type de données de ressource sous-jacent. Par exemple, si vous utilisez des charges d’UAV typées sur une ressource de mémoire tampon avec R8_UNORM données, vous devez déclarer le type d’élément comme unorm float:

RWBuffer<unorm float> uav;

Rendu

Liaison de ressources

Liaison de ressources dans HLSL

Modèle de nuanceur 5.1

Spécification de signatures racine en langage HLSL