Für manuelles PSO-Caching müssen Sie einen Build Ihres Spiels spielen, um PSO Informationen (Pipeline-Zustandsobjekt (PSO)) in einem Bundled Cache zu sammeln. PSO Vorcaching führt eine automatische PSO Sammlung und asynchrone Kompilierung für alle PSOs durch, die beim Rendering verwendet werden könnten.
PSO Precaching konfigurieren
Die folgenden Konsolenvariablen steuern das PSO-Precaching:
| Konsolenvariable | Beschreibung | Standardzustand |
|---|---|---|
| Globale Konsole Variable zum Einschalten von PSO-Precaching. Dies hängt von der RHI Flag (das) | Aktiviert |
| Vorcache-PSOs, die von Komponenten verwendet werden. | Aktiviert |
| Precache-PSOs, die von allen Ressourcen verwendet werden ( | Deaktiviert |
| Warten Sie auf die Erstellung des Komponenten-Proxys, bis alle erforderlichen PSOs kompiliert wurden. Wenn sie während der Proxy-Erstellung noch immer kompilieren werden, werden diese PSOs als hohe Priorität markiert. | Aktiviert |
| Wenn PSOs während der Proxy-Erstellung der Komponente noch kompilieren, fügt dies eine Option hinzu, das Material durch das Standardmaterial zu ersetzen. Dies hängt von | 0 (siehe unten) |
| Warte beim Laden nur auf PSOs mit hoher Priorität. Alle nicht essenziellen PSOs werden während des Gameplays kompilieren. Ein PSO wird als "Hohe Priorität" markiert, wenn er von einem Proxy benötigt wird und noch nicht kompiliert ist. | Deaktiviert |
| Legt fest, ob global Berechnungs- und Grafik-PSOs beim Start der Engine vorab zwischengespeichert werden sollen. | Aktiviert |
Global Shaders PSO Precaching
Bestimmte globale Shader PSOs werden vorab zwischengespeichert, da diese bei der ersten Verwendung zu Laufzeit-Hinches führen können. Diese PSOs werden beim Starten der Engine kompiliert und sind standardmäßig mit der Konsolenvariable r.PSOPrecache.GlobalShaders aktiviert.
Alle global Compute-Shader-Permutationen, die vom Spiel verwendet werden können, werden vorab zwischengespeichert.
static EShaderPermutationPrecacheRequest ShouldPrecachePermutation(const FShaderPermutationParameters& Parameters)Dies dient dazu, zu prüfen, ob eine bestimmte Permutation zur Laufzeit verwendet werden kann, indem die aktuellen Konsolenvariable-Einstellungen geprüft werden, um bestimmte Kombinationen auszuschließen. Standardmäßig wird ShouldCompilePermutation verwendet, daher sollte die Precache-Permutation eine Untermenge der kompilierten Permutationen sein.
Die meisten globalen Grafik-PSOs werden während der ersten Frames direkt nach dem Laden erstellt, und während dieser Frames sind einige Hitches zu erkennen. Die Verwendung eines sehr kleinen PSO-Pakets-Caches zum Sammeln dieser globalen Grafik-PSOs kann helfen. Aber bestimmte globale Grafik PSO-Permutationen werden ebenfalls zur Laufzeit erstellt und kompiliert, daher sollten diese auch vorgespeichert werden. Für global Grafik-PSOs werden spezielle PSO Kollektoren benötigt, um den korrekten Rendern Zustand zu sammeln, der zum kompilieren des Grafik- PSO benötigt wird.
PSO-Precaching ist aktuell für die folgenden globalen Shader-Typen implementiert:
Slate
Nachträgliche Lichter
Cascade-Partikelsimulation
Volumetrischer Nebel
Das Kompilieren aller global PSOs beim Start nimmt einige Zeit in Anspruch und geschieht normalerweise während der Navigation durch das Menü. Dies blockiert die Engine beim Start nicht, sollte aber Teil der Wartephase der PSO-Kompilierung während des anfänglichen Ladebildschirms sein.
Komponenten-PSO-Precaching
Grundkörper-Komponenten (UPrimitiveComponent) speichern alle PSOs, die für das Rendering benötigt werden, unmittelbar nach dem Laden (während PostLoad) vorab. Der Precache sammelt alle Pipeline Zustandsinformation, die zum kompilieren der PSOs benötigt werden, darunter:
Materialien
Scheitelpunktfabriken
Scheitelpunkt Element
Spezifische Vor-Cache-Parameter
Die Unreal Engine verwendet diese Informationen, um über alle möglichen Mesh Durchlauf -Prozessoren zu iterieren, auf denen die Komponente gerendert werden kann. Jeder Mesh-Durchlauf-Prozessor fügt die möglichen PSO-Initialisierer hinzu, die er beim Rendering benötigen könnte. Hintergrundaufgaben prüfen einen gemeinsam genutzten PSO-Cache, um sicherzustellen, dass die benötigten Daten nicht bereits zwischengespeichert werden, und kompilieren diese Anfragen asynchron.
Eine einzelne Komponente könnte viele PSOs benötigen, um in den verschiedenen Durchläufen, etwa Basis, benutzerdefinierte Tiefe, Tiefe, Verzerrung, Schatten, Virtuelle Shadow-Map, Geschwindigkeit und so weiter, korrekt gerendert zu werden. Es ist wichtig, dass all diese PSOs fertig sind, bevor die Komponente bereit ist, um keine grafischen Artefakte zu erzeugen, da sie zum Beispiel in einem Pass gerendert werden könnten, aber nicht in einem anderen.
Wenn die UE einen Primitive Proxy für eine Grundkörper-Komponente erstellt und ihre erforderlichen PSOs noch immer kompilieren, sind mehrere Optionen verfügbar:
Verzögert die Proxy-Erstellung, bis die PSO-Kompilierung abgeschlossen ist (Standard). Damit überspringen wir den Draw, bis das PSO bereit ist.
Ersetzen Sie das Material durch das Standardmaterial der Engine.
Fahren Sie fort und haben einen möglichen Hitch. Der Draw blockiert die PSO-Kompilierung.
Proxy Creation Delay Strategie
Die Konsolenvariable r.PSOPrecache.ProxyCreationDelayStrategy hängt von der Konsolenvariable r.PSOPrecache.ProxyCreationWhenPSOReady ab. Wenn ProxyCreationWhenPSOReady auf 1 (aktiviert) gesetzt ist, führt ProxyCreationDelayStrategy in Abhängigkeit von seinem Wert folgendes Verhalten aus:
| Wert | Verhalten |
|---|---|
0 | Überspringen Sie den Draw, bis das PSO bereit ist. |
1 | Fallback zum Standardmaterial der Engine, bis das PSO bereit ist. |
Ladebildschirm
Wir empfehlen wärmstens, Ihren anfänglichen Ladebildschirm rechtzeitig für PSO Precache-Anfragen einzurichten. .
Wenn Sie den anfänglichen Ladebildschirm für Ihr Spiel einrichten, sollten Sie diesen auf alle aktuell ausstehenden PSO Precache-Anfragen warten lassen. Ansonsten könnte es zu auffälligem visuellen knallig und Laufzeit bei Komponenten kommen, welche die Erstellung von Delay -Proxy nicht unterstützen, etwa bei Landschafts-Terrain, bei denen es eventuell nicht ratsam ist, diese Meshes durch ein Standard-Material zu ersetzen oder sie nicht zu rendern.
FShaderPipelineCache::NumPrecompilesRemaining() ist nützlich, um die Anzahl ausstehender PSO-Precache-Kompilierungen für den gebündelten Cache und das PSO-Precaching zu überprüfen. Sie können Ihre Ladebildschirm Logik modifizieren, um prüfen auf und den Ladebildschirm so lange aufrecht zu erhalten, bis sie auf null fällt. In den meisten Fällen sollte die anfängliche PSO-Kompilierzeit mit einem leeren Treiber-Cache auf mittleren CPUs weniger als eine Minute dauern.
Ressourcen verwalten
PSO Vorcaching beruht auf asynchroner Kompilierung mit Hintergrund-Threads und hat sich auf Arbeitsspeicher und Performance ausgewirkt. Dieser Sektion erläutert die verfügbaren Optionen zur Anpassung und Optimierung der Nutzung dieser Ressourcen an Ihr Projekt.
Speicher
Um Laufzeit Arbeitsspeicher zu sparen, löscht die UE PSOs, die für das Precaching kompiliert wurden, nach der Kompilierung. Das liegt daran, dass eine große Menge an PSOs, die von Ihrer Anwendung vorgespeichert werden, den Speicherbedarf der Anwendung drastisch erhöhen kann, wenn sie nicht bereinigt werden (Hunderte von Megabyte oder sogar Gigabyte).
PSO Vorcaching ist von einem zugrundeliegenden komprimierten Treiber- Cache abhängig. Selbst wenn PSOs nach dem Pre-Caching gelöscht werden, werden sie im Treiber Cache behalten. Wird in der Laufzeit ein PSO benötigt, lädt der Grafiktreiber es aus seinem komprimierten Treiber-Cache. Dies kann jedoch auch ressourcenintensiv sein und die ersten Abrufe aus diesen Caches können einige Millisekunden dauern. Sie können das Löschen der vorgespeicherten PSOs in D3D12 mit D3D12.PSOPrecache.KeepLowLevel deaktivieren.
Das Erstellen von PSOs aus dem Treiber- Cache kann bei bestimmten unabhängigen Hardwareherstellern (IHVs) lange dauern. Für NVIDIA gibt es die Option, einen bestimmten Teil der vorgespeicherten Grafik- und Berechnungs-PSOs im Speicher zu behalten, und zwar mit r.PSOPrecache.KeepInMemoryUntilUsed, wodurch die letzten N vorgespeicherten PSOs im Speicher bleiben und Performance-Einbruch im Treiber Cache vermieden wird. Die Anzahl der im Speicher behaltenen PSOs kann mit r.PSOPrecache.KeepInMemoryGraphicsMaxNum und r.PSOPrecache.KeepInMemoryComputeMaxNum für Berechnung und Grafik separat angepasst werden. Wenn Sie sich für diese Option entscheiden, empfehlen wir, die resultierenden Speicherkosten für Ihre Anwendung mit verschiedenen Einstellungen zu testen, um einen akzeptablen Kompromiss zwischen PSO-Performance und Speicher-Overhead zu ermitteln.
Performance
Standardmäßig verwendet die Unreal Engine einen PSO Thread-Pool, um das PSO asynchron zu kompilieren. Wenn r.pso.PrecompileThreadPoolSize oder r.pso.PrecompileThreadPoolPercentOfHardwareThreads festgelegt ist, wird der Thread-Pool verwendet. Ansonsten greift die PSO-Kompilierung auf reguläre Hintergrundaufgaben zurück, die zusammen mit den restlichen Arbeitslasten der Engine geplant werden.
| Konsolenvariable | Beschreibung | Standardzustand |
|---|---|---|
| Setzt die genaue Anzahl an Threads fest, die im Pool verwendet werden sollen | 0 |
| Setzt die Thread-Pool-Größe auf einen Prozentsatz der verfügbaren Hardware-Threads und erstellt einen Thread-Pool mit dieser Größe. Die Standardgröße ist 75, was 75 % der Hardware-Threads repräsentiert. | 75 |
| Die minimale Anzahl Threads zur Verwendung im PSO Thread-Pool. | 2 |
| Die maximale Anzahl Threads, die im PSO Thread-Pool verwendet werden sollen. Die Voreinstellung ist | INT_Max |
Zusätzliche Hinweise:
Bei einer unbegrenzten Anzahl von Threads im Thread-Pool kann es sein, dass der Arbeitsspeicher beim Kompilieren von PSOs auf Systemen mit vielen Prozessoren, aber nicht viel Speicher, ausgeht. Jeder PSO-Thread kann bis zu 2 GB Speicher kompilieren. Eine Begrenzung dieses Betrags kann für Ihr Projekt sinnvoll sein.
Im Gameplay können 75 Prozent der Hardware-Threads eine Menge sein. Kollisionen mit regulären Vordergrund-Threads können zu kleineren Frame-Drops führen. Das Erhöhen dieses Wertes während des Ladens und das erneute Verringern während des Gameplays kann helfen, aber es kann die PSO-Kompilierung verzögern und die verzögerte Proxy-Erstellung erhöhen — es sollte keine Laufzeit-Hänger verursachen.
Sie können das Argument -clearPSODriverCache verwenden, um das Löschen des Treiber Cache zu erzwingen. Wir empfehlen dies, um das erste Start Ihres Spiels zu testen.
Beim Testen auf PCs mit einer großen Anzahl von Kernen empfehlen wir außerdem, die Kernanzahl auf 8 oder eine andere typische Kernanzahl für einen Verbraucher-PC zu begrenzen. Verwenden Sie das Befehlszeilen-Argument -corelimit=n, wobei n die Anzahl der Kerne ist und -processaffinity=n, was weiterhin sichert, dass Windows das Spiel nur auf n physischen Kernen plant. Auf diese Weise stellen Sie sicher, das Nutzererlebnis genauer zu replizieren.
Verwende den Schalter -clearPSODriverCache konsistent für alle Testdurchläufe, mit denen die Laufleistung Ihres Spiels bewertet wird. Ohne sie werden Hitches möglicherweise vom PSO Cache maskiert, den der Grafiktreiber erstellt hat, und aus vorherigen Durchläufen zurückgelassen hat.
Validierung und Verfolgung
Es gibt verschiedene Optionen, um die Performance des PSO Precaching-System zu validieren und zu tracken.
Sie können die Validierung mit r.PSOPrecache.Validation aktivieren, indem Sie die folgenden Werte verwenden:
| Konsolenvariable | Beschreibung |
|---|---|
0 | Deaktiviert |
1 | Leichte Verfolgung nur mit hohen Zahlen. Dies hat minimale Auswirkungen auf die Performance und kann in ausgelieferten Titeln verwendet werden. |
2 | Detaillierte Verfolgung und Protokollierung von PSO Precache-Fehlern. |
Wenn die PSO Precache-Validierung aktiv ist, können Sie die erfassten Stats mit dem Konsolenbefehl PSOPrecache-Statistik untersuchen.
Die vom PSO Vorcaching-System gesammelten Statistik. Verwende den Konsolenbefehl Wert PSOPrecache, um sie anzuzeigen.
Die Werte sind in 3 Gruppen unterteilt:
| Gruppe | Beschreibung |
|---|---|
Nur-Shader-PSOs | Diese Werte tracken nur die verwendeten RHI Shaders und ignorieren alle anderen Zustandsinformationen in den PSOs. Das ist nützlich, um zu sehen, ob alle Shader vorgespeichert sind, und um herauszufinden, ob etwas in den anderen Rendern Zuständen fehlt oder nicht stimmt. Erfordert |
Minimale PSOs | Enthält die Shaders und alle Rendern Werte sowie Scheitelpunkt-Informationen mit Ausnahme der Renderziel-Informationen. Renderziel-Informationen stehen nur zum Zeit für die Validierung zur Verfügung, aber die minimalen PSO Stats können während der MeshDrawCommand-Erstellung aktualisiert und überprüft werden. Erfordert |
Vollständige PSOs | Der komplette, zur Laufzeit erforderliche PSO-Zustand, der von der Grafik-API verwendet wird. Dies entspricht den Minimal-PSOs, jedoch mit zusätzlichen Renderziel Informationen. |
Für jede Gruppe werden die folgenden Parameter erfasst:
| Parameter | Beschreibung |
|---|---|
Verpasst | Die Anzahl der PSOs, die nicht vorgespeichert wurden, da sie zum Draw- oder Dispatch Zeit benötigt wurden. Mögliche Gründe: falscher Shader, Renderziel Zustand, Scheitelpunktattribute, Renderzielinformationen. |
Nicht verfolgt | Die Anzahl der PSOs, für die Vorcaching nicht aktiviert ist. Mögliche Gründe: Validierung deaktiviert, globales Material, nicht unterstützte Scheitelpunktfabrik, nicht unterstützter Mesh-Durchlaufprozessor-Typ. In Auslieferung Builds, in denen bestimmte Debug Informationen nicht verfügbar sind, werden nicht verfolgte PSOs stattdessen als verpasst angezeigt. |
Treffer | Die Anzahl der bei der Laufzeit verwendeten PSOs, die erfolgreich vorgespeichert wurden. |
Zu spät | Die Anzahl der PSOs, die in der Warteschlange für das Vor-Caching waren, aber nicht rechtzeitig kompiliert wurden, als sie benötigt wurden. |
Benutzt | Die Anzahl der zur Laufzeit verwendeten PSOs (Summe aller oben genannten). |
Im Vor-Cache | Die Anzahl der PSOs, die vorab zwischengespeichert wurden (aber nicht unbedingt verwendet wurden). |
Der Shader Pipeline Cache liefert auch Informationen darüber, wie viele tatsächliche Laufzeit-HItches aufgrund der PSO-Kompilierung selbst erkannt wurden. Eine PSO Kompilierung wird als Hitch markiert, wenn die Kompilierung länger als eine bestimmte Zeitspanne in Millisekunden dauert, bis die Kompilierung des Laufzeit PSO stattfindet. Der Standard-Schwellenwert liegt bei 20 Millisekunden. Sie können dies mit r.PSO.RuntimeCreationHitchThreshold modifizieren, aber Sie sollten ihn so klein wie möglich halten.
Der Standardwert von 20 Millisekunden ist hoch, da die ersten Treffer im Cache Zeit dauern können.
Informationen zum PSO Precaching sammeln
Sie können die Log-Datei, den Visual Studio Debugger und Unreal Insights verwenden, um Weitere Informationen über das PSO Precaching zu erhalten und zu untersuchen, warum bestimmte PSOs immer noch Hitches zur Laufzeit verursachen können. Korrekte PSO-Vorcache-Zustände werden nur im Log und in den Insights angezeigt, wenn die PSO-Validierung aktiviert ist (siehe oben Validation and Tracking).
Wird ein PSO Fehler oder eine zu späte PSO-Aufgabe festgestellt, schreibt die UE folgende Information ins Log:
PSO PRECACHING MISS:
Type: FullPSO
PSOPrecachingState: Missed
Material: M_AdvancedSkyDome
VertexFactoryType: FLocalVertexFactory
MDCStatsCategory: StaticMeshComponent
MeshPassName: SkyPass
Shader Hashes:
VertexShader: EC68796503F829FDEACC56B913C4CA86C6AD3C16
PixelShader: 651BF1ABBAEC0B74C8D2A5E917702A00EF29817B
Insights ist ein nützliches Werkzeug, um PSO Precaching zu debuggen. Das Hinzufügen der Timer PSOPrecache: Missed und PSOPrecache: Too Late zur Reihe der Frame des Spiel ermöglicht es, einen Überblick über alle Probleme zu erhalten, die durch die PSO-Kompilierung über einen bestimmten Zeitraum verursacht wurden. Im folgenden Screenshot gibt es einige 5 bis 10 ms PSO Precaching-Fehler Ruckler, aber auch einen großen Ruckler von 117 ms, der für den Spieler auffällt. Die anderen großen Hitches ergeben sich nicht aus der PSO-Kompilierung.
Klicke, um das Bild zu vergrößern.
Beim Heranzoomen sehen wir, dass es aus dem Transluzenz-Durchlauf kommt (und das Log sollte weitere Informationen dazu enthalten):
Klicke, um das Bild zu vergrößern.
Mehr Informationen dazu finden Sie in „globale PSO -Validierungs-Helferobjekte“. Wenn die Validierung auf vollständige Verfolgung eingestellt ist (r.PSOPrecache.Validation=2), werden die Zahlen nach Mesh-Durchlaufprozessor und Scheitelpunktfabrik-Typ gruppiert. Das kann dabei helfen, die Quelle bestimmter Fehler zu tracken. Das kann auch dabei helfen, eine klarere Vorstellung davon zu erhalten, woher alle vorgespeicherten PSOs kommen, und es kann Ausreißer finden, die nicht so viele Shaders vorspeichern sollten.
Obwohl diese Per-Durchlauf- und Per-Scheitelpunktfabrik-Statistiken nicht direkt offengelegt werden, können Sie sie beim Debugging untersuchen, indem Sie durch die Datenstrukturen navigieren, die sie sammeln. Sie sind in PSOPrecacheValidation.cpp:
FullPSOPrecacheStatsCollectorShadersOnlyPSOPrecacheStatsCollectorMinimalPSOPrecacheStatsCollector
Der folgende Screenshot zeigt ein Beispiel.
Klicke, um das Bild zu vergrößern.
PSO Precaching um Engine-Funktionen erweitern
Diese Sektion enthält Informationen darüber, wie Sie unterstützende Objekte für PSO Precaching erweitern können.
UPrimitiveComponent
UPrimitiveComponent sammelt alle erforderlichen Informationen zur Einrichtung des PSO-Initialisierers. Er benötigt die Material-Instanz, die Scheitelpunktfabrik (möglicherweise mit einem Scheitelpunkt Element) und den Parametersatz, der den finalen Shader oder Rendern Zustand beeinflussen könnte, der im FMeshPassProcessor verwendet wird.
Die Parameter werden in FPSOPrecacheParams gespeichert und die korrekten Standardwerte werden in UPrimitiveComponent::SetupPrecachePSOParams eingerichtet.
Die Basis Funktion für PSO Vorcaching ist:
/** Precache all PSOs which can be used by the primitive component */
ENGINE_API virtual void PrecachePSOs();In den meisten Fällen muss die abgeleitete Komponente diese Funktion nicht implementieren und kann einfach die Precache-Parameter-Funktion überschreiben:
/**
* Collect all the data required for PSO precaching
*/
struct FComponentPSOPrecacheParams
{
EPSOPrecachePriority Priority = EPSOPrecachePriority::Medium;
Ein vollständiges Beispiel finden Sie in UStaticMeshComponent::CollectPSOPrecacheData, und einen einfacheren Anwendungsfall finden Sie in WaterMeshComponent::CollectPSOPrecacheData.
FVertexFactory
Eine neue Scheitelpunktfabrik muss flaggen, dass sie PSO-Vorcaching unterstützt, indem Sie das Flag EVertexFactoryFlags::SupportsPSOPrecaching verwenden, das mit dem Scheitelpunktfabrik-Deklarationsmakro IMPLEMENT_VERTEX_FACTORY_TYPE bereitgestellt werden kann.
Dann muss die Vertex-Factory die folgende Funktion implementieren:
static void GetPSOPrecacheVertexFetchElements(EVertexInputStreamType VertexInputStreamType, FVertexDeclarationElementList& Elements);FVertexFactory::GetPSOPrecacheVertexFetchElements wird während PSO-Vorcaching verwendet, wenn kein explizites Scheitelpunkt-Element-Set angegeben wird.
Das Element mit fixierter Scheitelpunkt ist gültig, wenn das Flag EVertexFactoryFlags::SupportsManualVertexFetch in der Scheitelpunktfabrik gesetzt ist oder wenn ein Element mit fixierter Scheitelpunkt im Shader verwendet wird.
Ist die Scheitelpunkt-Element-Liste von den Scheitelpunkt-Buffer-Daten des Mesh abhängig, dann muss der korrekte Satz in FPSOPrecacheVertexFactoryData bereitgestellt werden. Dies sollte während UPrimitiveComponent::CollectPSOPrecacheData passieren. Siehe UStaticMeshComponent::CollectPSOPrecacheData und FLocalVertexFactory::GetVertexElements für entsprechende Beispiele.
FMeshPassProcessor
Der Mesh-Durchlaufprozessor hat die folgende Funktion zu implementieren, um alle PSOs zu sammeln, die beim Zeichnen eines bestimmten Materials mit den angegebenen FPSOPrecacheParams verwendet werden können:
virtual void CollectPSOInitializers(const FSceneTexturesConfig& SceneTexturesConfig, const FMaterial& Material, const FPSOPrecacheVertexFactoryData& VertexFactoryData, const FPSOPrecacheParams& PreCacheParams, TArray<FPSOPrecacheData>& PSOInitializers) override {}Die Logik ist fast die gleiche wie bei AddMeshBatch (und kann idealerweise teilweise gemeinsam genutzt werden), aber während AddMeshBatch zur MeshDrawCommand-Zeit abgerufen wird, versucht das PSO-Vorcaching-System, die Informationen viel früher zu sammeln (PostLoad der Komponente).
Ein einfaches Beispiel finden Sie unter FDistortionMeshProcessor::CollectPSOInitializers. Ein umfassenderes Beispiel finden Sie unter FBasePassMeshProcessor::CollectPSOInitializers.
IPSOCollector
Nicht alle Material-Shader durchlaufen einen Mesh-Durchlaufprozessor oder haben einen EMeshPass::Type definiert (wie bei dynamischen Geometrie-Updates für Haare, Nanite oder Ray Tracing-Daten). Für diese kann es erforderlich sein, direkt vom Basis Interface abzuleiten.
Der IPSOCollector hat über eine einzige virtuelle Funktion, die implementiert werden muss:
// 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;Der PSO Kollektor muss für die Erstellung außerdem über eine globale FRegisterPSOCollectorCreateFunction registriert werden. Es gibt ein paar einfache Beispiele in der Engine: FTranslucentLightingMaterialPSOCollector, FRayTracingDynamicGeometryPSOCollector,…
GlobalPSOCollector
Wie bereits auf dieser Seite erwähnt, werden einige global Grafik-PSOs bereits beim Start Zeit zwischengespeichert, von denen wir wissen, dass sie Laufzeit -Permutationen kompilieren können. Dafür wird der GlobalPSOCollector verwendet. Es ist eine vereinfachte Version des IPSOCollectors. Ein globales FRegisterGlobalPSOCollectorFunction -Objekt muss deklariert werden, welches die globale PSO-Kollektor-Funktion bereitstellt:
typedef void (*GlobalPSOCollectorFunction)(const FSceneTexturesConfig& SceneTexturesConfig, int32 GlobalPSOCollectorIndex, TArray<FPSOPrecacheData>& PSOInitializers);Siehe DeferredLightGlobalPSOCollector oder RegisterVolutricFogGlobalPSOCollector für einige Anwendungsbeispiele.
Debuggen eines PSO-Precache-Fehlers
Um zu debuggen, woher der oben erwähnte PSO Precache-Fehler kommt, müssen Sie manuelles Debugging in Visual Studio verwenden.
Das Debugging von Fehlern im minimalen PSO Zustand ist unkompliziert, da diese während der Erstellung von MeshDrawCommand ausgelöst werden können und nicht zur Zeichnungszeit. Die finalen Renderziel-Informationen, die zur Berechnung des vollständigen PSO benötigt werden, sind nur während des Zeichnens verfügbar, was Debug Arbeiten erschwert.
Die Funktion LogPSOMissInfo ist ein guter Platz, um den Debugger zu brechen, wenn zur Laufzeit ein Fehler auftritt. Der Aufrufstapel und das Überwachungsfenster können weitere Informationen über die verwendeten Materialien, den Render-Durchlauf, die Scheitelpunktfabrik und den FPrimitiveSceneProxy liefern. Sie können zudem Informationen über das UPrimitiveComponent holen, das im ComponentForDebuggingOnly-Mitglied gespeichert ist. Die meisten dieser Daten werden auch in der Log-Datei abgelegt, wenn sie einen Fehler findet (gesammelt in der Funktion).
Zum Zeit der Ausführung von LogPSOMissInfo hat das PSO Precaching für diese Komponente jedoch in der Regel bereits stattgefunden. Wenn Sie herausfinden möchten, warum beim Precaching für die PSOs dieser Komponente ein falscher Shader oder Rendern Zustand verwendet wurde, müssen Sie beim PSO Precaching für diese Komponente und/oder dieses Material für den jeweiligen Durchlauf einen Breakpoint hinzufügen.
r.PSOPrecache.BreakOnMaterialName ist nützlich, um während des PSO Vorcachings zu brechen, wenn ein Material mit einem bestimmten Name gefunden wird – das kann hilfreich sein, um herauszufinden, warum sich ein bestimmter Rendern Zustand im Vergleich zum Laufzeit Zustand unterscheidet. r.PSOPrecache.BreakOnPassName und r.PSOPrecache.BreakOnShaderHash können ebenfalls verwendet werden, um problematische PSO einzuschränken. Diese Informationen finden Sie wie oben erwähnt im Log.
r.PSOPrecache.UseBackgroundThreadForCollection ist nützlich, um die Hintergrund-Thread-Aufgaben für die PSO-Initialisierer-Sammlung zu deaktivieren, um das Nachverfolgen von Komponenteninformationen oder anderem Zustand beim Debuggen eines PSO-Vorab-Caching-Fehlers zu erleichtern.
Möglicherweise müssen Sie auch die Werte von FPSOPrecacheParams prüfen, da diese auch den Shader und Renderzustand, der im PSO verwendet wird, beeinflussen können.