Optimisations UMA : textures accessibles par le processeur et Swizzle standard

Les GPU UMA (Universal Memory Architecture) offrent certains avantages en termes d’efficacité par rapport aux GPU discrets, en particulier lors de l’optimisation pour les appareils mobiles. Le fait de donner aux ressources un accès processeur lorsque le GPU est UMA peut réduire la quantité de copie qui se produit entre le processeur et le GPU. Bien que nous ne recommandons pas que les applications donnent aveuglément l’accès au processeur à toutes les ressources sur les conceptions UMA, il existe des possibilités d’améliorer l’efficacité en donnant aux ressources l’accès processeur approprié. Contrairement aux GPU discrets, le processeur peut techniquement avoir un pointeur vers toutes les ressources auxquelles le GPU peut accéder.

Vue d’ensemble des textures accessibles au processeur

Les textures accessibles au processeur, dans le pipeline graphique, sont une fonctionnalité de l’architecture UMA, qui permet aux processeurs d’accéder en lecture et en écriture aux textures. Sur les GPU discrets les plus courants, le processeur n’a pas accès aux textures dans le pipeline graphique.

Les meilleures pratiques générales pour les textures sont de prendre en charge les GPU discrets, ce qui implique généralement de suivre les processus de chargement de données de texture via des mémoires tampons, résumés comme suit :

  • N’ayant aucun accès au processeur pour la majorité des textures.
  • Définition de la disposition de texture sur D3D12_TEXTURE_LAYOUT_UNKNOWN.
  • Chargement des textures sur le GPU avec CopyTextureRegion.

Toutefois, dans certains cas, le processeur et le GPU peuvent interagir si fréquemment sur les mêmes données que les textures de mappage deviennent utiles pour économiser de l’énergie ou pour accélérer une conception particulière sur des cartes ou architectures particulières. Les applications doivent détecter ces cas et optimiser les copies inutiles. Dans ce cas, pour optimiser les performances, tenez compte des éléments suivants :

  • Commencez à divertir les meilleures performances des textures de mappage uniquement lorsque D3D12_FEATURE_DATA_ARCHITECTURE::UMA a la valeur TRUE. Faites ensuite attention à CacheCoherentUMA si vous décidez quelles propriétés de cache processeur choisir sur le tas.

  • L’utilisation de l’accès du processeur pour les textures est plus compliquée que pour les mémoires tampons. Les dispositions de texture les plus efficaces pour les GPU sont rarement row_major. En fait, certains GPU ne peuvent prendre en charge row_major textures que lors de la copie de données de texture.

  • Les GPU UMA doivent bénéficier d’une optimisation simple pour réduire les temps de chargement au niveau. Après avoir reconnu UMA, l’application peut optimiser le CopyTextureRegion initial pour remplir les textures que le GPU ne modifiera pas. Au lieu de créer la texture dans un tas avec D3D12_HEAP_TYPE_DEFAULT et de marshaler les données de texture, l’application peut utiliser WriteToSubresource pour éviter de comprendre la disposition de texture réelle.

  • Dans D3D12, les textures créées avec D3D12_TEXTURE_LAYOUT_UNKNOWN et aucun accès au processeur sont les plus efficaces pour le rendu et l’échantillonnage GPU fréquents. Lors des tests de performances, ces textures doivent être comparées aux D3D12_TEXTURE_LAYOUT_UNKNOWN avec accès au processeur, et D3D12_TEXTURE_LAYOUT_STANDARD_SWIZZLE avec l’accès au processeur, et D3D12_TEXTURE_LAYOUT_ROW_MAJOR pour la prise en charge des cartes croisées.

  • L’utilisation de D3D12_TEXTURE_LAYOUT_UNKNOWN avec l’accès au processeur active les méthodes WriteToSubresource, ReadFromSubresource, Map (empêchant l’accès de l’application au pointeur) et Unmap ; mais peut sacrifier l’efficacité de l’accès GPU.

  • L’utilisation de D3D12_TEXTURE_LAYOUT_STANDARD_SWIZZLE avec accès au processeur active WriteToSubresource, ReadFromSubresource, Map (qui retourne un pointeur valide vers l’application) et Unmap. Il peut également sacrifier l’efficacité de l’accès GPU plus que D3D12_TEXTURE_LAYOUT_UNKNOWN avec l’accès au processeur.

