Initialisieren von Direct3D und mehrere Grafikkarten in einem PC

Messezeit ist fürs erste rum, die meisten der Prüfungen sind geschrieben. Jetzt wird es Zeit, hier wieder einige Themen zu diskutieren. Neulich stand ich wieder vor der Frage, wie man bei einer „frischen“ 3D-Engine Direct3D initialisiert bzw. ganz allgemein die Device-Instanzen verwaltet. Mittlerweile ist die API zwar einfacher, das Thema meiner Meinung nach aber komplexer geworden. Hat man ein Windows.Forms Control als Render-Ziel, so hat man i. d. R. keine großen Probleme. Steckt man aber etwa in einem Szenario, in welchen man 3D-Grafik eines Direct3D 11 Renderers in WPF einbinden möchte, so muss man schon Ressourcen von Direct3D 9 und Direct3D 11 verwenden, da WPF selbst nur Ressourcen von Direct3D 9 einbinden kann. Will man jetzt noch per Direct2D direkt auf Texturen zeichnen, so sind – aber auch nur auf der Windows 7 Plattform – zusätzlich Ressourcen von Direct3D 10 notwendig.

Genauer

Das beschriebene Problem ist zugegebenermaßen schon etwas speziell, schließlich hat man nicht oft überhaupt den Bedarf, das alles mit den modernsten Schnittstellen zu können, und es dann auch noch in WPF einzubinden. Genau dieses Szenario finde ich aber besonders interessant, da es erlaubt, zum einen nachfolgende Vorteile von WPF zu verwenden.

  • Zeichnen von Gui-Elementen direkt über die 3D-Grafik
  • Verwenden der 3D-Grafik als beliebigen Brush für andere Gui-Elemente

Oder kurz: Mehr Interaktionsmöglichkeiten zwischen 3D-Szene und Gui. Zum Anderen verstecken sich mittlerweile richtig gute Funktionen in den anderen DirectX APIs, so erlaubt zum Beispiel Direct2D nicht nur das extrem schnelle Zeichnen von 2D-Grafiken, sondern kann diese auch direkt in von 3D-Objekten verwendeten Texturen zeichnen. Nur leider mit der Bedingungen, dass die DirectX Schnittstellen richtig initialisiert wurden und damit korrekt zusammenarbeiten.

Das ist eindeutig ein Thema, bei dem man sich einfach einmal durcharbeiten muss. Ein Problem, auf das ich dabei gestoßen bin, ist die Tatsache, dass sich hier Windows 8 an manchen Stellen anders verhält als Windows 7. So hat es zum Beispiel in Windows 8 problemlos geklappt, per Direct2D in eine Textur zu zeichnen, welche mit Direct3D 11 angelegt wurde. Unter Windows 7 klappt das nur mit Texturen aus der Direct3D 10 Schnittstellen. Zunächst verwirrend.

Was mir aber gefällt an dem Thema ist dennoch die Tatsache, dass die verschiedenen Schnittstellen sauber voneinander getrennt sind und dennoch die meisten Wege und Abhängigkeiten durch Microsoft sauber dokumentiert wurden. Ich bin auch überrascht, dass ich bisher nur geringe Unterschiede im Verhalten zwischen Windows 7 und Windows 8 beobachten konnte, nicht aber bei unterschiedlicher Hardware (NVidia und ATI). Mir kommt es so vor, als wenn man einmal einen Weg für beide Betriebssysteme gefunden hat, dass der dann so gut wie überall funktioniert.

Mehrere Grafikkarten in einem PC

Meine persönliche nächste Herausforderung bei dem Thema wird sein, auch mehrere Grafikkarten parallel anzusteuern. Mehrere Grafikkarten in dem Sinn, dass sie nicht in einem SLI- bzw. CrossFire-Verbund stecken, sondern wirklich unabhängig voneinander arbeiten können. Sinn macht das bei einem Szenario, bei dem man nicht nur einen oder zwei Monitore zu bedienen hat, sondern 3, 4 oder sogar noch mehr. Das Treibermodell von Windows unterstützt dieses Vorgehen prinzipiell durchgängig, nach ersten Tests sind sogar Grafikkarten verschiedener Hersteller in einem PC kein Problem.

Der Vorteil liegt daran, dass man damit wirklich parallel Rendern kann. Multithreading im Sinne von Direct3D 11 bedeutet nämlich i. d. R. nur, dass die sog. CommandLists parallel aufgebaut werden, die Grafikkarte diese aber nach wie vor sequenziell und ohne Multithreading abarbeitet. Verwendet man verschiedene Grafikkarten, kann man die angebundenen Monitore wirklich parallel mit Bildern versorgen, da es auch tatsächlich mehrere Grafikprozessoren gibt, welche unabhängig voneinander arbeiten und jeweils Bilder für die nur an sie angebundenen Monitore berechnen.

Das Initialisieren der verschiedenen Device-Objekte macht dabei scheinbar auch keine Probleme, die Schwierigkeiten kommen erst danach.

  • Verwaltung evtl. verschiedener Feature-Sets
  • Behandlung evtl. verschiedener Leistungsklassen
  • Verwaltung verschiedener Ressourcen
    => 3D-Ressourcen müssen für jede Hardware separat erstellt werden
  • Mehrere Render-Threads, welche parallel die 3D-Szene zeichnen

Das sind nur einige, welche mir spontan eingefallen sind. Sicherlich wird noch die Eine oder Andere Schwierigkeit auftauchen.

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.