Pour procéder à la mise en cache manuelle de PSO, vous devez exécuter une version de votre jeu en vue de collecter des informations sur les PSO (Pipeline State Objects, soit objets d'état du pipeline) dans un cache en lots. La mise en cache anticipée de PSO effectue automatiquement la collecte des PSO et la compilation asynchrone de tous les PSO pouvant être utilisés pendant le rendu.
Configurer la mise en cache anticipée de PSO
Les variables de console suivantes contrôlent la mise en cache anticipée de PSO :
| Variable de console | Description | État par défaut |
|---|---|---|
| Variable de console globale permettant d'activer la mise en cache anticipée de PSO. Celle-ci repose sur l'indicateur RHI | Enabled (Activée) |
| PSO mis en cache de façon anticipée utilisés par les composants. | Enabled (Activée) |
| PSO mis en cache de façon anticipée utilisés par toutes les ressources ( | Disabled (Désactivée) |
| Attendez la création du proxy de composant jusqu'à ce que tous les PSO nécessaires soient compilés. S'ils sont en cours de compilation au moment de créer le proxy, ces PSO sont marqués comme hautement prioritaires. | Enabled (Activée) |
| Lorsque les PSO sont en cours de compilation pendant la création des variables du composant, cette option permet de remplacer le matériau par le matériau par défaut. Cette variable dépend de | 0 (voir ci-dessous) |
| Attend uniquement les PSO hautement prioritaires pendant le chargement. Tous les PSO non essentiels sont malgré tout compilés pendant le jeu. Le PSO est marqué comme hautement prioritaire lorsqu'il est requis par un proxy et que la compilation n'a pas encore eu lieu. | Disabled (Désactivée) |
| Détermine s'il convient également d'effectuer une mise en cache anticipée des PSO de calcul global et des PSO graphiques lors du démarrage du moteur. | Enabled (Activée) |
Mise en cache anticipée de PSO pour les shaders globaux
Certains PSO de shaders globaux sont mis en cache de façon anticipée, car ils peuvent entraîner des interruptions d'exécution lors de la première utilisation. Ces PSO sont compilés au démarrage du moteur et sont activés avec la variable de console r.PSOPrecache.GlobalShaders par défaut.
Toutes les permutations de shaders de calcul globaux pouvant être utilisées par le jeu sont mises en cache de façon anticipée.
static EShaderPermutationPrecacheRequest ShouldPrecachePermutation(const FShaderPermutationParameters& Parameters)Ce code permet de vérifier si une permutation donnée peut être utilisée lors de l'exécution en vérifiant les paramètres actuels des variables de console afin d'exclure certaines combinaisons. Par défaut, il utilise ShouldCompilePermutation, de sorte que la permutation de mise en cache anticipée doit être un sous-ensemble des permutations compilées.
La plupart des PSO graphiques globaux sont créés au cours des premières images qui suivent le chargement, et des problèmes peuvent survenir dans ces images. Il peut être utile d'utiliser un petit cache en lots de PSO pour collecter ces PSO graphiques globaux. Néanmoins, dans la mesure où certaines permutations de PSO graphiques globaux sont également créées et compilées au moment de l'exécution, elles doivent également être mises en cache de manière anticipée. Pour les PSO graphiques globaux, des collecteurs de PSO spécifiques sont nécessaires pour collecter tous les états de rendu corrects, indispensables pour la compilation du PSO graphique.
La mise en cache anticipée de PSO est actuellement implémentée pour les types de shaders globaux suivants :
Slate
Lumières différées
Simulation de particules en cascade
Brouillard volumétrique
La compilation de tous les PSO globaux au démarrage prend du temps et a généralement lieu lors de la navigation dans le menu principal. Bien que cette procédure ne bloque pas le moteur au démarrage, elle devrait faire partie de la phase d'attente de compilation des PSO pendant l'écran de chargement initial.
Mise en cache anticipée de PSO pour les composants
Les composants de primitive (UPrimitiveComponent) effectuent la mise en cache anticipée de tous les PSO nécessaires pour le rendu immédiatement après le chargement (PostLoad). La mise en cache anticipée collecte toutes les informations d'état du pipeline nécessaires à la compilation des PSO, notamment :
Materials
Les fabriques de vertex
Des informations sur les éléments de vertex
Des paramètres de mise en cache anticipée spécifiques
L'Unreal Engine utilise ces informations pour itérer sur tous les processeurs de passe de maillage possibles où le composant peut être rendu. Chaque processeur de passe de maillage ajoute les initialiseurs de PSO dont il pourrait avoir besoin pendant le rendu. Les tâches en arrière-plan analysent un cache de PSO partagé pour s'assurer que les données nécessaires n'ont pas fait l'objet d'une mise en cache anticipée, puis compilent ces demandes de manière asynchrone.
Un seul composant peut nécessiter de nombreux PSO pour s'afficher correctement dans les différentes passes, notamment la base, la profondeur personnalisée, la profondeur, la distorsion, l'ombre, la texture d'ombre virtuelle, la vitesse, etc. Il est important que tous ces PSO soient disponibles avant que le composant ne soit prêt afin de ne pas introduire d'artefacts graphiques, car ceux-ci pourraient par exemple être rendus dans une passe et pas dans une autre.
Lorsque l'UE crée un proxy de primitive pour un composant de primitive et que les PSO nécessaires sont en cours de compilation, plusieurs options sont disponibles :
Retarder la création du proxy jusqu'à la fin de la compilation du PSO (option par défaut). Cette option permet de suspendre efficacement la génération jusqu'à ce que le PSO soit prêt.
Remplacer le matériau par le matériau par défaut du moteur.
Poursuivre l'opération, ce qui risque de générer un problème. La génération est bloquée lors de la compilation du PSO.
Stratégie de création différée de proxy
La variable de console r.PSOPrecache.ProxyCreationDelayStrategy dépend de la variable de console r.PSOPrecache.ProxyCreationWhenPSOReady. Si vous définissez la variable ProxyCreationWhenPSOReady sur 1 (variable activée), la variable ProxyCreationDelayStrategy exécute les comportements suivants en fonction de sa valeur :
| Valeur | Comportement |
|---|---|
0 | Elle ignore le processus de génération tant que le PSO n'est pas prêt. |
1 | Elle revient au matériau par défaut du moteur jusqu'à ce que le PSO soit prêt. |
Écran de chargement
Nous vous recommandons vivement de paramétrer votre écran de chargement initial en gardant à l'esprit les demandes de mise en cache anticipée de PSO. .
Lorsque vous configurez l'écran de chargement initial de votre jeu, vous devez attendre que toutes les demandes de mise en cache anticipée de PSO en cours soient traitées. Dans le cas contraire, des artefacts visuels notables risquent de se produire, voire des ralentissements d'exécution pour les composants qui ne prennent pas en charge la création différée de proxy, tels que les terrains de type paysage, où il pourrait être déconseillé de remplacer ces maillages par un matériau par défaut ou d'en omettre le rendu.
FShaderPipelineCache::NumPrecompilesRemaining() est utile pour vérifier le nombre de compilations de mise en cache anticipée de PSO en attente pour le cache en lots et la mise en cache anticipée de PSO. Vous pouvez modifier la logique de votre écran de chargement pour contrôler le nombre de compilations et conserver l'écran de chargement jusqu'à ce qu'il soit remis à zéro. Dans la plupart des cas, le temps de compilation initial de PSO avec un cache de pilotes vide doit prendre moins d'une minute sur des processeurs milieu de gamme.
Gérer les ressources du système
La mise en cache anticipée de PSO repose sur une compilation asynchrone utilisant des threads d'arrière-plan, et a un impact sur la mémoire et les performances du système. Dans cette section, nous vous décrivons les options disponibles pour ajuster et optimiser l'utilisation de ces ressources en fonction de votre projet.
Mémoire
Pour économiser la mémoire système à l'exécution, l'UE supprime les PSO compilés pour la mise en cache anticipée après la compilation. En effet, si la quantité de PSO mis en cache de façon anticipée par votre application est très élevée, cela peut considérablement augmenter l'empreinte mémoire de l'application, à moins de nettoyer ces PSO (qui représentent des centaines de mégaoctets, voire des gigaoctets).
La mise en cache anticipée de PSO repose sur l'existence d'un cache de pilotes compressé sous-jacent. Même lorsque les PSO sont supprimés après la mise en cache anticipée, ils sont conservés dans le cache de pilotes. Si un PSO est nécessaire à l'exécution, le pilote de la carte graphique le charge à partir de son cache de pilotes compressé. Notez toutefois que cette opération peut elle aussi nécessiter un grand nombre de ressources, et que les premières récupérations à partir de ces caches peuvent prendre quelques millisecondes. Vous pouvez désactiver la suppression des PSO mis en cache de façon anticipée dans D3D12 avec D3D12.PSOPrecache.KeepLowLevel.
La création de PSO à partir du cache de pilotes peut s'avérer lente avec certains fournisseurs de matériel indépendants (IHV). Pour NVIDIA, il existe une option permettant de conserver une certaine quantité de graphiques mis en cache de façon anticipée et de calculer les PSO en mémoire avec r.PSOPrecache.KeepInMemoryUntilUsed, qui conserve en mémoire les N derniers PSO mis en cache de façon anticipée et évite toute perte de performances due à la mémoire cache de pilotes. Il est possible d'ajuster séparément le nombre de PSO conservés en mémoire pour le calcul et les graphiques, avec r.PSOPrecache.KeepInMemoryGraphicsMaxNum et r.PSOPrecache.KeepInMemoryComputeMaxNum. Si vous décidez d'utiliser cette option, nous vous recommandons de tester le coût de mémoire résultant pour votre application avec différents paramètres afin de trouver un compromis acceptable entre les performances de création de PSO et le surcoût de mémoire.
Performances
Par défaut, l'Unreal Engine utilise un pool de threads de mise en cache anticipée de PSO pour compiler les PSO de façon asynchrone. Si le paramètre r.PSO.PrecompileThreadPoolSize ou r.PSO.PrecompileThreadPoolPercentOfHardwareThreads est défini, le pool de threads est utilisé. Dans le cas contraire, la compilation des PSO s'exécute comme une tâche en arrière-plan classique, planifiée avec les autres charges de travail du moteur.
| Variable de console | Description | État par défaut |
|---|---|---|
| Détermine la quantité exacte de threads à utiliser dans le pool. | 0 |
| Définit la taille du pool de threads en pourcentage des threads matériels disponibles, et crée un pool de threads de cette taille. La taille par défaut est de 75, ce qui représente 75 % de threads matériels. | 75 |
| Quantité minimale de threads à utiliser dans le pool de threads PSO. | 2 |
| Quantité maximale de threads à utiliser dans le pool de threads PSO. La valeur par défaut est | INT_Max |
Remarques supplémentaires :
Avec un nombre illimité de threads dans le pool de threads, il est possible que la mémoire système soit insuffisante lors de la compilation des PSO sur des systèmes dotés de nombreux processeurs, mais de peu de mémoire. Chaque thread compilant des PSO peut utiliser jusqu'à 2 Go de mémoire ; il peut donc être judicieux de limiter cette valeur pour votre projet.
Pendant le jeu, une taille de 75 % de threads matériels peut s'avérer beaucoup trop élevée. Des conflits avec les threads standard au premier plan peuvent survenir et entraîner la suppression de certaines images. Pour éviter cet écueil, il est possible d'augmenter cette valeur pendant le chargement, puis de la réduire pendant le jeu, bien que cela risque de retarder la compilation des PSO et d'augmenter le délai de création de proxy, sans toutefois entraîner de problèmes d'exécution.
Vous pouvez utiliser l'argument de ligne de commande -clearPSODriverCache pour supprimer de force le cache de pilotes, ce que nous recommandons pour tester la première expérience de démarrage de votre jeu.
Lors des tests sur des PC dotés d'un grand nombre de cœurs, nous recommandons également de limiter le nombre de cœurs à 8, ou à un nombre de cœurs standard pour un PC grand public, à l'aide des arguments de ligne de commande -corelimit=n, où n correspond au nombre de cœurs, et -processaffinity=n, qui vérifie en outre que Windows ne programmera le jeu que sur n cœurs physiques. Cela vous permet de répliquer de manière plus réaliste l'expérience utilisateur finale.
Utilisez systématiquement l'option -clearPSODriverCache pour tous les tests visant à évaluer la fluidité de votre jeu. Sans cette option, certains problèmes risquent d'être masqués par le cache PSO généré par le pilote graphique et conservé lors des exécutions précédentes.
Validation et suivi
Il existe plusieurs options pour valider et suivre les performances du système de mise en cache anticipée de PSO.
Vous pouvez activer la validation avec r.PSOPrecache.Validation en utilisant les valeurs suivantes :
| Variable de console | Description |
|---|---|
0 | Disabled (Désactivée) |
1 | Suivi léger avec uniquement les valeurs les plus importantes. Cette option a un impact minimal sur les performances et peut être utilisée dans les titres livrés. |
2 | Suivi détaillé et journalisation des échecs de mise en cache anticipée de PSO. |
Lorsque la validation de la mise en cache anticipée de PSO est active, vous pouvez inspecter les statistiques collectées à l'aide de la commande de console stat PSOPrecache.
Statistiques collectées par le système de validation de la mise en cache anticipée de PSO. Utilisez la commande de console stat PSOPrecache pour les visualiser.
Les statistiques sont divisées en 3 groupes :
| Groupe | Description |
|---|---|
PSO propres aux shaders | Ces statistiques ne suivent que les shaders RHI utilisés et ignorent toutes les autres informations d'état dans les PSO. Cela est utile pour vérifier si tous les shaders ont bien été mis en cache de façon anticipée lorsqu'un élément est manquant ou ne fonctionne pas correctement dans les autres états de rendu. Ce groupe nécessite |
PSO minimaux | Contient les shaders et toutes les statistiques de rendu ainsi que les informations sur les éléments de vertex, à l'exception des informations sur la cible de rendu. Les informations sur la cible de rendu ne sont disponibles à des fins de validation qu'au moment de la génération, mais les statistiques PSO minimales peuvent être mises à jour et vérifiées pendant la création de MeshDrawCommand. Ce groupe nécessite |
PSO complets | L'état PSO complet requis à l'exécution et utilisé par l'API graphique. Ces PSO sont identiques aux PSO minimaux, mais ils contiennent des informations de cible de rendu supplémentaires. |
Pour chaque groupe, les paramètres suivants font l'objet d'un suivi :
| Paramètre | Description |
|---|---|
Manqués | Nombre de PSO qui n'ont pas été mis en cache de façon anticipée, mais qui auraient dû l'être, car ils étaient nécessaires au moment de la génération ou de la répartition. Raisons possibles : shader, état de cible de rendu, attributs vertex ou informations de cible de rendu incorrects. |
Non suivis | Nombre de PSO dont la mise en cache anticipée n'est pas activée. Raisons possibles : validation désactivée, matériau global, fabrique de vertex non prise en charge, type de processeur de passe de maillage non pris en charge. Dans les versions de distribution, où certaines informations de débogage ne sont pas disponibles, les PSO non suivis sont considérés comme PSO manqués. |
Occurrences | Nombre de PSO utilisés à l'exécution qui ont été correctement mis en cache de façon anticipée. |
Trop tardifs | Nombre de PSO en attente de mise en cache anticipée, mais qui n'ont pas été compilés à temps pour être utilisés |
Utilisés | Nombre de PSO utilisés à l'exécution (somme des PSO ci-dessus). |
Préchargés | Nombre de PSO mis en cache de façon anticipée (mais pas nécessairement utilisés). |
Le cache de pipeline de shaders fournit également des informations sur le nombre de problèmes d'exécution détectés lors de la compilation du PSO. Une compilation de PSO est considérée comme un problème si la compilation a pris plus d'un certain nombre de millisecondes pour que le PSO d'exécution soit compilé. Le seuil par défaut est de 20 millisecondes. Vous pouvez modifier ce seuil avec r.PSO.RuntimeCreationHitchThreshold, bien que vous deviez sélectionner une valeur aussi faible que possible.
La valeur par défaut de 20 millisecondes est élevée, car les premiers accès au cache de pilotes peuvent prendre beaucoup de temps.
Collecter des informations sur la mise en cache anticipée de PSO
Vous pouvez utiliser le fichier journal, le débogueur Visual Studio et Unreal Insights pour obtenir plus d'informations sur la mise en cache anticipée de PSO et déterminer pourquoi certains PSO peuvent encore entraîner des problèmes lors de l'exécution. Les états de mise en cache anticipée de PSO corrects ne figurent dans le journal et dans Insights que lorsque la validation des PSO est activée (consultez la section Validation et suivi ci-dessus).
Lorsqu'un PSO manquant ou trop tardif est détecté, l'UE consigne les informations suivantes dans le journal :
PSO PRECACHING MISS:
Type: FullPSO
PSOPrecachingState: Missed
Material: M_AdvancedSkyDome
VertexFactoryType: FLocalVertexFactory
MDCStatsCategory: StaticMeshComponent
MeshPassName: SkyPass
Shader Hashes:
VertexShader: EC68796503F829FDEACC56B913C4CA86C6AD3C16
PixelShader: 651BF1ABBAEC0B74C8D2A5E917702A00EF29817B
Insights est un outil pratique permettant de déboguer la mise en cache anticipée de PSO. L'ajout des chronomètres PSOPrecache: Missed et PSOPrecache: Too Late à la série d'états de l'image du jeu donne un aperçu pratique de tous les problèmes causés par la compilation des PSO sur une certaine période. Dans la capture d'écran ci-dessous, vous constatez des ralentissements de 5 à 10 ms dus à des échecs de mise en cache anticipée de PSO, mais aussi un ralentissement important de 117 ms, perceptible par le joueur. Les autres principaux ralentissements ne proviennent pas de la compilation des PSO.
Cliquez sur l'image pour l'agrandir.
En y regardant de plus près, vous constatez que ces ralentissements proviennent de la passe Translucidité (le journal doit contenir plus d'informations à ce sujet) :
Cliquez sur l'image pour l'agrandir.
Vous trouverez des informations plus détaillées dans les objets d'aide de validation de PSO globaux. Lorsque la validation est définie sur le suivi complet (r.PSOPrecache.Validation=2), elle regroupe les valeurs par processeur de passes de maillage et types de fabrique de vertex, ce qui peut permettre de déterminer l'origine de certaines pertes. Elle peut également permettre de mieux comprendre l'origine de tous les PSO mis en cache de façon anticipée, et d'identifier les valeurs aberrantes qui ne devraient pas effectuer la mise en cache anticipée d'un nombre de shaders aussi élevé.
Bien que ces statistiques de fabrique par passe et par vertex ne soient pas directement exposées, il est possible de les inspecter pendant le débogage en parcourant les structures de données qui les collectent. Celles-ci se trouvent dans PSOPrecacheValidation.cpp :
FullPSOPrecacheStatsCollectorShadersOnlyPSOPrecacheStatsCollectorMinimalPSOPrecacheStatsCollector
Consultez l'exemple dans la capture d'écran ci-dessous.
Cliquez sur l'image pour l'agrandir.
Étendre la mise en cache anticipée de PSO avec les fonctionnalités du moteur
Dans cette section, nous vous expliquons comment étendre la prise en charge des objets pour la mise en cache anticipée de PSO.
UPrimitiveComponent
UPrimitiveComponent collecte toutes les informations nécessaires à la configuration de l'initialiseur de PSO. Il nécessite l'instance de matériau, la fabrique de vertex (avec l'ensemble d'éléments de vertex éventuel) et l'ensemble des paramètres susceptibles d'influer sur le shader final ou l'état de rendu utilisé dans FMeshPassProcessor.
Les paramètres sont stockés dans FPSOPrecacheParams et les valeurs par défaut sont configurées dans UPrimitiveComponent::SetupPrecachePSOParams.
La fonction d'entrée de base pour la mise en cache anticipée de PSO est la suivante :
/** Precache all PSOs which can be used by the primitive component */
ENGINE_API virtual void PrecachePSOs();Dans la plupart des cas, le composant dérivé n'a pas besoin d'implémenter cette fonction et peut se limiter à remplacer la fonction de collecte des paramètres de mise en cache anticipée :
/**
* Collect all the data required for PSO precaching
*/
struct FComponentPSOPrecacheParams
{
EPSOPrecachePriority Priority = EPSOPrecachePriority::Medium;
Vous trouverez un exemple complet dans UStaticMeshComponent::CollectPSOPRecacheData et un cas d'utilisation plus simple dans WaterMeshComponent::CollectPSOPrecacheData.
FVertexFactory
Une nouvelle fabrique de vertex doit signaler qu'elle prend en charge la mise en cache anticipée de PSO à l'aide de l'indicateur EVertexFactoryFlags::SupportsPSOPrecaching, qui peut être fourni avec la macro de déclaration de fabrique de vertex IMPLEMENT_VERTEX_FACTORY_TYPE.
La fabrique de vertex doit alors implémenter la fonction suivante :
static void GetPSOPrecacheVertexFetchElements(EVertexInputStreamType VertexInputStreamType, FVertexDeclarationElementList& Elements);FVertexFactory::GetPSOPrecacheVertexFetchElements est utilisée pendant la mise en cache anticipée de PSO si aucun ensemble d'éléments de vertex explicite n'est fourni.
L'ensemble d'éléments de vertex fixe est valide si l'indicateur EVertexFactoryFlags::SupportsManualVertexFetch est défini sur la fabrique de vertex ou si un ensemble d'éléments de vertex fixe est utilisé dans le shader.
Si la liste des éléments de vertex dépend des données du tampon de vertex du maillage, l'ensemble correct doit être fourni dans FPSOPrecacheVertexFactoryData. Cela doit survenir pendant UPrimitiveComponent::CollectPSOPRecacheData. Consultez par exemple les fonctions UStaticMeshComponent::CollectPSOPrecacheData et FLocalVertexFactory::GetVertexElements.
FMeshPassProcessor
Le processeur de passe de maillage doit implémenter la fonction suivante pour collecter tous les PSO qui peuvent être utilisés lors de la génération d'un certain matériau avec FPSOPrecacheParams :
virtual void CollectPSOInitializers(const FSceneTexturesConfig& SceneTexturesConfig, const FMaterial& Material, const FPSOPrecacheVertexFactoryData& VertexFactoryData, const FPSOPrecacheParams& PreCacheParams, TArray<FPSOPrecacheData>& PSOInitializers) override {}La logique est pratiquement identique à celle de AddMeshBatch (et peut idéalement être partiellement partagée). Cependant, alors que la fonction AddMeshBatch est appelée au moment de la construction de MeshDrawCommand, le système de mise en cache anticipée de PSO tente de collecter les informations beaucoup plus tôt (PostLoad du composant).
Pour obtenir un exemple simple, consultez FDistortionMeshProcessor::CollectPSOInitializers. Pour obtenir un exemple plus détaillé, consultez FBasePassMeshProcessor::CollectPSOInitializers.
IPSOCollector
Tous les shaders de matériau ne passent pas par un processeur de maillage ou n'ont plus EMeshPass::Type défini (comme les mises à jour de géométries dynamiques Poils, Nanite ou Ray tracing). Pour ceux-ci, il peut être nécessaire de passer directement par l'interface de base.
IPSOCollector a une seule fonction virtuelle qui doit être implémentée :
// Collect all PSO for given material, vertex factory & params
virtual void CollectPSOInitializers(const FSceneTexturesConfig& SceneTexturesConfig, const FMaterial& Material, const FPSOPrecacheVertexFactoryData& VertexFactoryData, const FPSOPrecacheParams& PreCacheParams, TArray<FPSOPrecacheData>& PSOInitializers) = 0;Le collecteur de PSO doit également être enregistré pour la création via une fonction FRegisterPSOCollectorCreateFunction globale. Il existe quelques exemples simples dans le moteur : FTranslucentLightingMaterialPSOCollector, FRayTracingDynamicGeometryPSOCollector, etc.
GlobalPSOCollector
Comme mentionné précédemment dans cette page, certains PSO graphiques globaux sont mis en cache de façon anticipée au démarrage, dont nous savons qu'ils peuvent compiler des permutations à l'exécution. Pour cela, le GlobalPSOCollector est utilisé. Il s'agit d'une version simplifiée du IPSOCollector. Un objet global FRegisterGlobalPSOCollectorFunction doit être déclaré, qui fournit la fonction de collecteur de PSO globale :
typedef void (*GlobalPSOCollectorFunction)(const FSceneTexturesConfig& SceneTexturesConfig, int32 GlobalPSOCollectorIndex, TArray<FPSOPrecacheData>& PSOInitializers);Consultez DeferredLightGlobalPSOCollector ou RegisterVolumetricFogGlobalPSOCollector pour obtenir des exemples d'utilisation.
Déboguer une erreur de mise en cache anticipée de PSO
Pour déboguer l'origine de l'erreur de la mise en cache anticipée de PSO ci-dessus, vous devez utiliser le débogage manuel dans Visual Studio.
Le débogage des erreurs sur un état de PSO minimal est simple, car celles-ci peuvent être déclenchées pendant la création de MeshDrawCommand et non au cours de la phase de génération. Les informations finales sur la cible de rendu, nécessaires pour calculer le PSO complet, ne sont disponibles que pendant la génération, ce qui rend le débogage plus difficile.
Utilisez la fonction LogPSOMissInfo pour interrompre le débogueur lorsqu'une erreur se produit à l'exécution. La pile d'appels et la fenêtre de surveillance peuvent fournir des informations supplémentaires sur le matériel utilisé, la passe de rendu, la fabrique de vertex et le FPrimitiveSceneProxy. Vous pouvez également obtenir des informations sur le composant UPrimitiveComponent en utilisant le membre ComponentForDebuggingOnly. La plupart de ces données sont également consignées dans le fichier journal lorsqu'une erreur est détectée (collectées dans cette fonction).
Cependant, au moment où LogPSOMissInfo s'exécute, la mise en cache anticipée de PSO a généralement déjà eu lieu sur ce composant. Si vous tentez de déterminer les raisons pour lesquelles un shader ou un état de rendu incorrect a été utilisé pendant la mise en cache anticipée des PSO de ce composant, vous devez ajouter un point d'arrêt pendant la mise en cache anticipée de PSO pour ce composant et/ou ce matériau pour la passe donnée.
r.PSOPrecache.BreakOnMaterialName est utile pour interrompre la mise en cache anticipée de PSO lorsqu'un matériau portant un nom donné est détecté. Cela peut vous aider à déterminer pourquoi certains états de rendu diffèrent de l'état d'exécution. Vous pouvez en outre utiliser r.PSOPrecache.BreakOnPassName et r.PSOPrecache.BreakOnShaderHash pour limiter la recherche aux PSO problématiques. Ces informations se trouvent dans le journal, comme mentionné ci-dessus.
r.PSOPrecache.UseBackgroundThreadForCollection est utile pour désactiver les tâches du thread en arrière-plan pour la collecte de l'initialiseur de PSO afin de faciliter le suivi des informations sur les composants ou d'autres états lors du débogage d'une erreur de mise en cache anticipée de PSO.
Il est possible que vous deviez vérifier les valeurs de FPSOPRecacheParams, car celles-ci peuvent également influer sur le shader et l'état de rendu utilisés dans le PSO.