Share via


Arbeitsspeicheraliasing und Datenvererbung

Platzierte und reservierte Ressourcen können physischen Arbeitsspeicher innerhalb eines Heaps aliasen. Platzierte Ressourcen ermöglichen mehr Datenvererbungsszenarien als reservierte Ressourcen, wenn für den Heap das freigegebene Flag festgelegt ist oder wenn die aliasierten Ressourcen über vollständig definierte Speicherlayouts verfügen.

Aliase

Zwischen der Verwendung von zwei Ressourcen, die denselben physischen Arbeitsspeicher nutzen, muss eine Aliasingbarriere ausgestellt werden, auch wenn die Datenvererbung nicht gewünscht ist. Einfache Nutzungsmodelle müssen zumindest die Zielressource bezeichnen, die an einem solchen Vorgang beteiligt ist. Weitere Informationen und erweiterte Nutzungsmodelle finden Sie unter CreatePlacedResource .

Nachdem auf eine Ressource zugegriffen wurde, werden alle Ressourcen, die physischen Arbeitsspeicher mit dieser Ressource gemeinsam nutzen, ungültig, es sei denn, die Datenvererbung darf erfolgen. Lesevorgänge ungültiger Ressourcen führen zu nicht definierten Ressourceninhalten. Schreibvorgänge in ungültige Ressourcen führen auch zu nicht definierten Ressourceninhalten, es sei denn, es treten zwei Bedingungen auf:

  • Die Ressource verfügt weder über das D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET noch über D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL.
  • Der Schreibvorgang ist ein Kopier- oder Clear-Vorgang für eine gesamte Unterquelle oder Kachel. Kachelinitialisierung ist nur für Ressourcen mit 64KB_TILE_UNDEFINED_SWIZZLE und 64KB_TILE_STANDARD_SWIZZLE verfügbar.

Überlappende Ungültigkeiten werden auf kleinere Granularitäten festgelegt, wenn Layouts Informationen zum Speicherort am Speicherort der Texel-Daten bereitstellen und sich Ressourcen in bestimmten Übergangsbarrierezuständen befinden. Ungültige Können jedoch nicht kleiner als die Granularitäten der Ressourcenausrichtung sein.

Eine Pufferausrichtungsgranularität beträgt 64 KB, und eine größere Ausrichtungsgranularität hat Vorrang. Dies ist wichtig, wenn 4 KB-Texturen berücksichtigt werden, da sich mehrere 4 KB-Texturen in einer 64 KB-Region befinden können, ohne sich gegenseitig zu überlappen. Ein Pufferalias mit derselben 64 KB-Region kann jedoch nicht in Verbindung mit diesen 4 KB-Texturen verwendet werden. Die Anwendung kann den Zugriff auf den Puffer nicht zuverlässig daran hindern, die 4 KB-Texturen zu überschneiden, da GPUs 4 KB-Texturdaten innerhalb der 64 KB-Region in einem undefinierten Muster verwischen dürfen.

64KB_TILE_UNDEFINED_SWIZZLE, 64KB_TILE_STANDARD_SWIZZLE und ROW_MAJOR Texturlayouts informieren die Anwendung darüber, welche überlappenden Ausrichtungsgranularitäten ungültig geworden sind. Beispiel: Eine Anwendung kann ein 2D-Renderzieltexturarray mit 2 Array-Slices, einer einzelnen MIP-Ebene und dem 64KB_TILE_UNDEFINED_SWIZZLE Layout erstellen. Angenommen, die Anwendung versteht, dass jeder Array-Slice 100 Kacheln mit 64 KB belegt. Die Anwendung kann auf array slice 0 verzichten und diesen Speicher entweder für einen Puffer von ca. 6 MB, eine Textur von ca. 6 MB mit nicht definiertem Layout usw. wiederverwenden. Gehen Sie weiter davon aus, dass die Anwendung die erste Kachel des Arrays slice 1 nicht mehr benötigt. Dann könnte die Anwendung dort auch einen 64 KB-Puffer finden, bis das Rendern erneut die erste Kachel des Array-Slices 1 erfordert. Die Anwendung müsste eine vollständige Kachel löschen oder kopieren, um die erste Kachel mit dem Texturarray erneut zu verwenden.

Aber auch Texturen mit definierten Layouts haben immer noch Problematische Fälle. Texturressourcengrößen können sich erheblich von dem unterscheiden, was die Anwendung selbst berechnen kann, da einige Adapterarchitekturen zusätzlichen Arbeitsspeicher für Texturen zuweisen, um die effektive Bandbreite während gängiger Renderingszenarien zu reduzieren. Alle Ungültigmachungen in diesem zusätzlichen Speicherbereich führen dazu, dass die gesamte Ressource ungültig wird. Weitere Informationen finden Sie unter GetResourceAllocationInfo .

Datenvererbung

Platzierte Ressourcen ermöglichen die meiste Datenvererbung für Texturen, auch bei nicht definierten Speicherlayouts. Anwendungen können die Funktionen für die Datenvererbung nachahmen, die freigegebene Commitressourcen ermöglichen, indem sie zwei Texturen mit identischen Ressourceneigenschaften am gleichen Offset in einem freigegebenen Heap suchen. Die gesamte Ressourcenbeschreibung muss identisch sein, einschließlich des optimierten werts und des Typs der Ressourcenerstellungsmethode (platziert oder reserviert). Beide Ressourcen hatten jedoch möglicherweise unterschiedliche anfängliche Übergangsbarrierezustände.

Reservierte Ressourcen ermöglichen die Datenvererbung pro Kachel; Für Zustände von Ressourcenübergangsbarrieren gibt es jedoch häufig Einschränkungen.

Zum Erben von Daten müssen sich beide Ressourcen in einem kompatiblen Zustand der Ressourcenübergangsbarriere befinden:

  • Bei Puffern, gleichzeitigen Zugriffstexturen und adapterübergreifenden Texturen ist der Ressourcenübergangszustand nicht wichtig, und alle Zustände sind "kompatibel".
  • Für reservierte Texturen ohne die vorherigen Eigenschaften oder andere Datenvererbung pro Kachel über 64KB_TILE_UNDEFINED_SWIZZLE oder 64KB_TILE_STANDARD_SWIZZLE muss sich der Zustand der Ressourcenübergangsbarriere einschließlich der Kachel im allgemeinen Zustand befinden.
  • Für alle anderen Texturen, bei denen die Ressourcenbeschreibungen genau übereinstimmen, muss der Zustand der Ressourcenübergangsbarriere für jedes entsprechende Paar von Unterressourcen:
    • Seien Sie im gemeinsamen Zustand.
    • Seien Sie gleich, wenn der Zustand das gleiche GPU-Schreibflag enthält.

Wenn die GPU Standard-Swizzle unterstützt, können Puffer und Standard-Swizzle-Texturen in denselben Arbeitsspeicher aliast werden und Daten zwischen ihnen erben. Die Anwendung kann texels aus der Pufferdarstellung bearbeiten, da das Standard-Swizzle-Muster beschreibt, wie Texels im Arbeitsspeicher angeordnet sind. Das CPU-sichtbare Swizzle-Muster entspricht dem gpu-sichtbaren Swizzle-Muster, das in Puffern zu sehen ist.

Unterzuweisung innerhalb von Heaps