Freigeben über


Übersicht über Deskriptoren

Deskriptoren werden durch API-Aufrufe erstellt und Ressourcen identifiziert.

Deskriptordaten

Ein Deskriptor ist ein relativ kleiner Datenblock, der ein Objekt für die GPU vollständig beschreibt, in einem GPU-spezifischen undurchsichtigen Format. Es gibt verschiedene Arten von Deskriptoren: Renderzielansichten (RTVs), Tiefenschablonenansichten (DSVs), Shaderressourcenansichten (SRVs), ungeordnete Zugriffsansichten (UAVs), Konstantenpufferansichten (CBVs) und Sampler.

Deskriptoren variieren je nach GPU-Hardware in Größe. Sie können die Größe eines SRV, UAV oder CBV abfragen, indem Sie ID3D12Device::GetDescriptorHandleIncrementSize aufrufen. Beschreibungen werden in dieser Dokumentation als unteilbare Einheiten gezeigt. Hier ist ein Beispiel.

srv, cbv, uav, and sampler

Deskriptoren werden durch API-Aufrufe erstellt und enthalten Informationen wie die Ressource und Mip-Zuordnungen, die der Deskriptor enthalten soll.

Der Treiber verfolgt oder speichert keine Verweise auf Deskriptoren. Es obliegt der Anwendung, sicherzustellen, dass der richtige Deskriptortyp verwendet wird und die Informationen aktuell sind. Hierfür gibt es eine kleine Ausnahme. Der Treiber überprüft Renderzielbindungen, um sicherzustellen, dass Swapchains ordnungsgemäß funktionieren.

Objektdeskriptoren müssen nicht freigeschaltet oder freigegeben werden. Treiber fügen keine Zuordnungen zur Erstellung eines Deskriptors an. Ein Deskriptor kann jedoch Verweise auf andere Zuweisungen kodieren, für die die Anwendung die Lebensdauer besitzt. Beispielsweise muss ein Deskriptor für einen SRV die virtuelle Adresse der D3D-Ressource (z. B. eine Textur) enthalten, auf die der SRV verweist. Es liegt in der Verantwortung der Anwendung, sicherzustellen, dass sie keinen SRV-Deskriptor verwendet, wenn die zugrunde liegende D3D-Ressource, von der sie abhängt, zerstört wurde oder geändert wird (z. B. als nichtident deklariert).

Die Hauptverwendung von Deskriptoren besteht darin, sie in Deskriptor-Heaps zu platzieren, die als Sicherungsspeicher für Deskriptoren dienen.

Deskriptor-Handles

Ein Deskriptor-Handle ist die eindeutige Adresse des Deskriptors. Es ähnelt einem Zeiger, ist aber nicht transparent, da die Implementierung hardwarespezifisch ist. Das Handle ist für Deskriptor-Heaps eindeutig, sodass beispielsweise ein Array von Handles auf Deskriptoren in mehreren Heaps verweisen kann.

CPU-Handles sind für den sofortigen Gebrauch bestimmt, z. B. beim Kopieren, bei dem sowohl die Quelle als auch das Ziel identifiziert werden müssen. Unmittelbar nach der Verwendung (z. B. ein Aufruf von ID3D12GraphicsCommandList::OMSetRenderTargets), können sie wiederverwendet werden, oder der zugrunde liegende Heap kann verworfen werden.

GPU-Handles sind nicht für die unmittelbare Verwendung bestimmt - sie identifizieren Orte aus einer Befehlsliste, die zur GPU-Ausführungszeit verwendet werden. Sie müssen beibehalten werden, bis alle Befehlslisten, auf die sie verweisen, vollständig ausgeführt wurden.

Um ein Deskriptor-Handle für den Anfang eines Heaps zu erstellen, rufen Sie nach der Erstellung des Deskriptor-Heaps selbst eine der folgenden Methoden auf:

Diese Methoden geben die folgenden Strukturen zurück:

Da die Größe der Deskriptoren je nach Hardware variiert, wird die Schrittweite zwischen den einzelnen Deskriptoren in einem Heap wie folgt ermittelt:

