Vue d’ensemble des descripteurs
Les descripteurs sont créés par des appels d’API et identifient des ressources.
- Données de descripteurs
- Poignées de descripteurs
- Descripteurs Null
- Descripteurs par défaut
- Rubriques connexes
Données de descripteurs
Un descripteur est un bloc de données relativement restreint qui fournit une description complète d’un objet pour le GPU en format opaque spécifique au GPU. Il y a plusieurs types de descripteurs : afficher les vues cibles (RTV), les vues de gabarit de profondeur (DSV), les vues de ressources de nuanceurs (SRV), les vues d’accès non ordonné (UAV), les vues de mémoire tampon constante (CBV) et les échantillonneurs.
Les descripteurs varient en matière de taille selon le matériel de GPU. Vous pouvez rechercher la taille d’une SRV, d’une UAV ou d’une CBV en appelant ID3D12Device::GetDescriptorHandleIncrementSize. Dans cette documentation, les descripteurs sont présentés en tant qu’unités indivisibles. En voici un exemple.
Les descripteurs sont créés par des appels d’API et comprennent des informations telles que la ressource et les mappages mip que vous souhaitez contenir dans le descripteur.
Le pilote ne piste pas et ne contient pas de références aux descripteurs. Il incombe à l’application d’assurer que le bon type de descripteur est utilisé et que les informations sont à jour. Une petite exception existe à cette règle : le pilote inspecte les liaisons cibles de rendu pour assurer que les chaînes d’échange fonctionnent correctement.
Les descripteurs d’objet n’ont pas besoin d’être libérés ou mis en production. Les pilotes ne joignent aucune allocation à la création d’un descripteur. Toutefois, il se peut qu’un descripteur encode des références à d’autres allocations pour lesquelles l’application possède la durée de vie. Par exemple, un descripteur de SRV doit contenir l’adresse virtuelle de la ressource D3D (par exemple, une texture) à laquelle la SRV fait référence. Il incombe à l’application d’assurer qu’elle n’utilise pas de descripteur SRV lorsque la ressource D3D sous-jacente dont elle dépend est détruite ou modifiée (par exemple, déclarée comme non résidente).
La principale façon d’utiliser des descripteurs consiste à les placer dans des tas de descripteurs qui sauvegardent la mémoire pour ces derniers.
Poignées de descripteurs
Une poignée de descripteur est son adresse unique du descripteur. Elle ressemble à un pointeur, mais elle est opaque, car son implémentation est spécifique au matériel. La poignée est unique à travers tous les tas de descripteurs. Par exemple, un groupe de poignées peut référencer des descripteurs dans plusieurs tas.
Les poignées d’UC sont destinées à une utilisation immédiate, par exemple lorsqu’il faut copier l’endroit où la source et la destination doivent être identifiées. Elles peuvent être réutilisées immédiatement après utilisation (par exemple, pour un appel à ID3D12GraphicsCommandList::OMSetRenderTargets). Sinon, leur tas sous-jacent peut être supprimé.
Les poignées de GPU ne sont pas immédiatement utilisées. Elles identifient à partir d’une liste de commandes les emplacements à utiliser au moment de l’exécution du GPU. Elles doivent être conservées jusqu’à ce que toutes les listes de commandes qui les référencent se soient entièrement exécutées.
Pour créer une poignée de descripteur pour le début d’un tas, appelez l’une des méthodes suivantes après avoir créé le tas de descripteurs lui-même :
- ID3D12DescriptorHeap::GetCPUDescriptorHandleForHeapStart
- ID3D12DescriptorHeap::GetGPUDescriptorHandleForHeapStart
Ces méthodes retournent les structures suivantes :
Comme la taille des descripteurs varie selon le matériel, utilisez la méthode suivante pour obtenir l’incrément entre chaque descripteur dans un tas :
Vous pouvez, en toute sécurité, décaler un emplacement de départ par un certain nombre d’incréments, copier des poignées et passer des poignées dans des appels d’API. Vous ne pouvez pas, de façon sécurisée, déréférencer une poignée comme s’il s’agissait d’un pointeur d’UC valide, ni analyser les bits dans une poignée.
Certaines structures d’assistance ont été ajoutées et sont accompagnées de membres d’initialisation pour faciliter la gestion des poignées.
Descripteurs Null
Lors de la création de descripteurs à l’aide d’appels d’API, les applications passent la valeur NULL pour le pointeur de ressource dans la définition du descripteur afin d’obtenir un effet « aucune liaison » lorsqu’on y accède avec un nuanceur.
Le reste du descripteur doit être rempli autant que possible. Par exemple, dans le cas des vues de ressources de nuanceurs (SRV), le descripteur peut être utilisé pour distinguer son type de vue (Texture1D, Texture2D, etc.). Les paramètres chiffrés dans le descripteur d’affichage, tels que le nombre de mappages mip, doivent tous être définis sur des valeurs valides pour une ressource.
Dans de nombreux cas, il existe un comportement défini pour accéder à une ressource indépendante, comme des SRV qui retournent des valeurs par défaut. Celles-ci sont respectées lors de l’accès à un descripteur NULL, tant que le type d’accès au nuanceur est compatible avec le type de descripteur. Par exemple, si un nuanceur s’attend à une SRV Texture2D et accède à une SRV NULL définie en tant que Texture1D, le comportement n’est pas défini et peut entraîner la réinitialisation de l’appareil.
En résumé, pour créer un descripteur null, passez null
pour le paramètre pResource lorsque vous créez la vue avec des méthodes comme CreateShaderResourceView. Pour le paramètre de description d’affichage pDesc, définissez une configuration qui fonctionne si la ressource n’est pas null (sinon, des incidents peuvent se produire sur certains matériels).
Toutefois, les descripteurs racines ne doivent pas être définis sur null.
Pour le matériel de niveau 1 (voir Niveaux matériels), tous les descripteurs liés (via des tables de descripteurs) doivent être initialisés en tant que descripteurs réels ou null, même s’ils ne sont pas accessibles par le matériel. Autrement, le comportement n’est pas défini.
Sur le matériel de niveau 2, cela s’applique aux descripteurs CBV et UAV liés, mais pas aux descripteurs SRV.
Sur le matériel de niveau 3, il n’existe aucune restriction à ce sujet, à condition que l’on n’accède jamais aux descripteurs non initialisés.
Descripteurs par défaut
Pour créer un descripteur par défaut pour une vue particulière, transmettez un paramètre pResource valide à la méthode de création de vue (par exemple CreateShaderResourceView), mais transmettez NULL pour le paramètre pDesc. Par exemple, si la ressource contient 14 mips, la vue contient 14 mips. Le cas par défaut concerne le mappage le plus évident d’une ressource à une vue. Cela exige donc que la ressource soit allouée avec un nom de format complet (par exemple DXGI_FORMAT_R8G8B8A8_UNORM_SRGB plutôt que DXGI_FORMAT_R8G8B8A8_TYPELESS).
Les descripteurs par défaut ne peuvent pas être utilisés avec une vue de structure d’accélération de raytracing, car le paramètre pResource fourni doit être NULL et l’emplacement doit être transmis via une D3D12_RAYTRACING_ACCELERATION_STRUCTURE_SRV.