7 Punkte von GN⁺ 2025-12-17 | Noch keine Kommentare. | Auf WhatsApp teilen
  • In den vergangenen zehn Jahren haben Low-Level-Graphics-APIs wie DirectX 12, Vulkan, Metal die GPU-Leistung gesteigert, aber auch die Komplexität und die Wartungskosten stark erhöht
  • Moderne GPUs unterstützen vollständige Cache-Hierarchien, 64-Bit-Zeiger und bindless Ressourcen, wodurch bisher komplexe Zustandsobjekte und Bindungsmodelle überflüssig werden
  • Das vorgeschlagene Design vereinfacht die Rendering-Pipeline drastisch durch speicherbasierten Zugriff über C/C++-Zeiger und einen einzelnen 64-Bit-Root-Pointer
  • Es entfernt PSO-Explosion, Resource Barriers und komplexe Binding-APIs und schlägt eine Struktur vor, die GPU-Speicher und Shader-Sprache direkt verbindet
  • Dieser Ansatz ist eine für moderne GPU-Architekturen optimierte Next-Generation-API und zeigt die Richtung, die DirectX 13 oder Vulkan 2.0 einschlagen sollten

Der Wandel von Low-Level-Graphics-APIs

  • 2013 wurden die AMD-GCN-Architektur der Xbox One und PS4 zum Standard in der AAA-Spieleentwicklung, woraufhin Low-Level-APIs wie Mantle, DirectX 12, Vulkan und Metal erschienen
    • Das heißt: Sie wurden auf Basis der GPU-Architekturen um das Jahr 2013 herum entworfen
  • Das bisherige DirectX 11/OpenGL stieß wegen Single-Thread-Rendering und hohem Treiber-Overhead an seine Grenzen
  • Diese APIs reduzierten mit vorab kompilierten Pipeline State Objects (PSO) die Kosten von Draw Calls, erhöhten aber die Komplexität, weil sie nicht gut zur Struktur von Engines passten
  • In der Folge entstand innerhalb der Engine eine weitere „Low-Level-Treiber-Schicht“, wodurch sich die Rolle von Graphics-Programmierern weiter ausdifferenzierte

Historischer Hintergrund: Warum wurde alles so kompliziert?

  • Frühe GPUs basierten auf getrennten Speichern und fest verdrahteten Pipeline-Strukturen
  • OpenGL und DirectX setzten auf zustands- und objektbasierte Designs, um die Vielfalt der Hardware zu abstrahieren
  • Selbst bis DirectX 11 wurden Texturen und Buffer über opake Deskriptoren verwaltet
  • Dieses Design wurde danach auch in spätere APIs gewissermaßen aus Trägheit übernommen

Die Diskrepanz zwischen modernen GPUs und APIs

  • Aktuelle GPUs unterstützen konsistente Cache-Hierarchien, PCIe ReBAR, 64-Bit-Zeiger und bindless Textures
  • Damit wird eine Struktur möglich, bei der die CPU direkt in den GPU-Speicher schreibt und die GPU sofort daraus lesen kann
  • In einer solchen Umgebung sind Konstrukte wie PSOs, Descriptor Sets und Binding Tables nicht mehr nötig
  • Durch das explodierende Wachstum von PSO-Caches werden Hunderte GB Cache benötigt, was Ladeverzögerungen und Stottern verursacht
  • Eine neue API könnte diese veralteten Strukturen entfernen und zu einem einfachen zeigerbasierten Zugriff wechseln

Vereinfachung des GPU-Speichermanagements

  • In bisherigem Vulkan/DirectX 12 ist nach der Erzeugung einer Ressource noch eine Abfrage der Heap-Kompatibilität nötig, was ineffizient ist
  • Der vorgeschlagene Ansatz weist GPU-Speicher direkt über eine einfache API im Stil von gpuMalloc/gpuFree zu
    • Die CPU kann den GPU-Speicher direkt mappen und initialisieren
    • Große Datenmengen lassen sich per Kopierkommando übertragen, um DCC-Komprimierung und Swizzle-Verarbeitung auszuführen
  • CPU-Mapping-Adresse und GPU-Adresse werden getrennt behandelt und über gpuHostToDevicePointer umgewandelt

Modernisierung von Daten und Shader-Sprache

  • Verwendet wird eine C/C++-zeigerbasierte Shader-Sprache wie bei CUDA, Metal und OpenCL
  • Über Wide Loads auf Strukturebene (128 Bit oder mehr) ist effizienter Speicherzugriff möglich
  • ByteAddressBuffer oder Texel Buffer von DirectX sind nicht länger optimal
  • GLSL/HLSL unterstützen keine Zeiger, wodurch ein Ökosystem wiederverwendbarer Shader-Bibliotheken fehlt, während sich CUDA mit reichhaltigen Bibliotheken weiterentwickelt hat

