Génération de l’exemple Streaming et de l’outil de contenu
Pour générer l’exemple, assurez-vous de disposer d’un environnement de développement Visual Studio 2017 à jour, d’avoir installé le GDK 1911 et d’avoir installé le Windows SDK 17134 ou une version ultérieure. Toutes les fonctionnalités Visual Studio requises proposeront de s’installer automatiquement à l’ouverture de la solution si elles ne sont pas déjà présentes. Ouvrez la solution (Streaming\Streaming.sln) et régénérez-la. Les builds release et profile sont beaucoup plus rapides que les builds debug, mais la build debug permet la validation de l’API Direct3D 12 à l’aide de la couche de débogage.Création et déploiement du contenu de textures
Générez la build release de ContentTool. Exécutez-la avec la ligne de commande suivante : contenttool.exe 64 8192 c:\temp Le paramètre « c:\temp » peut être remplacé par tout autre emplacement de répertoire temporaire approprié. Ces options génèrent 64 ensembles diffus-normal-spéculaire de textures en mosaïque avec mipmaps de 8192 × 8192, soit environ 10 Go de contenu. ContentTool consomme une grande quantité de mémoire lors de la création des textures. Nous vous recommandons de l’exécuter sur un système doté d’au moins 16 Go de mémoire. Copiez le contenu de textures généré par ContentTool (fichiers .trimg et .trdata) dans un sous-répertoire « streamingtextures » de la disposition de l’exemple Streaming, puis déployez. Pour la build plateforme Windows universelle (UWP) du devtest Streaming, les fichiers de textures doivent être déployés dans un emplacement de répertoire temporaire du package. Déployez la build UWP de l’application Streaming sans contenu et exécutez-la une fois. L’exemple démarre, affiche un message indiquant que le contenu de textures est manquant et ouvre une fenêtre de l’Explorateur de fichiers à un emplacement situé dans le répertoire temporaire de l’application. Copiez les fichiers de données de textures dans un sous-répertoire « streamingtextures » de ce répertoire temporaire. Une fois le contenu correctement déployé, l’exemple doit démarrer et afficher une grille de cubes colorés, comme dans l’image suivante.
Contrôles et utilisation
L’exemple a été conçu pour être utilisé avec une manette XBOX. Pour la build de bureau de l’exemple, nous vous recommandons de connecter une manette XBOX à votre PC de développement. Si ce n’est pas possible, des contrôles au clavier et à la souris sont également disponibles, comme indiqué dans le tableau suivant.Options et vues de débogage
- Les modes de rendu peuvent être parcourus à l’aide de la première option du menu. La complexité du nuanceur de la scène peut être augmentée d’une couche (diffus-normal-spéculaire) à trois couches (trois de chaque diffus-normal-spéculaire). En outre, la carte MinMip peut être superposée à la géométrie de la scène.
- Les statistiques de streaming sont activées par défaut et peuvent être basculées dans le menu Streaming Debug Views. Elles incluent des compteurs en temps réel du nombre de vignettes en transit, de la taille virtuelle totale de toutes les textures, de la capacité et de l’occupation du pool de vignettes, des statistiques de latence, des goulots d’étranglement, ainsi que des statistiques de résidence et d’accès par niveau de mip.
- Les textures de streaming individuelles peuvent être examinées, y compris la texture principale (ressource en mosaïque) et ses cartes MinMip et cartes de retour MinMip associées. Activez simplement Debug Texture Mode dans le menu Streaming Debug Views, puis utilisez les contrôles de la caméra pour pointer le réticule de visée sur un objet de la scène. Sa texture s’affiche et vous pouvez choisir entre les cartes diffuse, normale ou spéculaire de la première couche.
- Les temps processeur des différents sous-systèmes de streaming peuvent être activés dans le menu Streaming Debug Views.
Vue d’ensemble du moteur de streaming
Le moteur de streaming de textures de l’exemple Streaming est conçu pour le streaming de vignettes individuelles de 64 Ko. Les vignettes sont stockées en mémoire dans un pool de vignettes unique (un objet ID3D12Heap) d’une taille de 512 Mo par défaut. Un nombre quelconque de textures en mosaïque peut être instancié dans le moteur de streaming de textures, la seule limite étant la taille maximale des tas de descripteurs qui suivent les vues de ressources de nuanceur et les vues d’accès non ordonné des ressources de textures en mosaïque et de leurs cartes MinMip et cartes de retour MinMip associées. Le diagramme suivant représente le cycle d’opérations d’une texture en mosaïque individuelle dans le moteur de streaming de textures.
Création de textures en mosaïque et configuration du graphe de scène
Lorsqu’une texture en mosaïque est créée dans le moteur de streaming, les trois ressources suivantes sont créées.- La texture en mosaïque elle-même, via l’API
ID3D12Device::CreateReservedResource. - Une petite carte MinMip, créée en divisant les dimensions de la texture en mosaïque par les dimensions d’une vignette unique de 64 Ko dans ce format. Par exemple, une texture en mosaïque de 8192 × 8192 au format BC1 donnerait une carte MinMip de 16 × 32 texels, car une vignette de 64 Ko en BC1 a des dimensions de 512 × 256.
- Une petite carte de retour MinMip, de mêmes dimensions que la carte MinMip.
ID3D12Device8::CreateSamplerFeedbackUnorderedAccessViewX.
Par souci d’efficacité, les cartes de retour MinMip ne sont pas créées en tant que ressources individuelles. Elles sont plutôt créées sous forme de tranches sous-allouées d’une ressource opaque Texture2DArray plus grande, créée via l’API ID3D12Device8::CreatePlacedResource1. Cette stratégie est possible parce que de nombreuses cartes de retour MinMip partagent les mêmes dimensions. Les créer sous forme d’un tableau de textures plus grand garantit la disposition de compactage mémoire la plus efficace pour le matériel, et garantit en outre que les cartes de retour MinMip sont contiguës en mémoire, ce qui permet un effacement et un transcodage en bloc très efficaces.
Le graphe de scène contient les descripteurs visibles par le GPU, organisés par objet. Lorsque les objets de la scène sont instanciés avec leurs matériaux associés (sélections de textures en mosaïque), les descripteurs sont copiés du tas de descripteurs du moteur de streaming vers le tas de descripteurs visible par le GPU du graphe de scène.
Lors de la création de la texture en mosaïque, la queue de mip compactée (tous les niveaux de mip inférieurs à la taille de vignette de 64 Ko) est chargée depuis le disque dur et mappée dans la texture en mosaïque, et la carte MinMip est effacée avec la valeur du premier niveau de mip compacté.
Rendu de la scène et retour d’échantillonneur
Avant le rendu de la scène, toutes les cartes de retour du système sont effacées en bloc avec la valeur maximale possible dans une carte de retour, soit la valeur binaire 0xFF, ou 31,875 dans l’encodage fixe non signé 5.3. Pendant le rendu de la scène, la carte MinMip est échantillonnée pour produire une valeur de limitation du niveau de détail (LOD), puis la texture en mosaïque est échantillonnée avec cette valeur de limitation appliquée. Séparément, le retour d’échantillonneur est collecté sur la texture en mosaïque et écrit dans la carte de retour MinMip, sans appliquer la limitation du LOD. Le retour d’échantillonneur est effectué à l’aide d’une fonction du langage HLSL (high-level shader language),FeedbackTexture2D::WriteSamplerFeedback.
Les données de retour d’échantillonneur sont très redondantes. La couverture à l’écran d’une vignette de 64 Ko donnée est assurément assez grande pour les objets raisonnablement proches de la caméra. Par conséquent, le nuanceur de la scène n’exécute par défaut que 1/128 (0,7 %) des opérations de retour d’échantillonneur.
Relecture et analyse des données de retour d’échantillonneur
À chaque image, le processeur relit les données de retour d’échantillonneur pour déterminer les vignettes à charger ensuite. Tout d’abord, le nuanceur de calcul est utilisé pour copier en bloc les données de retour d’échantillonneur depuis les ressources de textures de tableau de retour accessibles en écriture par le GPU vers des empreintes placées lisibles par le processeur. Ensuite, le code processeur parcourt chaque texel des cartes de retour MinMip. Pour chaque texel, la valeur de retour MinMip est comparée à la base de données des vignettes afin de déterminer si la vignette requise pour cet emplacement, à ce niveau de mip et pour cette texture, est présente. Si la vignette n’est pas présente, une entrée de suivi est créée pour cette vignette et ajoutée à la file d’attente « Seen Tiles ». Si la vignette est déjà présente, elle est marquée avec un horodatage actuel. Une fois les cartes de retour MinMip traitées, la liste « Seen Tiles » est triée par niveau de LOD, et certaines vignettes sont mises en file d’attente pour être chargées depuis le disque dur, en commençant par les niveaux de LOD les plus élevés. Avant le chargement d’une vignette, un stockage temporaire doit être alloué pour les données compressées de la vignette, ainsi qu’un emplacement de destination dans le pool de vignettes. La disponibilité du stockage temporaire et du stockage du pool de vignettes est le principal facteur limitant le nombre de vignettes pouvant être chargées simultanément. Une fois qu’une vignette est mise en file d’attente pour le chargement, une opération d’E/S de fichier Win32 asynchrone est lancée pour la charger. Une fois l’opération terminée, plusieurs images plus tard, les données sont décompressées dans un emplacement intermédiaire décompressé. Parallèlement au chargement et à la décompression du fichier, la vignette est également mise en file d’attente pour être mappée dans la ressource en mosaïque sur le GPU via l’APIID3D12CommandQueue::UpdateTileMappings. Le chargement et le mappage d’une vignette donnée peuvent prendre plusieurs images.
Achèvement et expiration des vignettes jusqu’aux mises à jour de la carte MinMip
À chaque image, le moteur de streaming surveille différentes files d’attente pour détecter la fin du chargement et de la décompression des vignettes, ainsi que la fin de leur mappage. Les vignettes dont le chargement, la décompression et le mappage sont terminés sont placées dans une liste « Complete Tiles » et sont alors prêtes à être exposées au rendu de la scène via une mise à jour de la carte MinMip. Ces mises à jour sont mises en file d’attente et effectuées dans une copie intermédiaire côté processeur de chaque carte MinMip, puis transférées vers les cartes MinMip lisibles par le GPU via une copie de texture à l’aide deID3D12GraphicsCommandList::CopyTextureRegion.
La liste « Complete Tiles » est également triée par horodatage à chaque image. Toutes les vignettes dont l’horodatage est antérieur à un certain seuil (deux secondes) sont considérées comme expirées et marquées pour être démappées et supprimées. Les vignettes démappées entraînent également des mises à jour de la carte MinMip, qui sont mises en file d’attente et traitées avec les mises à jour de la carte MinMip pour les vignettes nouvellement chargées.