Vue d’ensemble de Standard Swizzle

D3D12 (et D3D11.3) introduisent une disposition de données multidimensionnelle standard. Cette opération permet à plusieurs unités de traitement de fonctionner sur les mêmes données sans copier les données ou les basculer entre plusieurs dispositions. Une disposition standardisée permet des gains d’efficacité grâce aux effets réseau et permet aux algorithmes d’effectuer des raccourcis en supposant un modèle particulier.

Pour obtenir une description détaillée des dispositions de texture, reportez-vous à D3D12_TEXTURE_LAYOUT.

Notez toutefois que ce swizzle standard est une fonctionnalité matérielle et peut ne pas être pris en charge par tous les GPU.

Pour obtenir des informations d’arrière-plan sur le swizzling, reportez-vous à la courbe d’ordre Z.

API

Contrairement à D3D11.3, D3D12 prend en charge le mappage de textures par défaut, il n’est donc pas nécessaire d’interroger D3D12_FEATURE_DATA_D3D12_OPTIONS. Toutefois, D3D12 ne prend pas toujours en charge swizzle standard. Cette fonctionnalité doit être interrogée avec un appel à CheckFeatureSupport et en vérifiant le champ StandardSwizzle64KBSupported de D3D12_FEATURE_DATA_D3D12_OPTIONS.

Les API suivantes référencent le mappage de texture :

Énumérations

  • D3D12_TEXTURE_LAYOUT : contrôle le modèle swizzle des textures par défaut et active la prise en charge de la carte sur les textures accessibles au processeur.

Structures

Méthodes

Les ressources et les tas parents ont des exigences d’alignement :

  • D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT (4 Mo) pour les textures multi-exemples.
  • D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT (64 Ko) pour les textures et mémoires tampons d’un seul exemple.
  • La copie linéaire de sous-ressources doit être alignée sur D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT (512 octets), le pitch de ligne étant aligné sur D3D12_TEXTURE_DATA_PITCH_ALIGNMENT (256 octets).
  • Les vues de mémoire tampon constantes doivent être alignées sur D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT (256 octets).

Les textures inférieures à 64 Ko doivent être traitées via CreateCommittedResource.

Avec des textures dynamiques (textures qui changent chaque image), le processeur écrit linéairement dans le tas de chargement, suivi d’une opération de copie GPU.

En règle générale, pour créer des ressources dynamiques, créez une mémoire tampon volumineuse dans un tas de chargement ( reportez-vous à Sous-emplacement dans les mémoires tampons). Pour créer des ressources intermédiaires, créez une mémoire tampon volumineuse dans un tas de lecture différée. Pour créer des ressources statiques par défaut, créez des ressources adjacentes dans un tas par défaut. Pour créer des ressources avec alias par défaut, créez des ressources qui se chevauchent dans un tas par défaut.

WriteToSubresource et ReadFromSubresource réorganisent les données de texture entre une disposition principale de ligne et une disposition de ressource non définie. L’opération étant synchrone, l’application doit garder à l’esprit la planification du processeur. L’application peut toujours diviser la copie dans des régions plus petites ou planifier cette opération dans une autre tâche. Les ressources MSAA et les ressources de gabarit de profondeur avec des dispositions de ressources opaques ne sont pas prises en charge par ces opérations de copie du processeur et entraînent un échec. Les formats qui n’ont pas de taille d’élément power-of-two ne sont pas non plus pris en charge et entraînent également un échec. Des codes de retour de mémoire insuffisante peuvent se produire.

Constantes principales

ID3D12Heap

Liaison de ressources