Root-Argumente und Datenstrukturen

  • Ein GPU-Kernel erhält einen einzelnen 64-Bit-Zeiger als Eingabe und castet ihn auf eine Struktur
  • CPU und GPU teilen sich denselben C/C++-Header, um Konsistenz der Datenstrukturen sicherzustellen
  • Über die Schlüsselwörter const/restrict werden Compiler-Optimierungen gefördert und die unnötige Trennung zwischen UBO und SSBO entfällt
  • Dabei werden Preloading in Scalar Registers und Dynamic Uniform Optimization moderner GPUs genutzt

Vereinfachung des Texture-Bindings

  • Alle Texturen werden als Array aus 256-Bit-Deskriptoren (Heap) verwaltet, das von CPU und GPU direkt beschrieben werden kann
  • 32-Bit-indexierter Zugriff unterstützt nicht-uniformes (non-uniform) Texture-Sampling
  • Das ist einfacher als der Descriptor Heap in DirectX 12 SM 6.6 und ähnlich zu Vulkan VK_EXT_descriptor_buffer
  • Texture-Objekterstellung, Upload und Sampling werden vollständig auf Basis von GPU-Speicherzeigern vereinheitlicht

Shader-Pipeline und Konstanten

  • Die Pipeline-Erzeugung besteht schlicht darin, Shader-IR zu laden und dann gpuCreatePipeline aufzurufen
  • Root Signatures, Descriptor Sets und Binding-Definitionen sind nicht erforderlich
  • Statische Konstanten (strukturbasiert) ersetzen Shader-Spezialisierungskonstanten und mildern das Problem der explodierenden PSO-Kombinationen
  • Konstantenstrukturen können GPU-Zeiger enthalten, sodass Laufzeitadressen direkt hartkodiert werden können

Vereinfachung von Barriers und Synchronisation

  • Die ressourcenspezifischen Barrier-Listen heutiger APIs passen nicht zu modernen GPU-Strukturen
  • Das vorgeschlagene Modell verwendet nur Bitfield-Flags auf Queue-/Stage-Ebene
  • Mit gpuBarrier(before, after, hazard) wird das Modell vereinfacht; ein Resource Tracking ist nicht nötig
  • Über gpuSignalAfter / gpuWaitBefore lässt sich eine GPU→GPU-Synchronisation ähnlich einem Timeline Semaphore umsetzen

Command Buffer und Rendering

  • Es werden nur einmalige (transiente) Command Buffer verwendet; das komplexe Wiederverwendungsmodell von Vulkan entfällt
  • Mit gpuBeginRenderPass / gpuEndRenderPass werden Render Targets gesetzt und Clears durchgeführt
  • Es gibt keine automatischen Barriers zwischen Render Passes, wodurch paralleles Rendering und Optimierungen wie ein Depth Pre-Pass möglich werden

Vereinfachung der Raster-Pipeline

  • Vertex/Pixel Shader greifen zeigerbasiert auf Daten zu, wodurch Binding-APIs entfallen
  • GpuDepthStencilState und GpuBlendState werden vom PSO getrennt, um die Zahl der Kombinationen zu verringern
  • Mobile GPUs unterstützen programmierbares Blending über Framebuffer-Fetch-Intrinsics
  • Das PSO enthält nur noch minimale Zustände wie Topologie, Format oder Sample-Anzahl

Indirect Draws und GPU-Driven Rendering

  • Alle Argumente (data, arguments) werden als GPU-Pointer übergeben
  • gpuDrawIndexedInstancedIndirectMulti unterstützt Multi-Draws
  • Die GPU kann Root-Daten und Draw-Argumente direkt selbst erzeugen und so vollständiges GPU-driven Rendering umsetzen

Tooling und Kompatibilität

  • Eine zeigerbasierte Struktur lässt sich wie in CUDA-/Metal-Debuggern über Symbolinformationen nachverfolgen
  • Durch virtuellen Speicher gibt es kein Sicherheitsproblem; bei fehlerhaften Zugriffen tritt ein Page Fault auf
  • Wie bei MoltenVK oder Proton können bestehende DirectX-, Vulkan- oder Metal-APIs über eine Übersetzungsschicht kompatibel gemacht werden

Mindestanforderungen und Fazit

  • Nvidia Turing (2018), AMD RDNA1 (2019), Intel Xe1 (2022) und Apple M1 (2020) unterstützen alle die vorgeschlagenen Funktionen
  • Heutige GPUs haben sich bereits zu einer Architektur mit bindless Ressourcen, 64-Bit-Zeigern und konsistentem Cache entwickelt
  • Nur die APIs hängen noch an Abstraktionen aus der Vergangenheit fest
  • Eine neue API wäre einfacher als DirectX 11, schneller als Vulkan und flexibler als Metal
  • Vulkan 2.0 / DirectX 13 der nächsten Generation sollten zu einem solchen vollständig bindless Design wechseln und das Ökosystem statt mit HLSL/GLSL mit einer C/C++-zeigerbasierten Shader-Sprache erweitern

Noch keine Kommentare.

Noch keine Kommentare.