Suivi de l’utilisation de l’allocation
Avec la liste d’allocations qui disparaît, le gestionnaire de mémoire vidéo (VidMm) n’a plus de visibilité sur les allocations référencées dans une mémoire tampon de commande particulière. Par conséquent, le VidMm n’est plus en mesure de suivre l’utilisation de l’allocation et de gérer la synchronisation associée. Cette responsabilité incombe maintenant au pilote en mode utilisateur (UMD). En particulier, l’UMD doit gérer la synchronisation en ce qui concerne l’accès direct du processeur à l’allocation et au renommage.
Le VidMm reporte de manière asynchrone la destruction de l’allocation de manière sécurisée, à la fois non bloquante pour le thread appelant et performante. En tant que tel, une UMD n’a pas à se soucier de devoir reporter la destruction de l’allocation. Lorsque VidMm reçoit une demande de destruction d’allocation, il suppose par défaut que les commandes mises en file d’attente avant la demande de destruction peuvent potentiellement accéder à l’allocation en cours de destruction. VidMm reporte donc l’opération de destruction jusqu’à ce que les commandes en file d’attente se terminent. Si l’UMD sait que les commandes en attente n’accèdent pas à l’allocation en cours de destruction, il peut demander au VidMm de traiter la demande sans attendre en définissant l’indicateur AssumeNotInUse lors de l’appel de Deallocate2 ou DestroyAllocation2.
Lock2
L’UMD est responsable de la gestion de la synchronisation appropriée en ce qui concerne l’accès direct au processeur. En particulier, une UMD est requise pour :
Prise en charge de la sémantique de verrouillage sans remplacement et d’abandon, ce qui implique que l’UMD doit implémenter son propre schéma de renommage.
Pour les opérations de mappage nécessitant une synchronisation (c’est-à-dire, pas le remplacement ou l’abandon ci-dessus) :
- Retourne WasStillDrawing si une tentative d’accès à une allocation est actuellement occupée et que l’appelant a demandé que l’opération Lock ne bloque pas le thread appelant (D3D11_MAP_FLAG_DO_NOT_WAIT).
- Ou, si l’indicateur D3D11_MAP_FLAG_DO_NOT_WAIT n’est pas défini, attendez qu’une allocation soit disponible pour l’accès au processeur. L’UMD doit implémenter une attente nonpolante. L’UMD utilisera le nouveau mécanisme de surveillance du contexte.
Pour l’instant, l’UMD continue d’appeler LockCb/UnlockCb pour demander au VidMm de configurer une allocation pour l’accès au processeur. Dans la plupart des cas, l’UMD peut conserver l’allocation mappée pendant toute sa durée de vie. Toutefois, à l’avenir, LockCb et UnlockCb seront dépréciés en faveur des nouveaux appels Lock2Cb et Unlock2Cb . L’objectif de ces rappels plus récents est de fournir une nouvelle implémentation propre avec un nouvel ensemble d’arguments et d’indicateurs.
Les plages swizzling sont supprimées de WDDM version 2. Il incombe au développeur de pilotes de supprimer la dépendance aux plages de swizzling des appels à LockCb à mesure qu’ils se déplacent vers une implémentation basée sur Lock2Cb.
Lock2Cb est exposé comme une méthode simple pour obtenir une adresse virtuelle à une allocation. Il existe quelques restrictions en fonction du type d’allocation et du segment actuel dans lequel il réside actuellement.
Le pilote indique si un segment est accessible au processeur via l’indicateur CpuVisible , qui se trouve dans le membre Flags de la structure DXGK_SEGMENTDESCRIPTOR .
Pour les allocations accessibles au processeur :
- Les allocations accessibles au processeur mises en cache doivent résider dans un segment d’ouverture ou ne pas être résidentes pour être verrouillées. Nous ne pouvons pas garantir la cohérence du cache entre le processeur et un segment de mémoire sur l’unité de traitement graphique (GPU).
- Les allocations accessibles au processeur situées dans un segment de mémoire entièrement accessible au processeur (redimensionnée à l’aide de la barre d’accès redimensionnable) sont garanties comme verrouillables et capables de retourner une adresse virtuelle. Aucune contrainte spéciale n’est requise dans ce scénario.
- Les allocations accessibles au processeur situées dans un segment de mémoire non accessible au processeur (avec ou sans accès à un ProcesseurHostAperture) peuvent ne pas être mappées à une adresse virtuelle du processeur pour différentes raisons. Si cpuHostAperture n’a plus d’espace disponible ou si l’allocation ne spécifie pas de segment d’ouverture, il est impossible d’obtenir une adresse virtuelle. Pour cette raison, toutes les allocations accessibles au processeur dans les segments de mémoire non accessibles au processeur doivent contenir un segment d’ouverture dans leur jeu de segments pris en charge. Cette exigence garantit que VidMm est en mesure de placer l’allocation dans la mémoire système et de fournir une adresse virtuelle.
- Les allocations accessibles au processeur déjà situées dans la mémoire système (et/ou mappées dans un segment d’ouverture) sont garanties de fonctionner.
Pour les allocations non accessibles au processeur :
- Les allocations accessibles au processeur sont sauvegardées par des objets de section qui ne peuvent pas pointer directement vers la mémoire tampon de trame des GPU. Pour verrouiller une allocation non accessible au processeur, l’allocation doit prendre en charge un segment d’ouverture dans l’ensemble de segments pris en charge, ou se trouver déjà dans la mémoire système (ne doit pas être résidente sur l’appareil).
Si une allocation est correctement verrouillée alors que l’allocation n’est pas résidente sur l’appareil, mais ne prend pas en charge un segment d’ouverture, l’allocation ne doit pas être validée dans un segment de mémoire pendant la durée du verrouillage.
Lock2 ne contient actuellement aucun indicateur, et les bits d’indicateur réservés doivent tous être 0.
CpuHostAperture
Pour mieux prendre en charge le verrouillage avec des segments de mémoire non accessibles au processeur lors de l’échec du redimensionnement de la barre d’accès, un processeurHostAperture est fourni dans l’ouverture PCI. CpuHostAperture se comporte comme un gestionnaire basé sur une page, qui peut ensuite être mappé directement aux régions de la mémoire vidéo via la fonction d’interface du pilote de périphérique (DDI) DxgkDdiMapCpuHostAperture. Le VidMm peut ensuite mapper une plage d’espace d’adressage virtuel directement à une plage non contiguée de CpuHostAperture, et faire mapper cpuHostAperture à la mémoire vidéo sans avoir besoin de plages swizzling.
La quantité maximale de mémoire verrouillable que le processeur peut référencer dans des segments de mémoire non accessibles au processeur est limitée à la taille de CpuHostAperture. Vous trouverez les détails de l’exposition de CpuHostAperture au noyau graphique DirectX dans l’ouverture de l’hôte du processeur.
Cohérence des E/S
Sur x86/x64 aujourd’hui, tous les GPU doivent prendre en charge la cohérence des E/S sur PCIe afin de permettre à un GPU de lire ou d’écrire sur une surface de mémoire système pouvant être mise en cache et de maintenir la cohérence avec le processeur. Lorsqu’une surface est mappée en tant que cache cohérent du point de vue du GPU, le GPU doit espionner les caches du processeur lors de l’accès à la surface. Cette forme de cohérence est généralement utilisée pour les ressources dont le processeur est censé lire, comme certaines surfaces de préproduction.
Sur certaines plateformes Arm, la cohérence des E/S n’est pas prise en charge directement dans le matériel. Sur ces plateformes, la cohérence des E/S doit être émulée en invalidant manuellement la hiérarchie du cache du processeur. Pour ce faire, le VidMm effectue le suivi des opérations vers une allocation provenant du GPU (opération de lecture/écriture de liste d’allocation) et du processeur (opération mapper, lecture/écriture). VidMm émet une invalidation du cache lorsqu’il détermine que le cache peut contenir :
- Données qui doivent être réécrites (écriture processeur, lecture GPU)
- Données obsolètes qui doivent être invalidées (écriture GPU, lectures du processeur).
Sur la plateforme sans cohérence d’E/S, la responsabilité de suivre l’accès processeur et GPU aux allocations incombe à l’UMD. Le noyau graphique expose un nouveau DDI de cache invalidéque l’UMD peut utiliser pour réécrire et invalider la plage d’adresses virtuelles associée à une allocation pouvant être mise en cache. Sur les plateformes qui n’ont pas de prise en charge de la cohérence des E/S, l’UMD est nécessaire pour appeler cette fonction après l’écriture du processeur et avant la lecture du GPU, ainsi qu’après l’écriture et avant la lecture du processeur. Ce dernier peut sembler peu intuitif au premier abord. Mais, étant donné que le processeur pouvait avoir lu des données de manière spéculative avant l’écriture gpu en mémoire, il est nécessaire d’invalider tous les caches du processeur pour s’assurer que le processeur lit à nouveau les données à partir de la RAM.