Es ist sicher, eine Startposition mit einer Anzahl von Inkrementen zu versetzen, Handles zu kopieren und Handles an API-Aufrufe zu übergeben. Es ist nicht sicher, ein Handle so zu derefenzieren, als wäre es ein gültiger CPU-Zeiger, und auch nicht, die Bits innerhalb eines Handles zu analysieren.

Es wurden einige Hilfsstrukturen mit Initialisierungselementen hinzugefügt, um die Verwaltung von Handles ein wenig zu vereinfachen.

Nulldeskriptoren

Bei der Erstellung von Deskriptoren über API-Aufrufe übergeben Anwendungen NULL für den Ressourcenzeiger in der Deskriptor-Definition, um den Effekt zu erzielen, dass beim Zugriff durch einen Shader nichts gebunden ist.

Der Rest des Deskriptors muss so weit wie möglich aufgefüllt werden. Bei Shaderressourcenansichten (SRVs) kann der Deskriptor beispielsweise verwendet werden, um den Typ der Ansicht zu unterscheiden (Texture1D, Texture2D usw.). Numerische Parameter im Ansichtsdeskriptor, z. B. die Anzahl der Mipmaps, müssen alle auf Werte festgelegt werden, die für eine Ressource gültig sind.

In vielen Fällen gibt es ein definiertes Verhalten für den Zugriff auf eine ungebundene Ressource, z. B. SRVs, die Standardwerte zurückgeben. Diese werden beim Zugriff auf einen NULL-Deskriptor berücksichtigt, solange der Shaderzugriffstyp mit dem Deskriptortyp kompatibel ist. Wenn ein Shader beispielsweise eine Texture2D SRV erwartet und auf eine NULL-SRV zugreift, die als Texture1D definiert ist, ist das Verhalten nicht definiert und kann dazu führen, dass das Gerät zurückgesetzt wird.

Um einen Nulldeskriptor zu erstellen, übergeben Sie null für den pResource-Parameter beim Erstellen der Ansicht mit Methoden wie CreateShaderResourceView. Legen Sie für den Anzeigebeschreibungsparameter pDesc eine Konfiguration fest, die funktionieren würde, wenn die Ressource nicht null war (andernfalls kann ein Absturz auf einer Hardware auftreten).

Stammdeskriptoren sollten jedoch nicht auf null festgelegt werden.

Auf der Hardwareebene1 (siehe Hardwareebenen) müssen alle deskriptorgebundenen Deskriptoren (über Deskriptortabellen), auch wenn nicht auf die Hardware zugegriffen wird, entweder als echte Deskriptoren oder Null-Deskriptoren initialisiert werden, andernfalls ist das Verhalten nicht definiert.

Auf der Hardwareebene2 gilt dies für gebundene CBV- und UAV-Deskriptoren, aber nicht für SRV-Deskriptoren.

Auf Hardwareebene3 gibt es keine Einschränkung, vorausgesetzt, es wird nie auf nicht initialisierte Deskriptoren zugegriffen.

Standarddeskriptoren

Um einen Standarddeskriptor für eine bestimmte Ansicht zu erstellen, übergeben Sie einen gültigen pResource-Parameter an die Create-Ansichtsmethode (z. B. CreateShaderResourceView), übergeben aber NULL für den pDesc-Parameter. Wenn die Ressource beispielsweise 14 Mips enthält, würde die Ansicht 14 Mips enthalten. Der Standardfall behandelt die offensichtlichste Zuordnung einer Ressource zu einer Ansicht. Dies erfordert, dass die Ressource einem vollqualifizierten Formatnamen zugeordnet ist (z. B. DXGI_FORMAT_R8G8B8A8_UNORM_SRGB anstelle von DXGI_FORMAT_R8G8B8A8_TYPELESS).

Standarddeskriptoren können nicht mit einer Raytracing-Beschleunigungsstrukturansicht verwendet werden, da der angegebene pResource-Parameter NULL sein muss und die Position über eine D3D12_RAYTRACING_ACCELERATION_STRUCTURE_SRV übergeben werden muss.

Deskriptoren