> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Barrières améliorées D3D12

> Barrières améliorées D3D12

Ce document vise à expliquer l'implémentation des barrières améliorées (Enhanced Barriers) pour XBOX Series X|S et à fournir des exemples détaillés sur la meilleure façon d'en tirer parti. Cette fonctionnalité n'est pas prise en charge sur Durango.

## Table des matières

1. [Introduction](#introduction)
2. [Synchronisation du GPU sur XBOX Series X|S](#gpu-synchronization-on-scarlett)
3. [Les barrières en détail](#barriers-in-depth)
4. [Configuration](#setting-things-up)
5. [Différences avec la spécification PC](#differences-with-the-pc-spec)
6. [Exemples de barrières améliorées](#enhanced-barrier-examples)
7. [Compatibilité avec les barrières de ressources héritées](#compatibility-with-legacy-resource-barriers)
8. [Prise en charge dans PIX et validation](#pix-support-and-validation)

<a id="introduction" />

## Introduction

***

Les *barrières améliorées* (EB, Enhanced Barriers) sont un nouvel ensemble d'API D3D12 conçues pour résoudre certains des problèmes introduits par l'API héritée des barrières de ressources (concepts déroutants comme la promotion et la dégradation de l'état des ressources, problèmes de conception liés aux barrières d'aliasing, opérations de vidage excessives, etc.), tout en donnant aux développeurs un contrôle indépendant sur la synchronisation du travail du GPU. Elles offrent un type de barrière plus expressif que ce qui était possible avec les barrières de ressources héritées.

Les fonctionnalités des barrières améliorées comprennent :

* Réduction de la latence de synchronisation et des vidages de cache excessifs.
* Aucune règle mystérieuse de promotion et de dégradation.
* Aliasing des ressources rapide et flexible.
* Abandon (discard) pendant la transition de barrière.
* Lecture/écriture simultanées et autocopie.

Vous trouverez un lien vers la spécification DirectX des barrières améliorées [ici](https://microsoft.github.io/DirectX-Specs/d3d/D3D12EnhancedBarriers.html).

<a id="gpu-synchronization-on-scarlett" />

## Synchronisation du GPU sur XBOX Series X|S

***

Avant d'aborder les barrières améliorées, une introduction à la synchronisation sur XBOX Series X|S est nécessaire. Il est important de comprendre les concepts et les mécanismes expliqués dans cette section, car ils constituent les éléments de base des barrières.

[Synchronisation du GPU sur XBOX Series X/S](/fr-CA/build/core-features/graphics/overviews/gpu-synchronization-scarlett)

Nous pouvons maintenant plonger dans les barrières améliorées et expliquer plus en détail leur fonctionnement.

<a id="barriers-in-depth" />

## Les barrières en détail

***

Les barrières améliorées introduisent trois concepts utiles pour décider comment effectuer la transition d'une ressource (ou d'une zone mémoire) donnée. Il s'agit de **Sync**, **Access** et **Layout**. D'une certaine façon, ils remplacent le concept précédent d'**état de ressource** (Resource State) utilisé avec les barrières de ressources. Ils ne sont toutefois pas équivalents, car il est toujours possible d'exprimer un état de ressource comme une combinaison de Sync, Access et Layout, mais il n'est pas toujours possible d'exprimer une combinaison de Sync, Access et Layout comme un état de ressource. La nouvelle API est plus expressive.

**Sync (avant-après)** sert à indiquer au pilote l'étape du pipeline dont il faut attendre la fin, et quel moteur doit être bloqué jusqu'à ce que les opérations de barrière soient terminées.

* Le tableau suivant montre comment certains indicateurs de synchronisation se traduisent en exigences de vidage (drain) ou de blocage d'étapes (consultez la section sur le pipelining). À noter : certains indicateurs de synchronisation de barrière désignent une étape générale (comme la copie), mais à l'interne, en fonction des données fournies par l'accès et la disposition, ils sont associés à des étapes précises (source de copie/destination de copie), ce qui génère des exigences de vidage/blocage plus adéquates. De plus, le tableau ci-dessous porte sur le cas des textures (pour les tampons, certaines étapes différeraient).

| **Indicateur de synchronisation de barrière** | **Étape(s) à vider** | **Étape(s) à bloquer** |
| - | - | - |
| D3D12\_BARRIER\_SYNC\_RENDER\_TARGET | Drain CB | BlockME |
| D3D12\_BARRIER\_SYNC\_COMPUTE\_SHADING | Drain CS | BlockME |
| D3D12\_BARRIER\_SYNC\_RAYTRACING | Drain CS | BlockME |
| D3D12\_BARRIER\_SYNC\_COPY (source) | DrainCPDMA, DrainCS, DrainPS | BlockME |
| D3D12\_BARRIER\_SYNC\_COPY (destination) | DrainCPDMA, DrainCS, DrainCB, DrainDB | BlockME |
| D3D12\_BARRIER\_SYNC\_DEPTH\_STENCIL | Drain DB | BlockME |
| D3D12XBOX\_BARRIER\_SYNC\_EXECUTE\_INDIRECT | DrainME | BlockPFP, BlockCE |

* Ces exigences sont ensuite analysées et transmises, avec d'autres primitives, aux fonctions SyncBottomOfPipe/SyncTopOfPipe afin de déterminer les actions de synchronisation finales (par exemple D3D12XBOX\_SYNC\_FLAG\_PS\_PARTIAL\_FLUSH ou D3D12XBOX\_SYNC\_FLAG\_IDLE). Il ne faut pas confondre ces indicateurs avec les indicateurs D3D12\_BARRIER\_SYNC, qui sont utilisés pour les appels de barrières améliorées.
* Ces exigences ne connaissent pas les mécanismes qui seront finalement utilisés pour les satisfaire; elles indiquent donc explicitement quel composant matériel doit être vidé/bloqué. Des composants ultérieurs pourraient constater, par exemple, que plusieurs vidages peuvent être accomplis par un seul événement EoP.

**Access (avant-après)** nous indique avec quels caches cette ressource pourrait interagir avant et après la barrière, ce qui se traduit par des exigences de réécriture (WB) et d'invalidation.

* Dans le contexte des barrières, il est utile de savoir quelles ressources correspondent à quels caches. Par exemple, si nous avons un AccessBefore de D3D12\_ACCESS\_RENDER\_TARGET et un accès après de D3D12\_ACCESS\_SHADER\_RESOURCE, nous voulons savoir quels caches invalider et/ou vider (si nécessaire). Le tableau suivant présente certains types de ressources fréquemment utilisés et la mémoire qu'ils utilisent.
* Les types de ressources ne sont pas le seul facteur déterminant quant aux caches utilisés par la ressource. Le type d'opération (scalaire ou vectorielle) compte également, et c'est le compilateur qui en décide. Une lecture dans un tampon de constantes, par exemple, peut passer par le chemin \$K-L2 s'il s'agit d'une opération scalaire (SMEM), ou par L0-L1-L2 s'il s'agit d'une opération vectorielle (VMEM).

| **Nom de l'accès** | **Caches utilisés** | **Remarques** |
| - | - | - |
| Rendertarget | Caches CB - L1, L2 | |
| Depth/Stencil | Caches DB - L1, L2 | |
| ShaderResource | L0-L1, \$K, L2, LM | |
| UnorderedAccess | L0-L1, \$K, L2, LM | |
| ConstantBuffer | L0-L1, \$K, L2 | Les tampons de constantes sont généralement lus au moyen d'instructions SMEM, mais s'ils sont accédés au moyen d'indices non uniformes, le compilateur génère des instructions VMEM. |
| VertexBuffer | L0-L1, L2 | Les tampons de sommets sont lus au moyen d'instructions VMEM (par L0-L1-L2). |
| IndexBuffer | L2 | Les tampons d'index sont récupérés de la DRAM vers L2 par le CPDMA déclenché par le PFP. |
| CopyDest | L0-L1, \$K, L2, LM, caches CB, caches DB | |
| CopySource | L0-L1, \$K, L2, LM | |
| Structure d'accélération du lancer de rayons (lecture/écriture) | L0-L1, \$K, L2 | |

**Layout (avant-après)** décrit la disposition en mémoire de la ressource. Cela détermine si les ressources devront être décompressées/compressées lors de l'opération de barrière, ainsi que si une initialisation des métadonnées est nécessaire (pour les cibles de rendu et les tampons de profondeur/gabarit). Par exemple, une cible de rendu avec DCC activée pourrait devoir effectuer un DCC-Eliminate lors de sa transition vers SRV, et donc subir une décompression.

* Certains indicateurs de ressource et de barrière modifient les exigences de compression/décompression qui en résultent :
  * Le pilote conserve deux tables qui associent le type de ressource aux opérations de compression/décompression. L'une de ces tables concerne les ressources créées avec D3D12XBOX\_RESOURCE\_FLAG\_FORCE\_TEXTURE\_COMPATIBILITY, tandis que l'autre concerne les ressources non TC.
  * Les EB introduisent D3D12\_TEXTURE\_BARRIER\_FLAG\_DISCARD qui, lorsqu'il est passé en argument à la méthode Barrier, force l'initialisation des métadonnées. Avant les EB, cela pouvait se faire au moyen d'une opération d'effacement effectuée avant la première utilisation de la ressource.
  * Les cibles de rendu et les tampons de profondeur/gabarit doivent être créés respectivement avec D3D12\_RESOURCE\_FLAGS\_ALLOW\_RENDER\_TARGET et D3D12\_RESOURCE\_FLAGS\_ALLOW\_DEPTH\_STENCIL pour que les surfaces de métadonnées soient allouées correctement.
  * Si vous voulez utiliser la DCC, la ressource doit être créée avec l'indicateur D3D12XBOX\_RESOURCE\_FLAG\_ALLOW\_DCC. La DCC impliquera des opérations de décompression lors de la transition d'un état d'écriture à un état de lecture, mais pas si la ressource est aussi créée avec D3D12XBOX\_RESOURCE\_FLAG\_FORCE\_TEXTURE\_COMPATIBILITY.
* Le tableau suivant, qui associe les indicateurs de disposition aux indicateurs d'état de compression, aide à mieux comprendre comment les transitions d'entrée et de sortie peuvent entraîner des compressions/décompressions. Par exemple, passer de cible de rendu (rt) à ressource de nuanceur (sr) sur des ressources non TC nécessite une décompression, puisque rt possède plusieurs indicateurs de compression alors que sr est marqué *uncompressedAll*. Mais la même transition pour une ressource TC ne déclencherait pas de décompression, étant donné que sr possède un surensemble des indicateurs d'état de compression de rt.

| **Indicateur de disposition** | **Non TC** | **TC** |
| - | - | - |
| D3D12\_BARRIER\_LAYOUT\_COMMON | uncompressedAll | uncompressedAll |
| D3D12\_BARRIER\_LAYOUT\_GENERIC\_READ | uncompressedAll | uncompressedAll |
| D3D12\_BARRIER\_LAYOUT\_RENDER\_TARGET | CompressedColor CompressedDcc ScatteredFmask IndirectColorClear | CompressedColor CompressedDcc ScatteredFmask IndirectColorClear |
| D3D12\_BARRIER\_LAYOUT\_UNORDERED\_ACCESS | uncompressedAll | CompressedColor CompressedDepth CompressedStencil CompressedDcc ScatteredFmask |
| D3D12\_BARRIER\_LAYOUT\_SHADER\_RESOURCE | uncompressedAll | CompressedColor CompressedDcc ScatteredFmask CompressedDepth CompressedStencil |
| D3D12\_BARRIER\_LAYOUT\_COPY\_SOURCE | CompressedColor CompressedDcc | CompressedColor CompressedDcc ScatteredFmask IndirectColorClear CompressedDepth CompressedStencil |
| D3D12\_BARRIER\_LAYOUT\_COPY\_DEST | CompressedColor CompressedDcc | CompressedColor CompressedDepth CompressedStencil CompressedDcc ScatteredFmask IndirectColorClear |

Définir un avant et un après pour **layout**, **access** et **sync** nous donne une grande flexibilité pour faire des choses impossibles avec ResourceBarriers (sauf les barrières fractionnées, nous y reviendrons), tout en améliorant les cas où les barrières de ressources pouvaient entraîner des vidages partiels inutiles (barrières UAV) et, dans le pire des cas, mener à une corruption de la mémoire (barrières d'aliasing, lors d'une tentative de décompression sans être certain de la disposition actuelle de la mémoire). Cela correspond aussi mieux à la façon dont la synchronisation fonctionne sur le GPU, ce qui donne au développeur un contrôle plus précis.

### La spécification définit également trois types de barrières :

* Barrières globales :
  * S'appliquent à toute la mémoire. Leur définition ne prend pas de pointeur de ressource.
  * Aucune information de disposition n'est passée en argument.
* Barrières de tampon
  * Comme leur nom l'indique, les barrières de tampon servent à effectuer la transition des ressources de type tampon.
  * Aucune disposition ni sous-ressource n'est spécifiée en paramètre (puisque les tampons n'utilisent ni l'une ni l'autre).
* Barrières de texture
  * Transition pour les ressources de texture (cibles de rendu, tampons de profondeur/gabarit, textures SRV, textures UAV, etc.).
  * La disposition est obligatoire; cette barrière peut donc déclencher des décompressions et des compressions.
  * Peut spécifier une sous-ressource précise ou une plage.
    * Pour les sous-ressources, il existe des limites en matière de décompression, puisqu'il est impossible de décompresser seulement une partie d'une ressource.

Voici la définition de l'API D3D12 pour les trois types de barrières :

```cpp theme={null}
struct D3D12_BUFFER_BARRIER 
{ 
    D3D12_BARRIER_SYNC SyncBefore; 
    D3D12_BARRIER_SYNC SyncAfter; 
    D3D12_BARRIER_ACCESS AccessBefore; 
    D3D12_BARRIER_ACCESS AccessAfter; 
    ID3D12Resource *pResource;     
    UINT64 Offset;  // Must be 0 
    UINT64 Size;    // UINT64_MAX or size in bytes 
};  
```

```cpp theme={null}
struct D3D12 _GLOBAL_BARRIER 
{ 
    D3D12_BARRIER_SYNC SyncBefore; 
    D3D12_BARRIER_SYNC SyncAfter; 
    D3D12_BARRIER_ACCESS AccessBefore; 
    D3D12_BARRIER_ACCESS AccessAfter; 
}  
```

```cpp theme={null}
struct D3D12_TEXTURE_BARRIER 
{ 
    D3D12_BARRIER_SYNC SyncBefore; 
    D3D12_BARRIER_SYNC SyncAfter; 
    D3D12_BARRIER_ACCESS AccessBefore; 
    D3D12_BARRIER_ACCESS AccessAfter; 
    D3D12_BARRIER_LAYOUT LayoutBefore; 
    D3D12_BARRIER_LAYOUT LayoutAfter; 
    ID3D12Resource *pResource; 
    D3D12_BARRIER_SUBRESOURCE_RANGE Subresources; 
    D3D12_TEXTURE_BARRIER_FLAGS Flags; 
};
```

* **LayoutBefore, LayourAfter** : disposition de la mémoire avant et après la barrière. Détermine ce que nous allons compresser/décompresser. Utilisé uniquement par D3D12\_TEXTURE\_BARRIER.
* **SyncBefore, SyncAfter** : étape dont il faut attendre le vidage et étape à bloquer avant de poursuivre.
* **AccessBefore, AccessAfter** : indique quels caches nous cesserons d'utiliser et quels caches nous commencerons à utiliser à la suite de la transition.
* **Subresource range** -- Permet de définir une plage de sous-ressources dont la barrière effectuera la transition. Utilisé uniquement par D3D12\_TEXTURE\_BARRIER.
* **Resource** -- Le propriétaire de la mémoire dont nous effectuons la transition. Utilisé par D3D12\_TEXTURE\_BARRIER et D3D12\_BUFFER\_BARRIER.
* **Texture Barrier flags** -- Les valeurs peuvent être D3D12\_TEXTURE\_BARRIER\_FLAG\_NONE et D3D12\_TEXTURE\_BARRIER\_FLAG\_DISCARD. Utilisé uniquement par D3D12\_TEXTURE\_BARRIER.
  * Nous utilisons l'indicateur discard lors de l'activation d'une ressource, afin que ses métadonnées soient initialisées correctement.
  * L'utilisation de cet indicateur permet aussi de regrouper l'initialisation des ressources. Les effacements peuvent se chevaucher, et les opérations de synchronisation des barrières sont regroupées.

<a id="setting-things-up" />

## Configuration

***

Pour utiliser les barrières améliorées, vous avez besoin des éléments suivants :

* GDK de mars 2023 ou plus récent.
* ID3D12GraphicsCommandList7 : nécessaire pour appeler la méthode [Barrier](https://learn.microsoft.com/windows/win32/api/d3d12/nf-d3d12-id3d12graphicscommandlist7-barrier). Prend une structure D3D12\_BARRIER\_GROUP et le numéro de groupe.

(**Facultatif**) ID3D12Device10 donne accès aux nouvelles définitions de création de ressources : **CreatePlacedResource2**, **CreateCommitedResource3** et **CreateReservedResource2**. Celles-ci prennent un D3D12\_BARRIER\_LAYOUT en paramètre au lieu du D3D12\_RESOURCE\_STATE.

* Selon la spécification, l'interopérabilité entre les API de barrières améliorées et les D3D12\_RESOURCE\_STATES hérités est prise en charge. Cependant, les sous-ressources dans tout état hérité autre que D3D12\_RESOURCE\_STATE\_COMMON doivent faire l'objet d'une transition vers D3D12\_RESOURCE\_STATE\_COMMON avant d'être référencées au moyen d'une barrière améliorée.

(**Facultatif**) ID3D12Device11 donne accès à de nouvelles API d'extension pour la création de ressources : **CreatePlacedResourceX1** et **CreateComponentPlacedResourceX2**. Celles-ci prennent un D3D12\_BARRIER\_LAYOUT en paramètre au lieu du D3D12\_RESOURCE\_STATE.

**Tests avec les barrières de ressources héritées**

Nous disposons d'un mécanisme permettant de désactiver les EB et de revenir à l'implémentation précédente des barrières de ressources. Si, à un moment donné, les développeurs rencontrent un blocage ou constatent que les barrières se comportent de façon inattendue (par exemple en prenant plus de temps que d'habitude pour une transition donnée, ou en générant de mauvais indicateurs de synchronisation/décompression), il pourrait valoir la peine de revenir en arrière et de vérifier si le problème persiste. Les étapes nécessaires sont les suivantes :

* Créez un fichier vide dans le dossier Loose (répertoire de déploiement) et nommez-le **D3D\_\_DisableLegacyResourceBarrierTranslation**.
* Déployez le jeu et assurez-vous que le fichier a bien été déployé sur la console.
  * **Remarque** : dans ce mode, le pilote ne prend pas en charge le mélange de barrières héritées et de barrières améliorées.

Nous encourageons **fortement** les développeurs à communiquer avec nous au moyen des [forums des développeurs XBOX](https://forums.xboxlive.com/) s'ils rencontrent de tels problèmes avec les barrières améliorées.

<a id="differences-with-the-pc-spec" />

## Différences avec la spécification PC

***

1. **Sur XBOX, le vidage à la frontière d'ExecuteCommandList** n'est pas émis; l'accès sans barrière n'est donc pas pris en charge.
   * Cela s'explique par des raisons de performance, puisqu'un vidage complet du GPU est coûteux.
   * [Accès sans barrière dans la spécification](https://microsoft.github.io/DirectX-Specs/d3d/D3D12EnhancedBarriers.html#barrier-free-access)
2. **Sous-ressources**. Sur PC, les métadonnées sont suivies par sous-ressource, alors que ce n'est pas notre cas. Cela signifie que l'état de compression par sous-ressource ne peut pas être suivi. Par conséquent, les changements de disposition qui impliquent une compression ou une décompression donneront des résultats différents selon que la plage de ressources couvre (ou non) la ressource entière.
   * Si une ressource dans une disposition compressée voit une ou plusieurs (mais pas toutes) de ses sous-ressources passer à une disposition non compressée, la ressource entière sera décompressée.
   * Si une ressource dans une disposition non compressée voit une ou plusieurs (mais pas toutes) de ses sous-ressources passer à une disposition compressée, la ressource entière demeure non compressée.
   * Nous prenons en charge des états de compression indépendants pour la profondeur et le gabarit, ce qui signifie que nous pouvons avoir une profondeur compressée et un gabarit non compressé, ou l'inverse.
3. Les **barrières fractionnées** fonctionnent, mais elles ne sont pas implémentées comme des barrières fractionnées dans le pilote. Elles sont plutôt converties en barrières immédiates. Nous effectuons cette conversion parce que les barrières fractionnées, telles que définies par D3D12, imposent un coût mémoire par ressource et sont inutilement inefficaces sur notre matériel. Cependant, la conversion en barrières immédiates n'est pas aussi efficace qu'elle pourrait l'être.
   * Cela est dû au fait que le pilote ne reçoit pas d'information complète sur la synchronisation avant et après. La conversion en barrière immédiate se fait du côté proche de la barrière (le côté éloigné est ignoré), de sorte que le pilote doit être pessimiste et bloquer à la fois le CE et le PFP, ce qui peut rendre les barrières fractionnées plus lentes que les barrières nativement immédiates.
   * Par ailleurs, historiquement, très peu de gens utilisent les barrières fractionnées avec l'API héritée.
   * Une façon de résoudre le coût mémoire par ressource à l'avenir pourrait être de permettre aux développeurs de fournir eux-mêmes cette mémoire.
   * Il est prévu de revoir l'implémentation des barrières fractionnées à l'avenir.

Bien qu'il ne s'agisse pas d'une différence, il convient de mentionner que **les copies demeurent sérialisées** (la spécification mentionne qu'avec les barrières améliorées, les copies sérialisées pourraient ne plus être nécessaires). **Remarque** : passer D3D12XBOX\_CMDLIST\_DRIVER\_HINT\_DONT\_SYNC\_ON\_COPY comme indication de liste de commandes permet des effacements et des copies non sérialisés.

* Nous recommandons aux utilisateurs d'implémenter leurs propres copies de textures dans des nuanceurs de calcul. Ils devront bien sûr gérer les dépendances, mais cela permettrait un travail non sérialisé et plus efficace.
  * L'une des raisons pour lesquelles les copies de textures gérées par le pilote peuvent être moins performantes est qu'elles peuvent utiliser les caches CB/DB. Cela entraîne la nécessité d'effectuer une réécriture (WB) supplémentaire et d'invalider les caches CB et DB lors des transitions vers les copies de textures ou à partir de celles-ci.

<a id="enhanced-barrier-examples" />

## Exemples de barrières améliorées

***

Bien que des améliorations automatiques des performances à l'exécution puissent être obtenues grâce à la capacité du pilote à traduire les appels de barrières de ressources héritées en équivalents de barrières améliorées, des gains supplémentaires peuvent être réalisés en utilisant directement les barrières améliorées. L'expressivité de l'API offre des occasions de réduire les latences de synchronisation et d'éliminer les vidages inutiles. Les exemples de code suivants montrent comment exprimer des appels de barrières de ressources héritées avec l'API des barrières améliorées afin de profiter de ces avantages supplémentaires.

* [Barrières de ressources de transition](#transition-resource-barriers)
* [Barrières de ressources d'accès non ordonné](#unordered-access-resource-barriers)
* [Autocopie](#self-copy)
* [Barrières de ressources d'aliasing](#aliasing-resource-barriers)

<a id="transition-resource-barriers" />

### **Barrières de ressources de transition**

Dans les applications graphiques, les ressources mémoire sont souvent accédées dans différents contextes, que ce soit en tant que cibles de rendu, vues de ressources de nuanceur, vues de tampons de sommets ou dans d'autres types d'états. Cela explique le besoin fréquent de barrières de ressources de transition pour assurer une synchronisation et une cohérence de cache correctes. Toutefois, dans certains cas, les barrières de ressources de transition peuvent introduire des ralentissements inutiles, comme un vidage excessif du pipeline.

Prenons l'extrait de code de barrière de ressource héritée suivant, qui montre la transition de l'état d'une ressource d'une vue de ressource de nuanceur (SRV) à une vue de cible de rendu (RTV) :

```cpp theme={null}
auto barrier = CD3DX12_RESOURCE_BARRIER::Transition(renderTarget,
    D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
    D3D12_RESOURCE_STATE_RENDER_TARGET);
commandList->ResourceBarrier(1, &barrier);
```

Cet exemple dessine d'abord dans une RTV, effectue la transition de la ressource vers une SRV pour une utilisation par un nuanceur de calcul, puis la ramène vers une RTV pour que l'image suivante reproduise le même modèle d'utilisation. Comme il n'existait aucun moyen explicite de décrire comment la ressource a été accédée en dernier et quel type de travail du GPU doit être synchronisé, le pilote doit vider toutes les étapes du pipeline où la ressource aurait pu avoir l'état D3D12\_RESOURCE\_STATE\_NON\_PIXEL\_SHADER\_RESOURCE.

Comme on le voit dans la capture PIX ci-dessous, cette transition amène le pilote, comme prévu, à invoquer un vidage partiel du nuanceur de calcul pour tenir compte de la dernière répartition (dispatch), mais déclenche inutilement un vidage partiel du nuanceur de sommets. Cette ressource a été utilisée dans un appel de dessin et une répartition antérieurs, et le pilote ne sait pas dans quel état la ressource a été utilisée dans chaque cas. Il ne sait pas non plus si les dessins et les répartitions sont terminés au moment où la barrière est émise. Ainsi, en donnant la priorité à une synchronisation correcte, il doit supposer que toutes les étapes actives du pipeline autres que le nuanceur de pixels (sommets et calcul) qui utilisent la ressource pourraient être touchées par le changement de type d'accès à la ressource.

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_01.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=feb23c0da6682c3b650d4c6ef9302033" alt="Interface utilisateur graphique, application Description générée automatiquement" width="1100" height="690" data-path="images/gdk/features/graphics/EnhancedBarriers_01.png" />

Le vidage partiel du nuanceur de sommets coûte 0 µs puisqu'aucun autre dessin n'est en cours d'exécution, comme on le voit dans la capture PIX ci-dessus. Toutefois, la barrière de ressource pourrait prendre plus de temps à se terminer s'il y avait du travail antérieur de nuanceur de sommets provenant d'événements D3D précédents non liés.

On peut éviter cela en précisant en plus les états de synchronisation et de disposition de la ressource au moyen de l'API des barrières améliorées, comme l'indiquent les arguments mis en évidence ci-dessous. L'utilisateur peut garantir qu'aucun travail de nuanceur de sommets ne sera actif au moment de l'appel de barrière, et limiter explicitement les vidages partiels à l'étape de calcul, tout en bloquant uniquement le travail qui demande à opérer sur une RTV.

```cpp theme={null}
auto barrierSubresourceRange = CD3DX12_BARRIER_SUBRESOURCE_RANGE();

auto textureBarrier = CD3DX12_TEXTURE_BARRIER (
    D3D12_BARRIER_SYNC_COMPUTE_SHADING,
    D3D12_BARRIER_SYNC_RENDER_TARGET,
    D3D12_BARRIER_ACCESS_SHADER_RESOURCE,
    D3D12_BARRIER_ACCESS_RENDER_TARGET,
    D3D12_BARRIER_LAYOUT_SHADER_RESOURCE,
    D3D12_BARRIER_LAYOUT_RENDER_TARGET,
    renderTarget,
    barrierSubresourceRange
);

auto barrierGroup = CD3DX12_BARRIER_GROUP(1, &textureBarrier);
```

Comme illustré ci-dessous, la barrière améliorée n'utilise plus de vidage partiel du nuanceur de sommets. La vue Command Disassembly et la vue Event Details de PIX peuvent aussi être utilisées pour examiner plus en détail, respectivement, les paquets de commandes et les paramètres de la barrière :

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_02.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=3ca408d5ea63002ae2ccff6ecb8bbfa7" alt="Interface utilisateur graphique, texte, application, courriel Description générée automatiquement" width="750" height="391" data-path="images/gdk/features/graphics/EnhancedBarriers_02.png" />

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_03.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=3bf3a236e5f689fcaa10dc0626b80524" alt="Interface utilisateur graphique, application, tableau Description générée automatiquement" width="750" height="556" data-path="images/gdk/features/graphics/EnhancedBarriers_03.png" />

Si la ressource était un tampon plutôt qu'une texture 2D comme dans le cas précédent, et que le tampon devait être utilisé comme sortie de flux (stream output) plutôt que comme RTV, une barrière de tampon pourrait être utilisée de façon similaire :

```cpp theme={null}
auto bufferBarrier = CD3DX12_BUFFER_BARRIER (
    D3D12_BARRIER_SYNC_COMPUTE_SHADING,
    D3D12_BARRIER_SYNC_STREAM_OUTPUT,
    D3D12_BARRIER_ACCESS_SHADER_RESOURCE,
    D3D12_BARRIER_ACCESS_STREAM_OUTPUT,
    m_renderTarget.Get(),
    barrierSubresourceRange
);
```

<a id="unordered-access-resource-barriers" />

### **Barrières de ressources d'accès non ordonné**

Les barrières de ressources héritées créées pour synchroniser les lectures et les écritures dans une vue d'accès non ordonné (UAV) sont également sujettes à des vidages superflus du pipeline du GPU, pour des raisons liées au pilote semblables à celles des barrières de ressources de transition héritées. Prenons un scénario où des textures avec mipmaps sont générées par un nuanceur de calcul, toutes écrites et lues dans une UAV de texture, et où le code de barrière de ressource d'accès non ordonné suivant est utilisé pour éviter les risques :

```cpp theme={null}
auto barrier = CD3DX12_RESOURCE_BARRIER::UAV(texture0);
commandList->ResourceBarrier(1, &barrier);
```

Si l'on examine les événements matériels générés dans PIX, des vidages partiels sont exécutés pour les étapes du nuanceur de pixels, du nuanceur de sommets et du nuanceur de calcul. Seuls des éléments de travail de calcul sont répartis jusqu'à l'exécution de la barrière; des vidages partiels du nuanceur de calcul suffisent donc.

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_04.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=38b89f5d74fede1bba85870254f2ad07" alt="Interface utilisateur graphique, application, tableau Description générée automatiquement" width="1100" height="969" data-path="images/gdk/features/graphics/EnhancedBarriers_04.png" />

La solution ici, comme dans l'exemple de barrière de ressource de transition, consiste à utiliser une barrière de texture dont les états de synchronisation vident et bloquent exclusivement le travail du nuanceur de calcul. La modification de code suivante fait disparaître de la capture PIX les vidages partiels des nuanceurs de sommets et de pixels.

```cpp theme={null}
auto barrierSubresourceRange = CD3DX12_BARRIER_SUBRESOURCE_RANGE();

auto barrier = CD3DX12_TEXTURE_BARRIER (
    D3D12_BARRIER_SYNC_CLEAR_UNORDERED_ACCESS_VIEW,
    D3D12_BARRIER_SYNC_COMPUTE_SHADING,
    D3D12_BARRIER_ACCESS_UNORDERED_ACCESS
    D3D12_BARRIER_ACCESS_SHADER_RESOURCE,
    D3D12_BARRIER_LAYOUT_UNORDERED_ACCESS,
    D3D12_BARRIER_LAYOUT_SHADER_RESOURCE,
    texture0,
    barrierSubresourceRange
);

auto barrierGroup = CD3DX12_BARRIER_GROUP(1, &barrier);
```

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_05.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=ceb9f67d854cd57cc87cebceb8913d3e" alt="Interface utilisateur graphique, application, tableau Description générée automatiquement" width="750" height="445" data-path="images/gdk/features/graphics/EnhancedBarriers_05.png" />

<a id="self-copy" />

### **Autocopie**

Auparavant, il était impossible d'écrire et de lire simultanément une sous-ressource, puisque la conception des barrières de ressources héritées interdit de combiner des bits de lecture seule et d'écriture. Cela signifiait que déplacer des données dans une ressource entre deux régions qui ne se chevauchent pas nécessitait la création d'une texture temporaire, davantage de barrières de transition pour passer de D3D12\_RESOURCE\_STATE\_COPY\_SOURCE à D3D12\_RESOURCE\_STATE\_COPY\_DEST, et davantage d'opérations de copie de sous-ressources. L'exemple de code ci-dessous illustre le travail nécessaire pour copier le quart supérieur gauche d'une texture dans son quart inférieur droit.

```cpp theme={null}
// Legacy resource barriers
{
    auto barrier = CD3DX12_RESOURCE_BARRIER::Transition(texture,
        D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
        D3D12_RESOURCE_STATE_COPY_SOURCE
    );
    commandList->ResourceBarrier(1, &barrier);

    barrier = CD3DX12_RESOURCE_BARRIER::Transition(textureTmp,
        D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
        D3D12_RESOURCE_STATE_COPY_DEST
    );
    commandList->ResourceBarrier(1, &barrier);
}

// Copy top left quarter to temp texture
{
    auto locationSrc = CD3DX12_TEXTURE_COPY_LOCATION(texture, 0);
    auto locationDst = CD3DX12_TEXTURE_COPY_LOCATION(textureTmp, 0);
    commandList->CopyTextureRegion(&locationDst, boxTopLeft.left,
        boxTopLeft.top, boxTopLeft.front, &locationSrc, &boxTopLeft);

    auto barrier = CD3DX12_RESOURCE_BARRIER::Transition(texture,
        D3D12_RESOURCE_STATE_COPY_SOURCE,
        D3D12_RESOURCE_STATE_COPY_DEST
    );
    commandList->ResourceBarrier(1, &barrier);

    barrier = CD3DX12_RESOURCE_BARRIER::Transition(textureTmp,
        D3D12_RESOURCE_STATE_COPY_DEST,
        D3D12_RESOURCE_STATE_COPY_SOURCE
    );
    commandList->ResourceBarrier(1, &barrier);
}

// Copy temp texture to bottom right quarter
{
    auto locationSrc = CD3DX12_TEXTURE_COPY_LOCATION(textureTmp, 0);
    auto locationDst = CD3DX12_TEXTURE_COPY_LOCATION(texture, 0);
    commandList->CopyTextureRegion(&locationDst, boxBottomRight.left,
        boxBottomRight.top, boxBottomRight.front, &locationSrc, &boxTopLeft);

    auto barrier = CD3DX12_RESOURCE_BARRIER::Transition(texture,
        D3D12_RESOURCE_STATE_COPY_DEST,
        D3D12_RESOURCE_STATE_UNORDERED_ACCESS
    );
    commandList->ResourceBarrier(1, &barrier);

    barrier = CD3DX12_RESOURCE_BARRIER::Transition(m_textureTmp.Get(),
        D3D12_RESOURCE_STATE_COPY_SOURCE,
        D3D12_RESOURCE_STATE_UNORDERED_ACCESS
    );
    commandList->ResourceBarrier(1, &barrier);
}
```

L'API des barrières améliorées permet désormais l'autocopie, ce qui rend le code nécessaire beaucoup plus facile à lire et à écrire tout en éliminant le besoin d'une texture intermédiaire :

```cpp theme={null}
// Self copy top left quarter to bottom right quarter
auto locationSrc = CD3DX12_TEXTURE_COPY_LOCATION(texture, 0);
auto locationDst = CD3DX12_TEXTURE_COPY_LOCATION(texture, 0);

commandList->CopyTextureRegion(&locationDst, boxBottomRight.left,
    boxBottomRight.top, boxBottomRight.front, &locationSrc, &boxTopLeft);
```

La vue Events de PIX peut être utilisée pour visualiser la différence d'événements matériels entre l'implémentation de l'autocopie de texture avec les barrières de ressources héritées et avec les barrières améliorées. Prenons la paire de captures d'écran suivante, tirées de captures PIX, où la première ne contient que des barrières de ressources héritées et la seconde, des barrières améliorées :

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_06.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=40e35c9cfcfc4fa549e5b79574a96fad" alt="Tableau Description générée automatiquement" width="926" height="1100" data-path="images/gdk/features/graphics/EnhancedBarriers_06.png" />

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_07.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=8145f6ff6b0ffaabb5a5032722f1693d" alt="Interface utilisateur graphique, texte, application, courriel Description générée automatiquement" width="750" height="248" data-path="images/gdk/features/graphics/EnhancedBarriers_07.png" />

<a id="aliasing-resource-barriers" />

### **Barrières de ressources d'aliasing**

Comme on le voit dans le code ci-dessous, tiré de la [documentation MSDN publique de D3D12](https://learn.microsoft.com/windows/win32/api/d3d12/ns-d3d12-d3d12_resource_aliasing_barrier), l'aliasing de ressources placées avec l'API des barrières de ressources héritées consistait historiquement à spécifier uniquement les deux ressources qui partageaient la mémoire du tas. L'API des barrières améliorées peut aider à éviter d'avoir à bloquer tout le travail du GPU et à vider toutes les écritures, tout en fournissant des états de disposition explicites pour que le pilote ne décompresse pas de la mémoire non compressée (consultez [ce lien](https://microsoft.github.io/DirectX-Specs/d3d/D3D12EnhancedBarriers.html#aliasing-barriers-are-very-expensive) pour en savoir plus sur ce dernier problème, sous « Aliasing Barriers Are Very Expensive »).

```cpp theme={null}
typedef struct D3D12_RESOURCE_ALIASING_BARRIER 
{
    ID3D12Resource *pResourceBefore;
    ID3D12Resource *pResourceAfter;
} D3D12_RESOURCE_ALIASING_BARRIER;
```

Cet extrait de code montre comment les barrières de texture peuvent être utilisées pour faciliter l'aliasing entre deux ressources placées : pTex0 contient des données précédemment copiées depuis un tas de téléversement, et pTex1 réutilise ces données pour les recopier dans un autre tampon.

```cpp theme={null}
// Transition pTex0 to COPY_SOURCE
auto tex0Barrier = CD3DX12_TEXTURE_BARRIER (
    D3D12_BARRIER_SYNC_RENDER_TARGET,
    D3D12_BARRIER_SYNC_COPY,
    D3D12_BARRIER_ACCESS_RENDER_TARGET,
    D3D12_BARRIER_ACCESS_COPY_SOURCE,
    D3D12_BARRIER_LAYOUT_RENDER_TARGET,
    D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_SOURCE,
    pTex0,
    CD3DX12_BARRIER_SUBRESOURCE_RANGE(0, 1, 0, 1)
);

// Barrier to affect an aliasing transition from pTex0 to
// pTex1 with a layout of COPY_SOURCE
auto tex1Barrier = CD3DX12_TEXTURE_BARRIER (
    D3D12_BARRIER_SYNC_RENDER_TARGET,
    D3D12_BARRIER_SYNC_COPY,
    D3D12_BARRIER_ACCESS_NO_ACCESS,
    D3D12_BARRIER_ACCESS_COPY_SOURCE,
    D3D12_BARRIER_LAYOUT_UNDEFINED,
    D3D12_BARRIER_LAYOUT_COPY_SOURCE,
    pTex1,
    CD3DX12_BARRIER_SUBRESOURCE_RANGE(0, 1, 0, 1)
);
```

<a id="compatibility-with-legacy-resource-barriers" />

## Compatibilité avec les barrières de ressources héritées

***

L'API de barrières précédente (Resource Barriers) est toujours prise en charge, mais le pilote les **traduit** en barrières améliorées en arrière-plan. Plusieurs tests ont été effectués sur des captures PIX pour mesurer l'incidence de la traduction (par rapport à l'utilisation de l'implémentation précédente). Les résultats montrent que la traduction en EB offre des gains importants.

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_08.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=7117c2331d6b4da6e8de894026bbc3f2" alt="Graphique, graphique en courbes Description générée automatiquement" width="1223" height="689" data-path="images/gdk/features/graphics/EnhancedBarriers_08.png" />

Le graphique ci-dessus montre les gains sur des captures d'une seule image (en % d'amélioration du temps d'image) pour un total de 115 captures. Il convient de noter que la sélection comprend à la fois des titres de jeux et des exemples, les exemples affichant les gains les plus élevés. Voici une liste de titres AAA et l'amélioration du temps d'image (%) obtenue à partir de leurs captures PIX.

| Titre | Amélioration du temps d'image (%) |
| - | - |
| Titre A | 5,7 % |
| Titre B | 3,7 % |
| Titre C | 3,2 % |
| Titre D | 2,5 % |
| Titre E | 2,4 % |
| Titre F | 2,3 % |
| Titre G | 1,6 % |

À noter : les gains dépendront grandement de la façon dont le moteur graphique est construit en matière de synchronisation et de placement des barrières.

Exemples où la traduction a apporté des améliorations par rapport aux barrières de ressources héritées :

### **Exemple 1 - Génération de vidages partiels par les barrières UAV**

Barrière de ressource héritée

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_09.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=f6c371681e9f7d80af7d70d03a23773a" alt="Interface utilisateur graphique" width="455" height="150" data-path="images/gdk/features/graphics/EnhancedBarriers_09.png" />

Barrière de ressource traduite

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_10.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=acf5eca179145aca94b75c08225e6423" alt="Interface utilisateur graphique" width="426" height="179" data-path="images/gdk/features/graphics/EnhancedBarriers_10.png" />

La barrière traduite présente les bonnes étapes de synchronisation. Elle effectue des vidages partiels PS, VS et CS avant l'invalidation, puisqu'elle doit se préparer au pire scénario (tenir compte de toutes les étapes qui pourraient écrire dans l'UAV). En revanche, la barrière héritée déclenche un vidage partiel PS et un vidage partiel CS avant l'invalidation. Ce n'est pas correct, puisqu'elle suppose que les étapes VS seront nécessairement suivies d'une étape PS, ce qui n'est pas toujours le cas. **Dans cet exemple, les barrières traduites corrigent un problème présent dans les barrières de ressources UAV**.

### **Exemple 2 - Aliasing**

Barrière de ressource héritée

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_11.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=fa96c405ce385338f87f5851ae3e1be6" alt="Interface utilisateur graphique" width="1342" height="371" data-path="images/gdk/features/graphics/EnhancedBarriers_11.png" />

Barrière de ressource traduite

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_12.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=e50298acca609ad108f9a55d080ead6c" alt="Interface utilisateur graphique" width="1029" height="122" data-path="images/gdk/features/graphics/EnhancedBarriers_12.png" />

Dans cet exemple, ResourceBarrier::Aliasing générait des vidages de sortie de flux (streamout) qui n'étaient pas nécessaires. La barrière traduite effectue une attente de clôture (fence) pour certains vidages et invalidations BoP, suivie d'une synchronisation ToP (ce qui est identique à ce que faisait la barrière héritée, sans les paquets liés à la sortie de flux). **Dans cet exemple, les barrières traduites obtiennent un gain de performance grâce à la traduction**.

> Tout ceci montre les gains que les développeurs peuvent obtenir uniquement grâce aux barrières améliorées, sans modifier leur code. Pour voir les gains possibles lors du passage à la nouvelle API Barrier, consultez la section [**Exemples de barrières améliorées**](#enhanced-barrier-examples).

<a id="pix-support-and-validation" />

## Prise en charge dans PIX et validation

***

**PIX** prend en charge à la fois les barrières améliorées et les barrières de ressources héritées traduites.

**Pour les barrières améliorées**, un événement PIX nommé **Barrier** est créé; il contient les paquets CP générés.

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_13.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=4bff7bc7ae85abc391ca2d7d705ab5a0" alt="Image d'une barrière de tampon SRV vers UAV dans PIX" width="594" height="114" data-path="images/gdk/features/graphics/EnhancedBarriers_13.png" />

Dans la vue Event Details, vous pouvez obtenir tous les détails de l'appel à l'API Barrier, comme les types, le nombre de groupes de barrières, l'avant/après pour la synchronisation, l'accès et la disposition (s'il s'agit d'une barrière de texture), ainsi que pResource (s'il ne s'agit pas d'une barrière globale).

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_14.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=324c1b88b935cdee6166bb371d6c950e" alt="Interface utilisateur graphique, texte Description générée automatiquement" width="1023" height="754" data-path="images/gdk/features/graphics/EnhancedBarriers_14.png" />

**Pour les barrières de ressources (héritées)**, PIX affiche le nom de l'API ResourceBarrier et, en tant que nœud enfant, la barrière traduite (\[Barrier]).

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_15.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=3816626e092ebf565bc71b746be4e77c" alt="Interface utilisateur graphique, texte, application, site Web Description générée automatiquement" width="778" height="142" data-path="images/gdk/features/graphics/EnhancedBarriers_15.png" />

Vous pouvez voir les Event Details de la barrière héritée en sélectionnant l'événement ResourceBarrier (c'est la même chose que la vue Event Details des barrières de ressources avant les barrières améliorées, à l'exception des bits Actions qui s'affichent comme D3D12XBOX\_RESOURCE\_BARRIER\_ACTION\_NONE).

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_16.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=60ae625af8392910661bb0e243d863fc" alt="Capture d'écran d'un ordinateur Description générée automatiquement avec un niveau de confiance moyen" width="877" height="577" data-path="images/gdk/features/graphics/EnhancedBarriers_16.png" />

En sélectionnant le nœud enfant \[barrier], vous pouvez voir les Event Details de la barrière traduite (comme pour une barrière améliorée).

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/EnhancedBarriers_17.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=e9c824b9f2c87a30e721fea5af7affc3" alt="Interface utilisateur graphique, texte, application Description générée automatiquement" width="868" height="157" data-path="images/gdk/features/graphics/EnhancedBarriers_17.png" />

### **Validation**

La validation sera offerte à la fois pour les **barrières améliorées** et pour les **barrières de ressources héritées qui passent par la couche de traduction**. La validation obtenue dépendra de l'API utilisée :

* Pour les barrières améliorées, la parité de validation porte sur les scénarios couverts. Les barrières améliorées sont différentes des barrières de ressources; la validation ne reproduira donc pas exactement ce qu'elle faisait pour l'API héritée, mais garantira que toutes les propriétés avant et après sont correctes pour la transition. Par exemple :
  * S'assurer que les ressources sont dans la bonne disposition au début d'une transition.
  * Valider l'exactitude de l'utilisation de l'API (plus de détails ci-dessous).
* Pour les barrières de ressources héritées (traduites), la validation offre la parité avec la validation actuelle des barrières de ressources.

La validation vérifie également que les ressources qui passent des barrières héritées aux barrières améliorées sont dans le bon état (D3D12\_RESOURCE\_STATE\_COMMON).

**Pour la validation de l'API**, la spécification énumère ce qui est attendu. La couche de débogage valide les éléments suivants lors des appels Barrier :

* Le périphérique sous-jacent prend en charge les barrières améliorées
* Il ne s'agit pas d'une liste de commandes de type bundle
* Avertissement si un compte (de groupes ou de barrières par groupe) est nul
* Vérification que les sous-ressources de la barrière de texture correspondent aux limites des sous-ressources de la texture
* Le type de barrière correspond au type de ressource
* LayoutBefore et AccessBefore correspondent à la disposition et à l'accès connus ou présumés de la ressource.
* SyncBefore, AccessBefore et LayoutBefore sont compatibles.
* SyncAfter, AccessAfter et LayoutAfter sont compatibles.
* Les barrières de fin de fractionnement correspondent aux barrières de début de fractionnement précédentes.
* Les barrières fractionnées de tampon et D3D12\_BARRIER\_LAYOUT\_COMMON ne franchissent pas les frontières d'ExecuteCommandLists.
  * Probablement un avertissement plutôt qu'une erreur, en raison des tolérances héritées

Quant à la sortie de validation, elle suivra le schéma ci-dessous :

```cpp theme={null}
TextD3D12 ERROR: [0xA7900038] ID3D12CommandQueue(Graphics)::ExecuteCommandLists: Resource is being transitioned from legacy to enhanced barriers but is not in the state D3D12_RESOURCE_STATE_COMMON as is required.
Current State is: D3D12_RESOURCE_STATE_RENDER_TARGET
|  -Group Index:   0
|  -Barrier Index: 0
|  -Barrier
|   |  -SyncBefore:   D3D12_BARRIER_SYNC_RENDER_TARGET
|   |  -SyncAfter:    D3D12_BARRIER_SYNC_COMPUTE_SHADING
|   |  -AccessBefore: D3D12_BARRIER_ACCESS_RENDER_TARGET
|   |  -AccessAfter:  D3D12_BARRIER_ACCESS_UNORDERED_ACCESS
|   |  -LayoutBefore: D3D12_BARRIER_LAYOUT_RENDER_TARGET
|   |  -LayoutAfter:  D3D12_BARRIER_LAYOUT_UNORDERED_ACCESS
|   |  -pResource:    (0x0000000200200C00) "<untitled>"
|   |  -Subresources
|   |    |  -IndexOrFirstMipLevel: 4294967295
|   |    |  -NumMipLevels:         0
|   |    |  -FirstArraySlice:      0
|   |    |  -NumArraySlices:       0
|   |    |  -FirstPlane:           0
|   |    |  -NumPlanes:            0
|   |  -Flags: D3D12_TEXTURE_BARRIER_FLAG_NONE (0x00000000)
```


## Related topics

- [D3D12_FEATURE](/reference/graphics/d3d12/enums/d3d12_feature_public.md)
- [D3D12_BLEND](/reference/graphics/d3d12/enums/d3d12_blend_public.md)
- [D3D12_FILTER](/reference/graphics/d3d12/enums/d3d12_filter_public.md)
